Python Classes Review - Further Practice Discussion

It’s also nice to incorporate the minimum_passing attribute of Grade into the Student class, to check if a student will pass given their average:

  def will_pass(self):
    return self.get_average() >= Grade.minimum_passing

Anyway, I finally understand this lesson completely. Thanks for the support here on the forums everyone!

1 Like

I am completely lost.
I can’t make get_average to work. Tried everything that my beginner brain could think of or fin on blogs. Could someone explain, please, what am I doing wrong? Please :slight_smile:

class Student:
    def __init__(self, name, year):
        self.name = name
        self.year = year
        self.grades = []

    def add_grade(self, grade):
        if type(grade) == Grade:
            self.grades.append(grade.score)

    def get_average(self):
        avg = 0
        for i in self.grades:
           avg += i
        return avg/len(self.grades)

class Grade:
    minimum_passing = 65

    def __init__(self, score):
        self.score = score

    def is_passing(self):
        if self.score >= Grade.minimum_passing:
            return True
        else:
            return False


# execute
roger = Student("Roger van der Weyden", 10)
sandro = Student("Sandro Botticelli", 12)
pieter = Student("Pieter Bruegel the Elder", 8)
x = Grade(60)
pieter.add_grade(x)
pieter.add_grade(Grade(77))

print(pieter.get_average)
pieter.grades.is_passing

A Grade object has a 'score' attribute. See the add_grade method for a hint.

Ok, i get that.
Thats why in add_grade i did self.grades.append(grades.score) thus I’d have the number directly stored in self.grades.
But that apparently doesn’t work. I tried :
For i in self.grades.score
Or
For i in self.grades:
Avg += i.score that only gives an error no .score for list.
Thus I’m lost… What am I missing ?

What if instead of appending the score, we append the actual Grade object?

class Student:
  def __init__(self, name, year):
    self.name = name
    self.year = year
    self.grades = []
    
  def add_grade(self, grade):
    if type(grade) == Grade:
      self.grades.append(grade.score)
  
  def get_average(self):
    self.average = 0
    if len(self.grades) > 0:
      for i in self.grades:
        self.average += i
      self.average = self.average / len(self.grades)
    print(self.average) #<------ This prints the expected average value
  
roger = Student("Roger van der Weyden", 10)

class Grade:
  def __init__(self, score):
    self.score = score
  
grade1 = Grade(100)
grade2 = Grade(35)
grade3 = Grade(73)

pieter.add_grade(grade1)
pieter.add_grade(grade2)
pieter.add_grade(grade3)

print(pieter.get_average()) #<------ This prints None

Why does the print line in the get_average method print the proper average value, but calling the method in it’s own print line at the bottom returns ‘None’?

Edit: Nvm, adding a

return self.average

line at the bottom of the .get_average method definition did the trick. I just don’t understand why. All other method definitions didn’t require a return line to work as expected, why did this one need it?

None is the absence of a return value.

you can also do:

pieter.get_average()

now the return value (or absence of one), isn’t print

but, using return is better. This means you can access this number outside of the class (do further math for example)

A post was merged into an existing topic: How can I access Pieter’s grade after it has been added?