In [ ]:
class Student(object):
    '''학생 정보를 담고 있는 클래스입니다.'''
    
    # 네임맹글링을 위해 _(underscore) 두개를 넣습니다.
    __id_pos = 0
    
    def __init__(self, name):
        '''학생 이름을 저장하고 고유번호를 부여합니다.'''
        self.name = name
        Student.__id_pos += 1
        self.id_no = Student.__id_pos
        
    def get_id_no(self):
        '''학생의 고유번호를 리턴합니다.'''
        return self.id_no

In [ ]:
Student._Student__id_pos

In [ ]:
class Subject(object):
    
    def __init__(self, title):
        self.title = title

In [ ]:
class GradeBooks(object):
    '''과목별로 학생들의 점수를 관리하는 클래스입니다.'''
    
    def __init__(self, subject):
        '''과목이름을 받아서 저장하고 학생 리스트와 점수를 위한 딕셔너리를 초기화합니다.'''
        self.subject = subject
        self.students = []
        self.grades = {}
        
    def add_student(self, student):
        '''student 오브젝트를 추가합니다.'''
        if student in self.students:
            return
        self.students.append(student)
        self.grades[student.get_id_no()] = []
    
    def add_grade(self, student, grade):
        '''student 오브젝트와 점수를 받아서 grades 딕셔너리에 추가합니다.'''
        id = student.get_id_no()
        if id in self.grades:
            self.grades[id].append(grade)
            
    def add_grades(self, student, grades):
        '''student 오브젝트와 점수 리스트를 받아서 grades 딕셔너리에 추가합니다.'''
        id = student.get_id_no()
        if id in self.grades:
            self.grades[id].extend(grades)
            
    def get_grade(self, student):
        '''학생이 가지고 있는 모든 점수를 리스트로 리턴합니다.'''
        id = student.get_id_no()
        if id in self.grades:
            return self.grades[id].copy()
        return None
    
    def all_students(self):
        '''저장된 모든 학생정보 리스트를 복사하여 리턴합니다.'''
        return self.students.copy()
    
    def best_student(self):
        '''학생별로 점수를 평균내고 가장 높은 점수와 학생 이름을 리턴합니다.'''
        mean_grade = []
        for student in self.students:
            id = student.get_id_no()
            mean = sum(self.grades[id]) / len(self.grades[id])
            mean_grade.append((mean, student.name))
        mean_grade.sort()
        return mean_grade[0]

In [ ]:
bob = Student('bob')

In [ ]:
tom = Student('tom')

In [ ]:
jane = Student('jane')

In [ ]:
math_subj = Subject('math')

In [ ]:
math = GradeBooks(math_subj)

In [ ]:
math.add_student(bob)

In [ ]:
math.add_student(tom)

In [ ]:
math.add_student(jane)

In [ ]:
math.add_grade(bob, 100)

In [ ]:
math.add_grade(bob, 70)

In [ ]:
math.add_grades(bob, [50,30,20])

In [ ]:
math.get_grade(bob)

In [ ]:
math.add_grade(bob, 50)

In [ ]:
math.add_grade(tom, 80)

In [ ]:
math.add_grade(tom, 90)

In [ ]:
math.add_grade(tom, 70)

In [ ]:
math.add_grade(jane, 80)

In [ ]:
math.all_students()

In [ ]:
math.best_student()

In [ ]: