Basta Fazoolin' - Issue with step #16

Hey folks,

Worked my way up to the last project of the Classes section, OOP is exciting to say the least :slight_smile:

However, during the final project called ‘Basta Fazoolin’ I’ve found myself in a situation I can’t debug, although I did try. I’ve also been following my attempts at a solution by watching the video walk through, still, there’s something off.

Here’s the code so far:

class Franchise:
    pass
    def __init__(self, address, menus):
        self.address = address
        self.menus = menus
        
    def __repr__(self):
        return self.address
        
    def available_menus(self, time):
        available_menus = []
        for menu in self.menus:
            if time >= menu.start_time and time <= menu.end_time:
                available_menus.append(menu)
        return available_menus

class Menu:
    pass
    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 f'{self.name} is available from {self.start_time} to {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]
            else:
                print('At least one item is not available on the menu.')
                return None
        return bill

# Brunch Menu
brunch_menu = {
    '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('Brunch', brunch_menu, 1100, 1600)

# Early Bird Menu
early_bird_menu = {
    '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('Early Bird', early_bird_menu, 1500, 1800)

# Dinner Menu
dinner_menu = {
    '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('Dinner', dinner_menu, 1700, 2300)

# Kids Menu
kids_menu = {
    'chicken nuggets': 6.50, 'fusilli with wild mushrooms': 12.00,
    'apple juice': 3.00
    }
kids = Menu('Kids', kids_menu, 1100, 2100)

# All Menu OBJECTS
menus = [brunch_menu, early_bird_menu, dinner_menu, kids_menu]

# 12
flagship_store = Franchise('1232 West End Road', menus)
new_installment = Franchise('12 East Mulberry Street', menus)


print(flagship_store.available_menus(1200))

The issue I have is related to .available_menus (3rd method of Franchise class), upon calling: print(flagship_store.available_menus(1200)) (example used in walkthrough video).

I get the error:

AttributeError: 'dict' object has no attribute 'start_time' 

As far as I’m concerned, the .available_menus doesn’t inherit the attributes of the Menus class, a sentiment not shared by the video narrator who says that it does (though I’m not sure why or how).

When I call: print(flagship_store.menus) for example, I do indeed get a list of dictionaries, so the error, as far I’m concerned, makes sense.

Instead of looping through some the menu OBJECTS, I would rather first loop through the Menus themselves – but I can’t figure out.

How it works in the walkthrough video however is beyond me.

Would really appreciate any insight on the matter. Apologies if this post is messy, I tried to keep it in order. I’m quite excited about OOP but this is very new to me.

Thanks in advance.

Hello, @vaylx.

I’d start here. When you instantiated Franchise what values did you use for arguments? Are you sure menus points to the values you intended?

Took a while but I found the mistake. Had the variable names mixed up :slight_smile:
Ahh… appreciate the tip!

1 Like

One more thing if you don’t mind, could you explain how, still in the .available_menus method, how does menu inherit all the attributes of the class Menu? I can’t make the connection.

I assume you changed:

to:

menus = [brunch, early_bird, dinner, kids]

The elements of the list menus are now instances of the Menu class. When you instantiate a new Franchise with a list of Menu objects, that list of Menu objects is assigned to self.menus:

Every instance of Menu has all of the attributes of the Menu class.

2 Likes

worth noting that this iteration pattern is filter

Returning either None or meaningful value is ehhh not so great. This should probably be:

raise ValueError('At least .... ')

If it’s going to fail, fail hard. Don’t make it possible to accidentally treat failure as success (that’s the problem with None/null/nil/undefined and whatever other horrible similar things)

and it is something that can be checked before doing anything else, making the loop simpler, in fact, without that, this loop is map, because you applying a transformation (dict lookup) to each thing in an iterable:

return list(map(self.items.get, purchased_items))

(get is a dictionary method, it behaves similarly to the [] operator)

should probably remove do-nothing statements

This topic was automatically closed 18 hours after the last reply. New replies are no longer allowed.