How to I iterate though list of elements that belong to a class that is not iterable and return a list at the end?

I want to print out the list of the grades of a student (i.e [100,90,80] ) but this code below gives me TypeError: ‘Grade’ object is not iterable. I don’t know how to do it. Could someone help me?

class Student:
  def __init__(self, name, year):
    self.name = name
    self.year = year
    self.grades = []
  
  def add_grade(self, grade):
    if type(grade) is Grade:
      self.grades.append(grade)    
  def get_average(self):
    Sum = 0
    for g in self.grades:
      Sum += g.score
    ave = Sum / len(self.grades)
    print(ave)
  def print_grades(self):
    lst=[]
    for grade in self.grades:
      lst += grade

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

  def is_passing(self,score):
    if self.score >= Grade.minimum_passing:
      return "Passed" 
    
roger = Student("Roger van der Weyden", 10)
sandro = Student("Sandro Botticelli", 12)
pieter = Student("Pieter Bruegel the Elder", 8)

pieter.add_grade(Grade(100))
pieter.add_grade(Grade(90))
pieter.add_grade(Grade(80))

pieter.print_grades()


Just check type(self.grades) right before you hit this code.

for grade in self.grades:

Should give you some clues.

1 Like

Thanks for your reply!
It’s a list, isn’t it? But I still have no clue how to print a list of grades in a readable way. I just started on Python so am very inexperienced.
The problem is that if I simply print(self.grades), it only gives me this :

[<__main__.Grade object at 0x000002EDCB754D08>, <__main__.Grade object at 0x000002EDCB754D48>, <__main__.Grade object at 0x000002EDCB754D88>]

Well, it’s a list of grade class objects. Not the actual grades themselves. You have to call their .score for that.

As a technical note you have to append these items to lst in the for-loop, not += them, that’s why the error is happening.

1 Like

If you were looking for a meaningful print output from those objects there’s a few ways of going about it.

You could for example just cycle through the objects in your list and print meaningful attributes from them or, and this might be the better choice in the long-run, you could look into the print friendly dunder methods for objects in Python-
https://docs.python.org/3/reference/datamodel.html#object.__str__

For this particular lesson though I think @toastedpitabread’s guidance may be more helpful.

2 Likes

@sh8421171557

Yes, you should also look at @tgrtim’s suggestions when you get more situated. __str__ and __repr__ can be useful! More on that: https://stackoverflow.com/questions/1436703/difference-between-str-and-repr

1 Like

As stated above, dunder methods might be a good way to do this, especially since you already have a Student class and a Grade class.

Something else to consider is that if you have a list of strings, you can use the str.join() method to assemble the items. In the current case, you would need to convert the numbers to strings. Try this, and revise as desired:

  def print_grades(self):
    print("Grades: " + ", ".join([str(grade.score) for grade in self.grades]))

Output:

Grades: 100, 90, 80
3 Likes

OH Great! Thanks a lot.

1 Like