Python Classes Review - Further Practice Discussion

Did anyone try the the bonus practice in the review?

I seem to be having a challenge with the including the get_average() method.

One thing I observed was that the .grades was printing out in string representation form and when I included repr in an attempt to debug it, I got a ‘NoneType’ error traceback. Here is code below: (can anyone spot the error?)

class Student(object):
attendance = {}
def init(self, name, year):
self.name = name
self.year = year
self.grades = list()

def repr(self):
print(self.name, self.year, self.grades)

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

roger = Student(“Roger van der Weyden”, 10)
sandro = Student(“Sandro Botticelli”, 12)
pieter = Student(“Pieter Bruegel the Elder”, 8)

class Grade:
minimum_passing = 65
def init(self, score):
self.score = score
def is_passing(self):
if self.score > self.minimum_passing:
return “Yes”
else:
return “No”

value = Grade(100)
pieter.add_grade(value)

print(pieter.grades)

One thing that you did wrong is writing init keyword without underscores before and after it. So it should be like this to work: __init__.

2 Likes

I have the same question, did anybody figure it out

I just figured you need to add the repr() method in your grade class to print out the list of grades without just showing the memory location

class Grade:
minimum_passing = 65

def init(self, score):
self.score = score
def repr(self):
return str(self.score)

3 Likes

Hey thanks.

I did a copy and paste but that didnt work…I have it in dunder in the actual code

Hey thanks. That worked.

But I’m still stuck on why my get_average does not work.

Did you by chance use a for loop?

def get_average(self):
total = 0
for grade in self.grades:
total += grade
return total

I get unsupported type error.

In case you struggled with this as well. I just made Grade a subclass of ‘int’ and it seemed to recognize this.

5 Likes

My code is follow:
class Student:
def init(self, name, year):
self.name = name
self.year = year
self.grades =
self.attendance = {}

def add_grade(self, grade):
if type(grade) == Grade:
self.grades.append(grade.score)
def get_average(self):
return sum(self.grades)/ len(self.grades)

9 Likes

3 posts were split to a new topic: How might the add_grade method yield integers into Pieter’s grades list?

The last step in this exercise gives some additional things you could do with the classes’ you just created, and one of those things is:
“Write a Student method get_average() that returns the student’s average score.”

First here is the code I am working with, I have changed it slightly from what you end up with in the exercise for the sake of solving the “get_average” problem.

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

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

    def get_average(self):
        return  #???

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


S = Student()

grade_obj_1 = Grade(100)
grade_obj_2 = Grade(50)

S.add_grade(grade_obj_1)
S.add_grade(grade_obj_2)

At this point I have no idea how I could go about getting the average of a students grades, because they have been added to the grades list as Grade objects, so I cannot preform any kind of calculation on to return a value.

2 Likes

the average is the sum divided by the length, and within the get_average method you have access to the self.grades instance variable.

1 Like

But the self.grades variable is just a list with 2 Grade objects in it.

print(S.grades)

Output: 
[<__main__.Grade object at 0x7f150a301668>, <__main__.Grade object at 0x7f150a3016a0>]

And if I try to do any kind of calculation on these Grade objects I get an error

S.grades[0] + S.grades[1]

Output:
  File "script.py", line 25, in <module>
    S.grades[0] + S.grades[1]
TypeError: unsupported operand type(s) for +: 'Grade' and 'Grade'

I get the same error if I try to do the calculation in the get_average method in the Student Class.
Could you maybe provide an example of how I could preform calculations on these objects?

1 Like

Hello, @fox3773.

grades is a list containing Grade objects as you’ve mentioned. You need to access the property of the Grade object that contains the value. You are almost there with S.grades[0]. That is the first grade object. How do you access its property?

Hint
class Grade:
    def __init__(self, score):
        self.score = score
             ^^^^^
5 Likes

Thanks @midlindner,
This really did help, but it still took me a long time to figure out I was looking for S.grades[0].score
I am definitely going to need some more time to get a handle on classes.

2 Likes

Since we are instantiating a Grade class within the argument of the add_grade() method, it doesn’t get assigned as a referable instance except by accessing the grades instance variable (the list of grades).

pieter.add_grade(Grade(100))
  def get_grades(self):
    return [x.score for x in self.grades]
grades = pieter.get_grades()
print (grades[0])    # 100
4 Likes

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!

3 Likes

4 posts were split to a new topic: Can’t make get_average to work

2 posts were split to a new topic: Why did this one need return?