Code:
from dataclasses import dataclass
from pprint import pprint
from statistics import mean


@dataclass
class GradeRecord:
    course_name: str
    grades: list[float]

    ###
    ### Part a)
    ###

    def avg_grade(self) -> float:
        num_grades = len(self.grades)
        if num_grades == 0:
            return -1
        return sum(self.grades) / num_grades

    def avg_grade2(self) -> float:
        if self.grades:
            sum = 0.0
            for grade in self.grades:
                sum += grade
            return sum / len(self.grades)
        return -1

    def avg_grade3(self) -> float:
        if len(self.grades) == 0:
            return -1
        return mean(self.grades)

    ## End of Part a)


@dataclass
class Student:
    id: str
    first: str
    last: str
    grade_records: list[GradeRecord]


# fmt: off
student1 = Student(id="S001", first="Jane", last="Doe", grade_records=[
    GradeRecord("Math", [6.0, 6.0, 6.0]),
    GradeRecord("English", [4.5, 5.0, 6.0]),
    GradeRecord("History", [6.0, 6.0, 6.0]),
    GradeRecord("Physics", [5.0, 5.5, 5.0]),
])

student2 = Student(id="S002", first="John", last="Smith", grade_records=[
    GradeRecord("Math", [5.5, 6.0, 4.5]),
    GradeRecord("English", [5.5, 5.5, 5.5]),
    GradeRecord("History", [4.5, 5.0, 5.5]),
    GradeRecord("Physics", [5.0, 5.5, 5.0]),
])
# fmt: on

all_students: list[Student] = [student1, student2]


###
### Part b)
###


def get_average_grade(all_students: list[Student], student_id: str, course_name: str) -> float:
    for student in all_students:
        if student.id == student_id:
            for grade in student.grade_records:
                if grade.course_name == course_name:
                    return grade.avg_grade()
    return -1


def get_average_grade2(all_students: list[Student], student_id: str, course_name: str) -> float:
    for student in all_students:
        if student.id != student_id:
            continue
        for grade in student.grade_records:
            if grade.course_name != course_name:
                continue
            return grade.avg_grade()
    return -1


## End of Part b)


###
### Part c)
###

indexed_avgs: dict[str, dict[str, float]] = {}
for student in all_students:
    indexed_avgs[student.id] = {}
    for grade_record in student.grade_records:
        indexed_avgs[student.id][grade_record.course_name] = grade_record.avg_grade()

## End of Part c)


pprint(indexed_avgs)
Last modified: Monday, 8 July 2024, 15:55