Where do I need to include raisins?

Shouldn’t the method in subclass of the exercise be changed from “def init(self, potatoes, celery, onions):” into “def init(self, potatoes, celery, onions, raisins):” i mean what would the “self.raisins = 40” refer to, if the content of the method in subclass be the same as in the parent class?

1 Like

Good point. The example does not really make much sense either way, but including the raisins in the subclass init() method does work. This code also passes the exercise:

class SpecialPotatoSalad(PotatoSalad):
  def __init__(self,potatoes, celery, onions, raisins = 40):
    super().__init__(potatoes, celery, onions)
    self.raisins = raisins
2 Likes

True, but does the code work if you don’t include “raisins” in the constructor for the subclass? Instinctively, I find it weird to declare

self.raisins = 40

without including “raisins” in the constructor.

@byteninja93187, you’re right: it does not work:

class SpecialPotatoSalad(PotatoSalad):
  def __init__(self, potatoes, celery, onions, raisins = 40):
    super().__init__(potatoes, celery, onions)
    self.raisins = raisins
    
sps = SpecialPotatoSalad(3,4,5)
print(sps.raisins)

# Output:
40

Now, comment out the line self.raisins = raisins

class SpecialPotatoSalad(PotatoSalad):
  def __init__(self, potatoes, celery, onions, raisins = 40):
    super().__init__(potatoes, celery, onions)
    # self.raisins = raisins

sps = SpecialPotatoSalad(3,4,5)
print(sps.raisins)

# Output:
Traceback (most recent call last):
  File "script.py", line 13, in <module>
    print(sps.raisins)
AttributeError: 'SpecialPotatoSalad' object has no attribute 'raisins'

Thanks, but I (and I think the previous contributors as well) was actually wondering whether the below would work:

class SpecialPotatoSalad(PotatoSalad):
  def __init__(self, potatoes, celery, onions):
    super().__init__(potatoes, celery, onions)
    self.raisins = raisins

Would you be able to declare the instance variable “self.raisins” without including it as a parameter in the constructor?

To me, it seems impossible but I definitely passed the exercise this way.

Not if you try to actually instantiate an object!

class SpecialPotatoSalad(PotatoSalad):
  def __init__(self, potatoes, celery, onions):
    super().__init__(potatoes, celery, onions)
    self.raisins = raisins
    
sps = SpecialPotatoSalad(3,4,5)
# print(sps.raisins)

# Output:
Traceback (most recent call last):
  File "script.py", line 12, in <module>
    sps = SpecialPotatoSalad(3,4,5)
  File "script.py", line 10, in __init__
    self.raisins = raisins
NameError: name 'raisins' is not defined
1 Like

Thanks, I’ll report it!

… and it doesn’t pass:capture

If you put inself.raisins = 40, you are assigning a value to raisins, but self.raisins = raisins throws a name error.

Suprisingly many examples in this course don’t… :frowning: the deeper we go the dumber it gets.
I mean - for real, potato salad?
My contribution:
potatoes += 1

2 Likes

Ok, as far as I understand it: you would instantiate your potato salad with variable amounts of potatos, celery and onions. However, you always put in one pack of raisins into it, so you give it a value which is the content of the pack (40).

eg:

special_potato_salad = SpecialPotatoSalad(300, 50, 150)

print(special_potato_salad.onions)
#prints: 150
print(special_potato_salad.raisins)
#prints: 40

super_special_potato_salad = SpecialPotatoSalad(300, 50, 500)

print(super_special_potato_salad.onions)
#prints: 500
print(super_special_potato_salad.raisins)
#prints: 40

Could someone explain why this code works, even though raisins does not appear at all in the constructor?

  def __init__(self, potatoes, celery, onions):
    self.potatoes = potatoes
    self.celery = celery
    self.onions = onions
    
class SpecialPotatoSalad(PotatoSalad):
  def __init__(self, potatoes, celery, onions):
    super().__init__(potatoes, celery, onions)
    self.raisins = 40

sps = SpecialPotatoSalad(3,4,5)
print(sps.raisins)

The __init__() method is the constructor. raisins isn’t a parameter of the function because we are always going to use 40 raisins. The amounts of the other 3 ingredients varies, and those values are passed as arguments when we instantiate a SpecialPotatoSalad object. If we wanted to vary the number of raisins as well we could change the constructor:

class PotatoSalad():
  def __init__(self, potatoes, celery, onions):
    self.potatoes = potatoes
    self.celery = celery
    self.onions = onions
    
class SpecialPotatoSalad(PotatoSalad):
  def __init__(self, potatoes, celery, onions, raisins): #include raisins as a parameter
    super().__init__(potatoes, celery, onions) #do not pass raisins to the parent constructor
    self.raisins = raisins #assign the value passed in to the self.raisins property

sps = SpecialPotatoSalad(3,4,5,63)
print(sps.raisins) #prints: 63

Okay, thank you.
I must confess, object orientation makes my head hurt.

1 Like