coding improvement tips - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: coding improvement tips (/thread-16689.html) |
coding improvement tips - vaisesumit29 - Mar-10-2019 Hi All, I am apologizing in advance if it wastes your time. Because it's not a question regarding any topic. It is for my improvement. Experts can suggest to me what would be the better option that could be used. I believe Feedbacks are the best way to improve oneself. So here is my project. Its a simple project of a restaurant. Flow: Code as user whether he would like to order something? If it's Yes --> The code displays the menu ---> Ask for the food items he would like to place? ---> Once the user is done with the order. A final bill is displayed. Restaurant.py """ This module is a restaurant program. Ask user input to place an order. Provide multiple options to user to choose. """ class TajRestaurant: """ Class TajRestaurant ask user input to place an order """ # class variable tables_occupied = 0 max_tables = 10 menu = {'burger': {'hamburger': 5, 'chicken': 7}, 'pizza': {'cheese': 6, 'veg': 8}} def __init__(self): if TajRestaurant.max_tables < 10: TajRestaurant.tables_occupied += 1 self.bill_amount = 0 self.print_menu() self.take_order() else: print(" Sorry we are full. Kindly wait") def get_status(self): msg = input(" Would you like to place an order anything?? \n").lower() if msg == "yes": return True elif msg == "no": return False else: print("Invalid Input. ") exit() def print_menu(self): for food, sub_food in TajRestaurant.menu.items(): for items, price in sub_food.items(): print(items + " " + food + '\n =====================', "Price: $", price) def take_order(self): status = self.get_status() total_order = [] while status: user_order = input(" What would you like to have? ").lower() food_status = self.check_item_availability(user_order) if food_status: # collect all the food items to bill total_order.append(user_order) status = self.get_status() if status == False: self.cashier(total_order) break if status == False: print("Thanks you for your visit ") def check_item_availability(self, food_item): fstatus = False for _, sub_food in TajRestaurant.menu.items(): if food_item in sub_food: fstatus = True break else: fstatus = False if fstatus: print("Item Available ") else: print("Unavailable !") return fstatus def get_price(self, ordered_food): for _, sub_food in TajRestaurant.menu.items(): for user_food in ordered_food: if user_food in sub_food: self.bill_amount += int(sub_food[user_food]) return self.bill_amount def cashier(self, user_food): bill = self.get_price(user_food) print("Your bill is: $" + str(bill)) print(" Welcome to Taj Restaurant !!!") RE: coding improvement tips - stullis - Mar-10-2019 Not a waste of time at all. This forum's here for people looking to learn and improve. The first things that jumped out at me were the class name and __init__(). They are too specific. The __init__() is meant to create an instance of a class rather than running the internal code of that class. To make it more general, I would make these changes: class Restaurant: def __init__(self, name, tables, **menu): self.name = name self.max_tables = tables self.menu = menu tables_occupied = 0 taj_menu = { 'burger': {'hamburger': 5, 'chicken': 7}, 'pizza': {'cheese': 6, 'veg': 8} } taj = Restaurant("TajRestaurant", 10, **taj_menu)Now, this could be TajRestaurant or Ricardo's Ristorante or Jim's Pizza Emporium with different numbers of tables, different menus, etc. Of course, it no longer has a means to admit a new customer to the restaurant. Let's fix that and add a means to remove a customer: def admit_new_customer(self): if self.tables_occupied < self.max_tables: self.tables_occupied += 1 else: print(" Sorry we are full. Kindly wait") def remove_customer(self): self.tables_occupied -= 1 print("Thank you! Come again!")Let's look at how our customers are ordering their food. To me, get_status() doesn't add much; if we're calling take_order(), we can suppose that the customer will answer "yes" to get_status(). Without this though, we'll need to give the customer an option to stop ordering. Then, it calls check_item_availability() which is good. The result does not need to be stored though, we can just call the method in the if statement and be done with it. def take_order(self): total_order = [] while True: self.print_menu() user_order = input("What would you like to have?").lower() if user_order in ("no", "nothing", "done", "exit", "finished", "full"): break if self.check_item_availability(user_order): # collect all the food items to bill total_order.append(user_order) else: print("Sorry, we don't sell that...") return total_orderFor check_item_availability(), we can simplify the method: def check_item_availability(self, food_item): return food_item in self.menu.keys()Of course, that supposes that we aren't allowing options on the menu items. The customer could order a burger but could not select between beef and chicken. Either the menu formatting would have to change to accommodate. Personally, I would change the menu to: taj_menu = { 'hamburger': 5, 'chicken sandwich': 7, 'cheese pizza': 6, 'veg pizza': 8 }We can simplify get_price() as well. Instead of iterating over the menu (which could be lengthy), it should iterate over the order since that should be shorter. We can get the prices with a dict.get() call. def get_price(self, ordered_food): total = 0 for item in ordered_food: total += self.menu.get(item) return totalThe cashier() method can be simplified a little: def cashier(self, user_food): print("Your bill is: $" + str(self.get_price(user_food)))Finally, we need to run the code so, let's add a run() method. My implementation is very basic, but you get the idea: def run(self): while True: self.admit_new_customer() order = self.take_order() self.cashier(order) # or self.cashier(self.take_order()) self.remove_customer()The final result of this refactoring is this: """ This module is a restaurant program. Ask user input to place an order. Provide multiple options to user to choose. """ class Restaurant: def __init__(self, name, tables, **menu): self.name = name self.max_tables = tables self.menu = menu tables_occupied = 0 def admit_new_customer(self): if self.tables_occupied < self.max_tables: self.tables_occupied += 1 else: print(" Sorry we are full. Kindly wait") def remove_customer(self): self.tables_occupied -= 1 print("Thank you! Come again!") def take_order(self): total_order = [] while True: self.print_menu() user_order = input("What would you like to have?").lower() if user_order in ("no", "nothing", "done", "exit", "finished", "full"): break if self.check_item_availability(user_order): # collect all the food items to bill total_order.append(user_order) else: print("Sorry, we don't sell that...") return total_order def print_menu(self): for food in TajRestaurant.menu: print(food, " ", '\n =====================', "Price: $" + self.menu.get(food)) def check_item_availability(self, food_item): return food_item in self.menu.keys() def get_price(self, ordered_food): total = 0 for item in ordered_food: total += self.menu.get(item) return total def cashier(self, user_food): print("Your bill is: $" + str(self.get_price(user_food))) def run(self): while True: self.admit_new_customer() order = self.take_order() self.cashier(order) # or self.cashier(self.take_order()) self.remove_customer() |