General Question regarding classes

I am currently working on the Review assignment for Python Classes.
Python Classes | Codecademy

I am nearly done with the assignment but am hung up on the final questions. I got the get_average method to function correctly but am not sure how to get my is_passing method to tell me if the average score is greater than 65 or not. Since the is_passing is in the grade class when I try to use it on pieter_average_grade I get an AttributeError.
Also, there are so many lines of code just to get pieter_avg_grade, If he had 50 grades, doing it this way I’d need 100 lines lol… This works how I’d like it to but I feel there has got to be something I am missing to shorten it up.
one final quick question, if I wanted to print a string with the average grade, like "Pieters average grade is: " could I put it in the return for the get_average method and use {self.name} ? couldnt get that to work for me
Thank you for your time!

class Student:
  def __init__(self, name, year):
    self.name = name
    self.year = year
    self.grades = []
  def __repr__(self):
    return 'Students name and year: {self.__class__.__name__}({self.name}, {self.year})'.format(self=self)
  
  def add_grade(self, grade):
      if type(grade) == Grade:
        self.grades.append(grade)
        return self.grades
      else:
        pass

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

class Grade:
  minimum_passing = 65
  def __init__(self, score):
    self.score = score
 # def __repr__(self):
  #  return '({self.score})'.format(grade = self.grades)
  def __repr__(self):
    return '({self.__class__.__name__}({self.score}))'.format(self=self)

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

roger = Student("Roger van der Weyden", 10)
sandro = Student("Sandro Botticelli", 12)
pieter = Student("Pieter Bruegel the Elder", 8)
print(pieter)
print(roger)
print(sandro)
pieter_grade1 = Grade(75)
pieter_grade2 = Grade(45)
pieter_grade3 = Grade(88)
sandro_grade1 = Grade(95)
sandro_grade2 = Grade(88)
sandro_grade3 = Grade(73)
pieter.add_grade(pieter_grade1)
pieter.add_grade(pieter_grade2)
pieter.add_grade(pieter_grade3)
sandro.add_grade(sandro_grade1)
sandro.add_grade(sandro_grade2)
sandro.add_grade(sandro_grade3)

print(pieter.grades)

pieter_avg_grade = pieter.get_average()
sandro_avg_grade = sandro.get_average()
print(pieter_avg_grade)
print(sandro_avg_grade)
pieter_passing = pieter_avg_grade.is_passing()
print(pieter_passing)

Your method get_average from the student class should be returning a float value so it wouldn’t have an is_passing method. It winds up a bit like doing x = 3.5 followed by x.is_passing() and therefore throws the attribute error.

If you wanted to use it like this you could make your get_average method return an instance of the Grade class instead which would then have the is_passing method bound to it (it would no longer behave like a float elsewhere though).

As for having too many lines I’d have thought by now that data types like lists should have been covered along with loops. Use of these would help with the DRY principle.

As for your final point, yes, you could set that up but consider whether you want this function to return a float, an instance of Grade or a string (and whether or not you also want lines printed to stdout). What is it you tried that didn’t work?