Basta Fazoolin'!

https://www.codecademy.com/courses/learn-python-3/projects/basta-fazoolin

For this project this is my code and notes so far:

class Business:
  
  def __init__(self, name, franchises):
    self.name = name
    self.franchises = franchises
    #these classes work with each other, Franchise class has a list of menus it is storing and keeping track of, Business class has a list of franchiese it is keeping track of

class Franchise:

  def __init__(self, address, menus):
    self.address = address
    #self stands in for the object getting created
    #when we create an object, we call on init
    #when the init constructor gets called, it returns a "Franchise" object
    #self is the object getting returned from the constructor
    #we assign self."address" of the object from the constructor equal to the address that got passed into the ( )
    self.menus = menus
  
  def __repr__(self):
    return self.address
    #this will return a string of the address, no menu, if you print(flagship_store) for "flagship_store = Franchise("1232 West End Road", menus)" you will get the address only
  
  def available_menus(self, time):
    available_menu = []
    for menu in self.menus:
      if time >= menu.start_time and time <= menu.end_time: <-- QUESTION HERE
        #we defined self.menu above and we have self.start/end_time below
        available_menu.append(menu)
    return available_menu

class Menu:
  def __init__(self, name, items, start_time, end_time):
    self.name = name
    #the object that is getting created from the constructor, the object's attribute "name" is = to the "name" that got passed in
    self.items = items
    self.start_time = start_time
    self.end_time = end_time
  
  def __repr__(self):
    return self.name + ' menu available from ' + str(self.start_time) + ' to ' + str(self.end_time)
    #check print(brunch_menu) below

  def calculate_bill(self, purchased_items):
    bill = 0
    for purchased_item in purchased_items:
      if purchased_item in self.items:
        item = self.items.get(purchased_item)
        #another way is:
        #item = self.items[purchased_item]
        bill += item
    return bill
    

#Brunch Menu
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) 

print(brunch_menu.calculate_bill(['pancakes', 'home fries', 'coffee']))
#testing out calculate_bill on brunch_menu

print(brunch_menu)
#tests out __repr__ for class Menu

#Early Bird Menu
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)

print(early_bird_menu.calculate_bill(['salumeria plate', 'mushroom ravioli (vegan)']))
#testing out calculate_bill on early_bird_menu

#Dinner Menu
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 Menu
kids_items = {
  'chicken nuggets': 6.50, 'fusilli with wild mushrooms': 12.00, 'apple juice': 3.00
}

kids_menu = Menu('Kids', kids_items, 1100, 2100)

menus = [brunch_menu, early_bird_menu, dinner_menu, kids_menu]

flagship_store = Franchise("1232 West End Road", menus)

new_installment = Franchise("12 East Mulberry Street", menus)

print(flagship_store)
#checking to see if it prints out __repr__ address

print(flagship_store.available_menus(1200))
print(flagship_store.available_menus(1700))
#testing out the available_menus on flagship_store

if you look at: if time >= menu.start_time and time <= menu.end_time:

this is under def available_menus

My question is, how are we able to use menu.start_time and menu.end_time?

I’ve never defined it anywhere (I saw this from the youtube video).

For example, in the same block of code we have: for menu in self.menus:
I have defined self.menus under class Franchise.

And for self.start_time and self.end_time I have defined it under class Menu.

But nowhere have I defined menu.start_time and menu.end_time so how are we able to use menu.start_time and menu.end_time? It seems to me like somehow we combined self.start_time and self.menu to create menu.start_time

Hi @code7884045795,

Examine the __init__ method for the Menu class. Therein, we define the start_time and end_time attributes for an instance of that class.

Edited on March 27, 2020 to add the following:

Whenever we create a Menu instance, we include a start_time and end_time. Thereafter, we can access those attributes for that instance anywhere, even from within the code for another class.

Oh I see, I think I get it, thanks for the reply

1 Like

Just an aside to this, I used range to figure out what items will be available for the argument passed into the available_menus function and it seemed to work fine and looks cleaner to me.

Also, I initially misunderstood the instructions for step #16 so this is what I wrote. Not what they were looking for exactly but it gives a nice list (literally) of what items are available at that time.

  def available_menus(self, time):
    self.time = time
    print("The following items are available at "+ str(self.time) +":00: ")
    for menu in self.menus:
      if time in range(menu.start_time, menu.end_time):
        for item, price in menu.items.items():
          print(item.title() + ": $"+ "%.2f" % price)

I also did that. But, correct me if I am wrong, the upper limit of the range should be menu.end_time + 1 rather than menu.end_time.

Same here. Thanks for sharing this, I couldn’t figure this out, but now that I see your code, it makes sense.