Could you help me with an exercise on classes, please?

https://www.codecademy.com/paths/computer-science/tracks/cspath-python-objects/modules/cspath-python-classes/lessons/data-types/exercises/review

Hello,

I can’t do the exercise No. 7, could you help me? I would appreciate if you could not only show me the correct code but also give me an explanation. For that purpose I will ask several more things below that concerns the exercise:

Add an .add_grade() method to Student that takes a parameter, grade .

How and where should I add this .add_grade( ) method? Why is it called a method, shouldn’t a method be something that is like built-in? Not knowing what to do, I just wrote literally .add_grade(grade) in a new line and of course it gave me a syntax error.

.add_grade() should verify that grade is of type Grade and if so, add it to the Student ‘s .grades .

So if grade is of type Grade (written in code of course), I should add it to Student’s .grades. What exactly here are Student’s grades? self.grades?

If grade isn’t an instance of Grade then .add_grade() should do nothing.

How do we actually do this ‘‘should no nothing’’?

Thank you very much.

I’m not going to give you the solution, as I think you’ll learn more if we point you in the right direction and you figure it out yourself with some hints.

You have presumably defined a new class, Student. You’ll have some code, like this:

class Student:
    # your class code goes here.

When the exercise says to “add a method” to a class, it means to define a function that is part of that class. Like so:

class Example:
    def print_example():
        print('This is an example method')
        return None

thing = Example
thing.print_example()

>>> This is an example method

Here, thing.print_example() is us calling the print_example method of the Example class.

You have presumably, by this point, initialised one or more instances of your Student class, e.g.: dave = Student.

Your Student class presumably contains an attribute for grades - an attribute being a variable defined within your class - so this is where you would add it to.

If you need to provide some code to Python, but you don’t want it to do anything, you can use the pass keyword. Like so:

def favourite_food(food):
    if food == 'pizza':
        print("Excellent choice.")
    elif food == 'burgers':
        print("Right on!)
    else:
        pass

If food is not either pizza or burgers, Python will execute the pass - which essentially means it does nothing. This is a rather laboured example, but pass is useful in situations where you’re required to provide code for Python to evaluate but you don’t need it to do anything.

As an aside, I’m not a Pro user and so don’t have access to the course in question. Hence why some of my reply is a bit vague. Should hopefully help point you in the right direction, though. :slight_smile:

2 Likes

@ai-2090, the exercise that you have linked to above is part 14 of a 14-part lesson on classes. The previous 13 parts might possibly be worth reviewing, as this is important material.

methods are explained in parts 7 & 8 of the lesson, where you defined a class Circle and gave it an area() method.

Student’s grades is a list initiated for each Student object. You set it up in step 6: " In the body of the constructor for Student , declare self.grades as an empty list."

You can “do nothing” by doing nothing:

def my_method(self):
    if condition:
        do something

That’s it. If condition is not True, the method ends, and does nothing.

2 Likes

Thank you very much both for your answers, as soon as I find some free time, hopefully later during the day, I’ll retry to complete the exercise, this time using your help.

@patrickd314 I was actually thinking the same thing, that is to repeat this whole lesson on classes, although I somehow completed previous 13 parts I still don’t feel like I understand well what classes are all about, definitely the hardest thing for me so far. So probably as soon as I complete this last 14. part I’m going to repeat everything. Thank you.

Unfortunately, I still didn’t succeed. I tried various things, this is the code I’m having right now:

def add_grade(self, grade):
  if type(grade) == Grade:
    self.grades.append(grade)
ocjena (meaning ''grade'' in my language) = Student()
ocjena.add_grade()

It reports me TypeError in the line – ocjena = Student( ) – saying init() missing 2 required positional arguments: ‘name’ and ‘year’. I tried to put literally name and year between the parenthesis of Student but then it just told me that name wasn’t defined. So basically I don’t understand what kind of an error it’s reporting.

Also, why did it give me indentation error when firstly I tried to define my method with the same indent as the previous method in this class? I moved it then at the beginning of the row but honestly I thought that all the methods in the same class should be of the same indent. Looks like I was wrong.

Do you have an __init__() method that looks like this:

class Student:
  def __init__(self, name, year):
    self.name = name
    self.year = year
    self.grades = []

When Python sees a sequence of characters with no quotation marks like this: name, it assumes that the sequence is a variable, and a variable must be defined by an assignment statement (a statement using the assignment operator, =) like this:

name = "Ai-2090"

If there has been no assignment statement, then name (again, without quotes) will raise a NameError, just as you saw.

So to properly initialize a new student, you need something like:

ocjena = Student( "Ai-2090", 12)  

After that, you can call ocjena.add_grade()


Yes, the add_grade() method should be indented at the same level as __init__().

3 Likes

Thank you very much, very well explained. Unfortunately, I’m still not making it, now my code looks like this:

def add_grade(self, grade):
  if type(grade) == Grade:
    self.grades.append(grade)
ocjena = Student("Roger van der Weyden", 10)
ocjena.add_grade()

As you can see, I added “Roger van der Weyden” and 10 between the parenthesis of Student (which is 1 of 3 instances I previously created) in order to evade NameError, but now it reports AttributeError in the line ocjena.add_grade(), saying ‘Student’ object has no attribute ‘add_grade’. Could you explain please?

As for the indentation, I actually at first did define the add_grade() method at the same level as init() but then it reported IndentationError so I just moved it at the beginning of the row. I notice that the lucky thing in programming is that you can give yourself several tries when guessing the right indentation. : D Just joking, of course that the best way is to understand things.

If it is aligned like this:

class Student:
  def __init__(self, name, year):
    # init block here
  def add_grade(self, grade):
    if type(grade) == Grade:
      self.grades.append(grade)

class Grade:
  def __init__(self, score):
    # init block here

… it should work fine with

ocjena = Student("Roger van der Weyden", 10)
grade = Grade(100)
ocjena.add_grade(grade)  
1 Like

Would you mind if I send you the whole code I’m having right now, maybe that way it’ll be much simpler to notice where the problem is?

Also, I understood that in order to evade NameError I had to write something between the parenthesis of Student, but I still don’t feel comfortable about it because I wasn’t told by the exercise to write anything specific so I just wrote “Roger van der Weyden” and 10.

Here’s the code:

class Student:
  def __init__(self, name, year):
    self.name = name
    self.year = year
    self.grades = []
roger = Student("Roger van der Weyden", 10)
sandro = Student("Sandro Botticelli", 12)
pieter = Student("Pieter Bruegel the Elder", 8)
def add_grade(self, grade):
    if type(grade) == Grade:
      self.grades.append(grade)
ocjena = Student("Roger van der Weyden", 10)
ocjena.add_grade()

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

Thank you.

  1. add_grade() is a method of the Student class, so (as mentioned above) it must be indented at the same level as __init__()
  2. Put all of the calling and instantiating statements (roger =, ocjena.add_grade(), etc.) at the end, not in the middle of your class definitions.
  3. When you call ocjena.add_grade(), you must provide a grade: ocjena.add_grade(Grade(99)).

(If you want to message me, that is fine.)

1 Like