How can I access Pieter's grade after it has been added?

I just finished working my way through this exercise and am left with a couple of questions. Here is my (solution) code for reference:

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)

class Grade:
  minimum_passing = 65
  
  def __init__(self, score):
    self.score = score
    
roger = Student("Roger van der Weyden", 10)
sandro = Student("Sandro Botticelli", 12)
pieter = Student("Pieter Bruegel the Elder", 8)

pieter.add_grade(Grade(100))
1. Just to make sure, `if type(grade) == Grade` is checking if an instance of `Grade` was used to pass into `grade`? And `type(grade)` returns `<class '__main__.Grade'>` because an instance of `Grade` was passed in?

2. Why does `pieter.add_grade(Grade(100))` append `<__main__.Grade object at 0x7f40fdbf5a20>` to `self.grades` and not `100`?
  1. That’s pretty much what it does, check that the parameter is a Grade instance.

  2. The 100 is assigned to the instance variable, score.

    print (Grade(100).score) # 100

But how I can get Pieter’s Grade?
print(pieter.grades)
give me a - [<main.Grade object at 0x7f258e2eca20>]

grade is an object which has properties, which property holds his score?

I can’t figure out how to print out the list of Pieter’s grades after I add the grade of 100 to his list of grades. Could someone explain to me how I can do that?

image

You will be able to access the grades attribute on the instance…

pieter.grades

Hello, @kbiz.

Are you seeing something like this when attempting to print(pieter.grades)?

[<__main__.Grade object at 0x7ff92e16dcf8>]

1 Like

Because Grade objects have a score attribute, we need to drill down, which can be done easiest with a method.

def print_grades(self):
    for grade in self.grades:
        print grade.score
    return 1

That should be added to the Students class definition, which will then,

pieter.print_grades()

Since this is a Python 3 exercise, we’ll need to invoke print as a function, with parentheses included.

1 Like

D’oh! Thanks for pointing that out.

It seems simpler to change their add_grade methods so that instead of appending or adding grade, they were appending/adding grade.score.

As for your print_grades method, is there a reason we’d want to have the Student grades list entries be Grade objects instead of integers?

1 Like

Integers have no attributes save those inherited from int(). By maintaining an instance of Grade, we can tack on any useful methods we wish and have them apply. If Grade is not in play, then the methods have to be tacked on to Student, which makes very little sense.

1 Like

Thanks for this. Just one question. What does return 1 do?

Nothing, really. It doesn’t need to be there.

@mtf thanks for your input,

A quick question though, with your new method, when printing out or calling the pieter.print_grades() method, it individually prints out each score instead of printing out the list of scores that it should be.

I have a gut feeling that we should be using the repr method to get back a string however I can’t quite wrap by head around it.

I tried using:

  def __repr__(self):
    return self.grades

but it didn’t do anything. Any guidance?

According to you, what does the __repr__ method do?

If you want the print_grades method to give different output, you would have to change the body of the function

how are you able to access a “.score” from class “Grade” there?

We confirmed that all new Student instances have Grade objects in their grades array. Each of these objects have a score property.

1 Like

self.grades is under the class “Grades”, how is it possible to add a type “Grades” variable. it only works for integer or floats.
it return this error for me:
TypeError: unsupported operand type(s) for +: ‘int’ and ‘Grade’

Chief interest above is that we are dealing with an array of objects, a list of dictionaries.