Basta Fazoolin'

Hello!

I’m getting an attribute error in the Basta Fazoolin’ exercise, Here’s my code:

class Menu:
  def __init__(self, name, items, start_time, end_time):
    self.name = name
    self.items = items
    self.start_time = start_time
    self.end_time = end_time
  def __repr__(self):
    return self.name + " menu is available from " + str(self.start_time) + " to " + str(self.end_time)
    
brunch_items = {
  'pancakes': 7.50, 'waffles': 9.00, 'burger': 11.00, 'home fries': 4.50, 'coffee': 1.50, 'espresso': 3.00, 'tea': 1.00, 'mimosa': 10.50, 'orange juice': 3.50
}
brunch_menu = Menu("Brunch", brunch_items, 1100, 1600)
  
early_bird_items = {
  'salumeria plate': 8.00, 'salad and breadsticks (serves 2, no refills)': 14.00, 'pizza with quattro formaggi': 9.00, 'duck ragu': 17.50, 'mushroom ravioli (vegan)': 13.50, 'coffee': 1.50, 'espresso': 3.00,
}
early_bird_menu = Menu("Early Bird", early_bird_items, 1500, 1800)
dinner_items = {
  'crostini with eggplant caponata': 13.00, 'ceaser salad': 16.00, 'pizza with quattro formaggi': 11.00, 'duck ragu': 19.50, 'mushroom ravioli (vegan)': 13.50, 'coffee': 2.00, 'espresso': 3.00,
}
dinner_menu = Menu("DInner", dinner_items, 1700, 2300)
kids_items = {
  'chicken nuggets': 6.50, 'fusilli with wild mushrooms': 12.00, 'apple juice': 3.00
}
kids_menu = Menu("Kids", kids_items, 1100, 2100)

def calculate_bill(self, purchased_items):
  bill = 0
  for purchased_item in purchased_items:
    if purchsed_item in self.items:
      bill += self.items[purchased_item]
  return bill
print(brunch_items.calculate_bill('pancakes', 'home fries', 'coffee'))

And the error is as follows:

Traceback (most recent call last):
File “script.py”, line 34, in
print(brunch_items.calculate_bill(‘pancakes’, ‘home fries’, ‘coffee’))
AttributeError: ‘dict’ object has no attribute ‘calculate_bill’

I don’t know where I’m going wrong! I would really appreciate some help!

There’s several issues at play here.
First:

def calculate_bill(self, purchased_items):
  bill = 0
  for purchased_item in purchased_items:
    if purchsed_item in self.items:
      bill += self.items[purchased_item]
  return bill

Spelling error in the IF loop. Fix this.

Second:

def calculate_bill(self, purchased_items):
  bill = 0
  for purchased_item in purchased_items:
    if purchsed_item in self.items:
      bill += self.items[purchased_item]
  return bill

You need to put this method inside your class, otherwise you can’t assign an attribute from it.

Finally:

print(brunch_items.calculate_bill('pancakes', 'home fries', 'coffee'))

You are trying to assign an attribute from a class you didn’t call, that also doesn’t exist (previous step fixes the latter). If you look at your code again you already have done this, you just need to use the proper object. If you look at this line of code:

brunch_menu = Menu("Brunch", brunch_items, 1100, 1600)

You can see its calling the class AND brunch_items
Therefore:

print(brunch_menu.calculate_bill(['pancakes', 'home fries', 'coffee']))

is the correct code. Remember, your calculate_bill() method only takes 2 positional arguments, so you need to make the input a SINGLE list of strings, as self counts towards those 2 args.

EDIT Spelling, grammar.

1 Like

Thanks so much for your detailed reply. I’ve fixed most of the problems that you pointed out. However, I’m not sure how to put the method inside of the class. If I put it near the top of the code it says that the variables aren’t defined. When I put it at the bottom it now says there’s an indentation error.

class Menu:
    def __init__(self, name, items, start_time, end_time):
        self.name = name
        self.items = items
        self.start_time = start_time
        self.end_time = end_time

    def __repr__(self):
        return self.name + " menu is available from " + str(self.start_time) + " to " + str(self.end_time)

    def calculate_bill(self, purchased_items):
      bill = 0
      for purchased_item in purchased_items:
        if purchased_item in self.items:
          bill += self.items[purchased_item]
      return bill

Provided CA doesn’t bork my code, the above is what it should look like.

1 Like

I’ve done as you did and it says:

Traceback (most recent call last):
File “script.py”, line 15, in
print(brunch_menu.calculate_bill([‘pancakes’, ‘home fries’, ‘coffee’]))
NameError: name ‘brunch_menu’ is not defined

I’m assuming that this is because the variable brunch_menu is defined after the method.

I’m assuming you moved the print statement inside the class; don’t. Put it outside the scope of your class, you’re calling it before you define it.

class Menu:
    def __init__(self, name, items, start_time, end_time):
        self.name = name
        self.items = items
        self.start_time = start_time
        self.end_time = end_time

    def __repr__(self):
        return self.name + " menu is available from " + str(self.start_time) + " to " + str(self.end_time)

    def calculate_bill(self, purchased_items):
      bill = 0
      for purchased_item in purchased_items:
        if purchased_item in self.items:
          bill += self.items[purchased_item]
      return bill
#your defined variables
#your defined variables
#your defined variables
#your defined variables

print(your_code_here)

EDIT Fixed the code block

I see! It’s still resulting in an error:

Traceback (most recent call last):
File “script.py”, line 34, in
print(brunch_menu.calculate_bill([‘pancakes’, ‘home fries’, ‘coffee’]))
AttributeError: ‘Menu’ object has no attribute ‘calculate_bill’

Here’s the code again:

  def __init__(self, name, items, start_time, end_time):
    self.name = name
    self.items = items
    self.start_time = start_time
    self.end_time = end_time
  def __repr__(self):
    return self.name + " menu is available from " + str(self.start_time) + " to " + str(self.end_time)
    def calculate_bill(self, purchased_items):
     bill = 0
     for purchased_item in purchased_items:
      if purchased_item in self.items:
        bill += self.items[purchased_item]
    return bill

brunch_items = {
  'pancakes': 7.50, 'waffles': 9.00, 'burger': 11.00, 'home fries': 4.50, 'coffee': 1.50, 'espresso': 3.00, 'tea': 1.00, 'mimosa': 10.50, 'orange juice': 3.50
}
brunch_menu = Menu("Brunch", brunch_items, 1100, 1600)

early_bird_items = {
  'salumeria plate': 8.00, 'salad and breadsticks (serves 2, no refills)': 14.00, 'pizza with quattro formaggi': 9.00, 'duck ragu': 17.50, 'mushroom ravioli (vegan)': 13.50, 'coffee': 1.50, 'espresso': 3.00,
}
early_bird_menu = Menu("Early Bird", early_bird_items, 1500, 1800)
dinner_items = {
  'crostini with eggplant caponata': 13.00, 'ceaser salad': 16.00, 'pizza with quattro formaggi': 11.00, 'duck ragu': 19.50, 'mushroom ravioli (vegan)': 13.50, 'coffee': 2.00, 'espresso': 3.00,
}
dinner_menu = Menu("Dinner", dinner_items, 1700, 2300)
kids_items = {
  'chicken nuggets': 6.50, 'fusilli with wild mushrooms': 12.00, 'apple juice': 3.00
}
kids_menu = Menu("Kids", kids_items, 1100, 2100)

print(brunch_menu.calculate_bill(['pancakes', 'home fries', 'coffee']))

  















Ah easy fix, indentation error. You have your calculate bill method INSIDE your repr method.

It’s only adding the pancakes and then stopping… !! :sweat_smile:

What does the output say, 7.50?

Yes, 7.5. It should be 13.5.

Is the code with the indentation error the same as you’re using now…? Because when I fix your indentation error I get 13.5.

This is how it looks now:

def __repr__(self):
    return self.name + " menu is available from " + str(self.start_time) + " to " + str(self.end_time)
  
  def calculate_bill(self, purchased_items):
     bill = 0
     for purchased_item in purchased_items:
      if purchased_item in self.items:
        bill += self.items[purchased_item]
        return bill

It’s strange because on the CA portal the indentation is fine but when I copy and paste it here it’s off.

Haha… another indentation error put return 1 indent farther than the method its in.

def calculate_bill(self, purchased_items):
  bill = 0
  for purchased_item in purchased_items:
    if purchased_item in self.items:
      bill += self.items[purchased_item]
  return bill

See my previous comment, at the level of indentation your return call is at, you only get 7.5…

I"m using my IDE so that probably why mine doesn’t get borked by the formating.

It’s fixed! The lines of code starting bill and for were indented incorrectly throwing off the whole thing. Thank you so much!

All good, the tab key and I are arch-enemies >:)

1 Like