"""
https://github.com/MayankNCodes
"""
from typing import List, Tuple


def GradePoint(subject) -> int:
    """
    This function calculates the grade point on the marks obtained in a subject.
    
    Parameters:
    subject (int): The marks obtained in a subject.
    
    Returns:
    int: The calculated grade.
    """
    if subject <= 100 and subject >= 90:
        return 10
    elif subject <= 89 and subject >= 75:
        return 9
    elif subject <= 74 and subject >= 65:
        return 8
    elif subject <= 64 and subject >= 55:
        return 7
    elif subject <= 54 and subject >= 50:
        return 6
    elif subject <= 49 and subject >= 45:
        return 5
    elif subject <= 44 and subject >= 40:
        return 4
    else:
        return 0
def Grade(subject) -> str:
    """
    This function calculates the grade on the basis ofmarks obtained in a subject.
    
    Parameters:
    subject (int): The marks obtained in a subject.
    
    Returns:
    str: The calculated grade.
    """
    if subject <= 100 and subject >= 90:
        return "O"
    elif subject <= 89 and subject >= 75:
        return "A+"
    elif subject <= 74 and subject >= 65:
        return "A"
    elif subject <= 64 and subject >= 55:
        return "B+"
    elif subject <= 54 and subject >= 50:
        return "B"
    elif subject <= 49 and subject >= 45:
        return "C"
    elif subject <= 44 and subject >= 40:
        return "P"
    else:
        return "F"

def SGPAFromGradePoint(subjects: List[Tuple[int, int]], roundPrecision: int = 2) -> float:
    """
    This function calculates the Semester Grade Point Average (SGPA) of a student/individual studying in IPU.
    
    Parameters:
    subjects (List[Tuple[int, int]]): A list of tuples where each tuple contains the credits and grade point of a subject.
    roundPrecision (int, optional): The number of decimal places to round the SGPA to. Default is 2.
    
    Returns:
    float: The calculated SGPA.
    
    Raises:
    ValueError: If the total credits are zero.
    """
    total_credits: int = 0
    weighted_sum: int = 0

    for credits, grade_point in subjects:
        total_credits += credits
        weighted_sum += credits * grade_point

    if total_credits == 0:
        raise ValueError("Total credits cannot be zero")

    sgpa: float = weighted_sum / total_credits
    return round(sgpa, roundPrecision) #default is 2

def SGPAFromMarks(subjects: List[Tuple[int, int]], roundPrecision: int = 2) -> float:
    """
    This function calculates the Semester Grade Point Average (SGPA) of a student/individual studying in IPU.
    
    Parameters:
    subjects (List[Tuple[int, int]]): A list of tuples where each tuple contains the credits and marks obtained in a subject.
    roundPrecision (int, optional): The number of decimal places to round the SGPA to. Default is 2.
    
    Returns:
    float: The calculated SGPA.
    
    Raises:
    ValueError: If the total credits are zero.
    """
    total_credits: int = 0
    weighted_sum: float = 0

    

    for credits, grade_point in subjects:
        total_credits += credits
        weighted_sum += credits * GradePoint(grade_point)

    if total_credits == 0:
        raise ValueError("Total credits cannot be zero")

    sgpa: float = weighted_sum / total_credits
    return round(sgpa, roundPrecision) #default is 2

def CGPAFromSemesterMarks(semesters: List[List[Tuple[int, int]]], roundPrecision: int = 2) -> float:
    """
    Calculate the Cumulative Grade Point Average (CGPA) of a student/individual studying in IPU.

    Parameters:
    semesters (List[List[Tuple[int, int]]]): A list of semesters where each semester is a list of tuples containing the credits and grade point of a subject.

    Returns:
    float: The calculated CGPA.

    Raises:
    ValueError: If the total credits are zero.
    """
    total_credits: int = 0
    weighted_sum: int = 0

    for semester in semesters:
        for credits, grade_point in semester:
            total_credits += credits
            weighted_sum += credits * grade_point

    if total_credits == 0:
        raise ValueError("Total credits cannot be zero")

    cgpa = weighted_sum / total_credits
    return round(cgpa, roundPrecision)
def CGPAFromSemesterSGPA(semesters: List, roundPrecision: int = 2) -> float:
    """
    Calculate the Cumulative Grade Point Average (CGPA) of a student/individual studying in IPU.

    Parameters:
        semesters (List): A list of semester GPAs.
        roundPrecision (int, optional): The number of decimal places to round the CGPA to. Default is 2.

    Returns:
        float: The calculated CGPA.

    Raises:
        ValueError: If the total credits are zero.
    """
    total_sgpa: int = 0

    for i in semesters:
        total_sgpa += i

    cgpa = total_sgpa / len(semesters)
    return round(cgpa, roundPrecision)
