Https://www.codecademy.com/courses/learn-python-3/lessons/data-types/exercises/review

https://www.codecademy.com/courses/learn-python-3/lessons/data-types/exercises/review

Hi there,

I think I’m stuck, but I’m not sure as I’m getting all by boxes neatly checked. 'm not sure if my is_passing, and my get_average methods will work as I’m having a lot of trouble understanding this chapter in Python.

This is my code, anybody see anything odd?:

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):

     total = 0

     for grade in self.grades:

       total += grade

     avg = total / len(self.grades)

     return avg

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 score > minimum_passing:

      return True

    

pieter.add_grade(Grade(100))

Hi, I would play with the objects you created.

So now that you’ve added a grade for pieter, can you check his grade, average, is_passing with a print statement?

I will try that, if I can figure out how… This OOP is at this piont still a little vague to me…

It’s ok to experiment with small things!

>>> class Person:
...      def talk(self):
...          print("hello world")
... 
>>> random_guy = Person()
>>> random_guy.talk()
hello world #this is the output
>>> class Person:
...     def __init__(self, name):
...         self.name = name
...     def speak_own_name(self):
...         print("my name is " + self.name)
... 
>>> joe = Person("Joe")
>>> jane = Person("Jane")
>>> joe.speak_own_name()
my name is Joe
>>> jane.speak_own_name()
my name is Jane

Hi there, I tried print(pieter), which gives me the memory location of pieter, I think.

I’d better start this part of the course again, because I just don’t seem to get it (and especially, how to use all the commands and methods).
As long as I don’t understand how everything’s working on everything else, it’s no use wasting someone else’s time and energy.

Cheers for your help so far!

Yea no worries!

It’s a complex topic so you’re doing the right thing on trying to get a good grasp of the fundamentals. Just ask here freely if you have more questions.

Exactly! No point in doing all the exercises exactly along the lines without understanding the framework. Thanks again, I won’t hesitate to ask.

Hey toastedpitabread,

I’m back for more questions. Still stuck at the same exercise. This is my code, and the last box is neatly checked again, but how do I know if it works and whether I made any mistake? When I run the code, all is fine, no errors:

class Student:

def init(self,name,year):

self.name = name

self.year = year

self.grades = []

def get_average(self):

total = 0

for grade in self.grades:

  total += grade

  avg = total / len(self.grades)

  return avg

def add_grade(self,grade):

if type(grade) is 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.grade >= minimum_passing:

  return "passed"

else:

  return "not passed"

pieter.add_grade(Grade(100))

Hi @dn1975,

A sensible thing is to test the methods and properties of your instance pieter of class Student (methods are functions that belong to classes).

You have 2 methods of which one was uses (though not tested). You also have 3 properties to the student class you can test.

A very simple example you can run at the end of your code

#access using dot operator
print(pieter.name)
print(pieter.year)
print(pieter.grades)
print(pieter.get_average())
print(pieter.add_grade(Grade(some_number)))

etc.
I would also note that to test the methods that have an effect on your class instance, you can either add some debug message to just double check that it’s running properly, or access the property after to test if a change was made.

N.B:

Since the first post was formatted I got the gist of the code, but in python unformatted code is not possible to read (constructively), so check out this note when you can: [How to] Format code in posts

And an extra note:
Once you’re comfortable with the gist of the above, try to see if you can access the is_passing() of Grade method via pieter (now that pieter has an instance of Grade). You can always ask if you need a hint for how this is done.

Thanks again! The first test I ran was print(pieter.is_passing), which, didn’t work. Is that because the method is_passing is only working for the class Grade?

And then, I get this message:

File “script.py”, line 16, in get_average
total += self.grade
AttributeError: ‘Student’ object has no attribute ‘grade’.

But in the method before get_average, I attributed grade to Student, I’d think…

Hi,

Yes, I think the lesson is structured a bit more complex than how one would write it for the purpose of making you discover how things interact.

total += self.grade doesn’t work because grade is a whole object, not a number. If you want to access the value of grade you have to write something like self.grade.score (this is a bit contrived, usually it would have better semantic synergy… but I digress).

As for the is_passing(), the thing to note is that the method also belongs to the grade object. So you’d have to ask it of one of the objects for pieter that is of class Grade.

I think in a way this lesson is a good puzzle, but it is a bit steep if you haven’t done classes before. So let’s think about this:

Pieter has a property grades which is an array of objects of the Grade class. is_passing() can be used on each single one of those objects. But, collectively, when you write get_average() you are getting back just a numerical representation of a grade (which you can’t check whether it’s passing or not)…

So… You’d have to convert (or preprocess) the get_average() result into a Grade class object to verify if it is_passing().

Confusing? The thing to do would be to draw a map in this type of situation. One may argue that is a convoluted way of setting up a simple structure, but in a way it prepares the learner to be able to tackle more complex data structures that do have this type of interplay.

Well, clearly I don’t get the gist of it :wink:

How is it that grade is not a number, when the add_grade method is checking a given grade to the class Grade?

I actually drew a map, by the way! That was the only way to get some visual perspective. However, in my case it turned to be a collection of boxes, circles and arrows that didn’t really clear things up. But it could certainly be helpful.

I appreciate your help a lot, but it’s just frustrating for me that I don’t understand the cohesion in all this.

I think I’ll leave this exercise for now, and just move on. Thanks for your time and support!

No problem!

That’s my exact issue with the exercise.

grade is an instance of Grade… which is not a number. The instance “holds” a number value named score. So the only way to get the value of grade is to write grade.score.

You define it here:

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

Best of luck!

Ah, I was already wondering why I defined it :wink: