How to check for passing in the Grade class?

Did you try,

pieter.is_passing()

?

I did! It gave me,
AttributeError: 'Student' object has no attribute 'is_passing'

It looks as though there might be a missing method to obtain the average score. That result would be what to call the is_passing method on…

print ( Grade(pieter.get_average()).is_passing() )

It’s a thought.

1 Like

Thanks, I’ll give that a try! I didn’t write the average method yet, but I’ll do that and see if it completes the puzzle.

1 Like

Man, I breezed through all of Python up until this point, and this is just an insane roadblock that I’m not getting through at all ;(

Anyway, I’m having trouble using the is_passing() method. Here is my code:

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

  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)
pieter.add_grade(Grade(100))
x = Grade(70)
print(x.is_passing())
pieter.grade.is_passing()

When I do that, like you suggested, I get an attribute error:
AttributeError: 'Student' object has no attribute 'grade'

Any ideas? x.is_passing works fine.

1 Like

here:

pieter.grade.is_passing()

does pieter (which is instance of Student class) have a grade attribute? lets see:

    self.name = name
    self.year = year
    self.grades = []

i only see name, year and grades attribute

here:

def add_grade(self, grade):

grade is a parameter of the add_grade method, just like functions, scope rules apply.

in the add_grade method we add the grade to the array (which is an attribute of Student, maybe we could use this?

1 Like

EDIT:
Ah!! I got it!!
I tried to switch it to
pieter.grades.is_passing()

and it said that wouldn’t work on a list, so I wrote a for loop like

for grade in pieter.grades:
  print(grade.is_passing())

And that worked!! Thanks for calling attention to that!

1 Like

Would checking each grade in turn be any indication of having a passing grade? Not really.

There is a method missing in the Student class…

Write a Student method get_average() that returns the student’s average score.

It is in this way that we can obtain a single grade to test.

average = pieter.get_average()

There is no way to tie this to Grade as an instance so we create a transient instance using that average and then call the is_passing() method on that instance.

print ( Grade(average).is_passing() )
3 Likes

Hi,

I am trying to print out the contents of self.grades with repr but it does not work.
What am I missing here?
Thanks!

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)
      return self.grades
    else:
      pass

     
  def get_average(self):
    for student in self.grades:
      return student
  
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 > Grade.minimum_passing:
      return True
    else:
      return False
     
    def __repr__(self):
      print('Your grade is {grade}'.format(grade = self.grades))

pieter_grade = Grade(60)
pieter.add_grade(pieter_grade)
print(pieter.grades)

i don’t see you attempting to print pieter_grade anywhere?

Also, the __repr__ method seems to be nested within the is_passing function

furthermore, the __repr__ method seems to be part of Grade class, while you seem to intent to change the default representation of the Student class.

Grade has no attribute grades.

After I added a grade to add_grade, I actually want to fetch the content of self.grades list. I tried it with simply print(pieter.grades) but it just print the object id

pieter_grade = Grade(60)
pieter.add_grade(pieter_grade)
print(pieter.grades)

When I try to to embed repr in Students to make pieter.grades visible, it does not give me anything.

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)
      return self.grades
    else:
      pass

  def __repr__(self):
    return 'Your grade is {grade}'.format(grade = self.grades)
  
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 > Grade.minimum_passing:
      return True
    else:
      return False

pieter_grade = Grade(60)
pieter.add_grade(pieter_grade)
print(pieter_grade.is_passing())
print(pieter.grades)

I guess, I still haven’t understood how __repr__works.
Thanks

You’re getting closer, though. Now you have it in the correct class.

__repr__() will return a representation of the object instance.

  def __repr__(self):
    return f"Name: {self.name}\nYear: {self.year}\nGrade: {self.get_average()}"

The above assumes your Student class has a get_average method. We access this by printing the instance…

 print (pieter)

Output

Name: Pieter Bruegel the Elder
Year: 8
Grade: 92.75
1 Like

Ok, I came up with this solution, but I think it is not very pythonic.

Can you please review and give me some recommendations for cleaner code. Is there a way to write the add_grade() and is_passing() calls at the end in one line?

Thanks!

class Student:
  
  def __init__(self, name, year, day):
    self.name = name
    self.year = year
    self.day = day
    
    self.grades = []
    
    self.attendance ={'Monday':True, 
                    'Tuesday':False, 
                    'Wednesday':False,
                   'Thursday':True,
                   'Friday':True}
  
  def add_grade(self, grade):
    if type(grade) == Grade:
      self.grades.append(grade)
    
  def get_average(self):
    x = 0
    for student in self.grades:
      x += student.score
      return x/(len(self.grades))
  
  def availability(self):
    for key, val in self.attendance.items():
      if key == self.day:
        return val
    
       
  def __repr__(self):
    return f'Name: {self.name}\nYear: {self.year}\nGrade:{self.get_average()}\Attendance: {self.availability()}'
  
  
pieter = Student('Pieter Bruegel the Elder', 8, 'Wednesday')


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

pieter_grade = Grade(100)
pieter_grade1 = Grade(80)
pieter_grade2 = Grade(60)

pieter.add_grade(pieter_grade)
pieter.add_grade(pieter_grade1)
pieter.add_grade(pieter_grade2)

pieter_grade.is_passing()
pieter_grade1.is_passing()
pieter_grade2.is_passing()

pieter.get_average()
pieter.availability()

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

Consider the expression,

self.score >= Grade.minimum_passing

It has only two possible outcomes, either it is a true assertion, or it is false. That means we can return it without the if..else coming into play, at all.

As for the add_grade method, making it into a one-line return will take some convoluted logic that will not be superior to the simple if question, even if it does look clever.

self.grades += [grade] if type(grade) == Grade else []
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)

   else:

     return

class Grade:

  minimum_passing = 65

  def __init__(self, score):

     self.score = score

  def is_passing(self):

     if self.score > self.minimum_passing:

      return True

     return False

roger = Student("Roger van der Weyden", 10)

sandro = Student("Sandro Botticelli", 12)

pieter = Student("Pieter Bruegel the Elder", 8)

pieter.add_grade(Grade(100))

How can I check is_passing method here without having get_average method?

Thank you in advance

is_passing currently can only handle individual grades/scores.

Thank you @stetim94. Please can you let me know , how can I modify it to obtain output as per assignment ?

You have completed the exercise? Now you simple call is_passing on each grade to see if they passed the exam.

Very disappointing end to this module. The course has been great overall, but the whole “is_passing” part leaves a lot of ambiguity about what to do. Are you assuming that we write the “is_passing” method but don’t actually do any testing until further challenges (average) are completed? I’d propose revising this end of module to have some more steps and hints along the way.

13 Likes