One More Lecture with Classes and Objects

We have time this semester for one more exposure to classes. Today is mainly a case study on writing a student grade tracker. We will not just define a Student class, but show how classes can hold complex data, and how they make programming easier.

Reading

For a review of classes you can re-read Chapter 14.

Today in Class

  1. Creating multiple instances of a class.
  2. Storing class instances in a list.
  3. Class definitions with lots of data.

You should be able to understand this program.

The grades.txt input file goes with this:

class Student:
    def __init__(self, name, a):
        self.name = name
        self.alpha = a
        self.grades = dict()

    def add_grade(self, assignment, grade):
        self.grades[assignment] = grade

    def get_grade(self, assignment):
        return self.grades[assignment]

    def get_all_grades(self):
        """ Return all grades sorted alphabetically by assignment """
        allgrades = list()
        for key in sorted(self.grades.keys()):
            allgrades.append(self.grades[key])
        return allgrades

    def get_all_assignments(self):
        """ Return all grades sorted alphabetically by assignment """
        return sorted(self.grades.keys())

    def print(self):
        print(self.name + '\t' + self.alpha, end='\t')
        print(self.get_all_grades())

        
def read_file(filename):
    """ Create a List of students from a file of grades. """
    students = list()
    
    fh = open(filename)
    for line in fh:
        parts = line.split()
        student = Student(parts[0], parts[1])

        for i in range(2,len(parts)):
            student.add_grade('hw'+str(i-1), int(parts[i]))
        
        students.append(student)

    return students



# Read a file of student grades into a List of Student objects.
students = read_file('grades.txt')
for st in students:
    st.print()

# USER INTERACTION
q = input('Query: ')
while q != 'quit':

    # 'add brown hw5 98'
    if q.startswith('add'):
        parts = q.split()
        name = parts[1]
        assign = parts[2]
        grade = parts[3]
        # Find the student and update grade!
        for s in students:
            if s.name.lower() == name.lower():
                s.add_grade(assign, int(grade))

    # 'get brown hw5'
    elif q.startswith('get'):
        parts = q.split()
        name = parts[1]
        assign = parts[2]
        # Find the student and update grade!
        for s in students:
            if s.name.lower() == name.lower():
                print(s.get_grade(assign))

    elif q == 'quit':
        break
    
    # 'brown'  -- just a student's name
    else:
        name = q
        # Find the student and print!
        for s in students:
            if s.name.lower() == name.lower():
                s.print()
                
    q = input('Query: ')