Advertisement
GeorgiLukanov87

Python OOP Exam - 15 August 2021 - Bakery

Nov 12th, 2022 (edited)
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.01 KB | None | 0 0
  1. # Python OOP Exam - 15 August 2021 - Bakery
  2.  
  3. # https://judge.softuni.org/Contests/Practice/Index/3591#0
  4.  
  5. =============================================================================================
  6. # file name: baked_food.py
  7.  
  8. from abc import ABC, abstractmethod
  9.  
  10.  
  11. class BakedFood(ABC):
  12.     def __init__(self, name: str, portion: float, price: float):
  13.         self.name = name
  14.         self.portion = portion
  15.         self.price = price
  16.  
  17.     @property
  18.     def name(self):
  19.         return self.__name
  20.  
  21.     @name.setter
  22.     def name(self, value):
  23.         if value.strip() == '':
  24.             raise ValueError('Name cannot be empty string or white space!')
  25.         self.__name = value
  26.  
  27.     @property
  28.     def price(self):
  29.         return self.__price
  30.  
  31.     @price.setter
  32.     def price(self, value):
  33.         if value <= 0:
  34.             raise ValueError("Price cannot be less than or equal to zero!")
  35.         self.__price = value
  36.  
  37.     @abstractmethod
  38.     def __repr__(self):
  39.         ...
  40.  
  41. =============================================================================================
  42. # file name: bread.py
  43.  
  44. from project.baked_food.baked_food import BakedFood
  45.  
  46.  
  47. class Bread(BakedFood):
  48.     def __init__(self, name: str, price: float):
  49.         super().__init__(name, 200, price)
  50.  
  51.     def __repr__(self):
  52.         return f" - {self.name}: {self.portion:.2f}g - {self.price:.2f}lv"
  53.  
  54. =============================================================================================
  55. # file name: cake.py
  56.  
  57. from project.baked_food.baked_food import BakedFood
  58.  
  59.  
  60. class Cake(BakedFood):
  61.     def __init__(self, name: str, price: float):
  62.         super().__init__(name, 245, price)
  63.  
  64.     def __repr__(self):
  65.         return f" - {self.name}: {self.portion:.2f}g - {self.price:.2f}lv"
  66.  
  67.  
  68. =============================================================================================
  69. # file name: drink.py
  70.  
  71. from abc import ABC, abstractmethod
  72.  
  73.  
  74. class Drink(ABC):
  75.     def __init__(self, name: str, portion: float, price: float, brand: str):
  76.         self.name = name
  77.         self.portion = portion
  78.         self.price = price
  79.         self.brand = brand
  80.  
  81.     @property
  82.     def name(self):
  83.         return self.__name
  84.  
  85.     @name.setter
  86.     def name(self, value):
  87.         if value.strip() == '':
  88.             raise ValueError("Name cannot be empty string or white space!")
  89.         self.__name = value
  90.  
  91.     @property
  92.     def portion(self):
  93.         return self.__portion
  94.  
  95.     @portion.setter
  96.     def portion(self, value):
  97.         if value <= 0:
  98.             raise ValueError("Portion cannot be less than or equal to zero!")
  99.         self.__portion = value
  100.  
  101.     @property
  102.     def brand(self):
  103.         return self.__brand
  104.  
  105.     @brand.setter
  106.     def brand(self, value):
  107.         if value.strip() == "":
  108.             raise ValueError("Brand cannot be empty string or white space!")
  109.         self.__brand = value
  110.  
  111.     @abstractmethod
  112.     def __str__(self):
  113.         ...
  114.  
  115. =============================================================================================
  116. # file name: tea.py
  117.  
  118. from project.drink.drink import Drink
  119.  
  120.  
  121. class Tea(Drink):
  122.     def __init__(self, name: str, portion: float, brand: str):
  123.         super().__init__(name, portion, 2.50, brand)
  124.  
  125.     def __str__(self):
  126.         return f" - {self.name} {self.brand} - {self.portion:.2f}ml - {self.price:.2f}lv"
  127.  
  128. =============================================================================================
  129. # file name: water.py
  130.  
  131. from project.drink.drink import Drink
  132.  
  133.  
  134. class Water(Drink):
  135.     def __init__(self, name: str, portion: float, brand: str):
  136.         super().__init__(name, portion, 1.50, brand)
  137.  
  138.     def __str__(self):
  139.         return f" - {self.name} {self.brand} - {self.portion:.2f}ml - {self.price:.2f}lv"
  140.  
  141. =============================================================================================
  142. # file name: table.py
  143.  
  144. from abc import ABC, abstractmethod
  145.  
  146. from project.baked_food.baked_food import BakedFood
  147. from project.drink.drink import Drink
  148.  
  149.  
  150. class Table(ABC):
  151.     def __init__(self, table_number: int, capacity: int):
  152.         self.table_number = table_number
  153.         self.capacity = capacity
  154.  
  155.         self.food_orders = []
  156.         self.drink_orders = []
  157.         self.number_of_people = 0
  158.         self.is_reserved = False
  159.  
  160.     @property
  161.     def capacity(self):
  162.         return self.__capacity
  163.  
  164.     @capacity.setter
  165.     def capacity(self, value):
  166.         if value <= 0:
  167.             raise ValueError("Capacity has to be greater than 0!")
  168.         self.__capacity = value
  169.  
  170.     @abstractmethod
  171.     def reserve(self, number_of_people):
  172.         ...
  173.  
  174.     @abstractmethod
  175.     def order_food(self, baked_food: BakedFood):
  176.         ...
  177.  
  178.     @abstractmethod
  179.     def order_drink(self, drink: Drink):
  180.         ...
  181.  
  182.     @abstractmethod
  183.     def get_bill(self):
  184.         ...
  185.  
  186.     @abstractmethod
  187.     def clear(self):
  188.         pass
  189.  
  190.     @abstractmethod
  191.     def free_table_info(self):
  192.         ...
  193.  
  194. =============================================================================================
  195. # file name: inside_table.py
  196.  
  197. from project.baked_food.baked_food import BakedFood
  198. from project.drink.drink import Drink
  199. from project.table.table import Table
  200.  
  201.  
  202. class InsideTable(Table):
  203.     def __init__(self, table_number: int, capacity: int):
  204.         super().__init__(table_number, capacity)
  205.  
  206.     @property
  207.     def table_number(self):
  208.         return self.__table_number
  209.  
  210.     @table_number.setter
  211.     def table_number(self, value):
  212.         if not 1 <= value <= 50:
  213.             raise ValueError("Inside table's number must be between 1 and 50 inclusive!")
  214.         self.__table_number = value
  215.  
  216.     def reserve(self, number_of_people):
  217.         if self.capacity >= number_of_people and not self.is_reserved:
  218.             self.number_of_people += number_of_people
  219.             self.is_reserved = True
  220.             return f'Table {self.table_number} has been reserved for {number_of_people} people'
  221.         else:
  222.             return f'No available table for {number_of_people} people'
  223.  
  224.     def order_food(self, baked_food: BakedFood):
  225.         self.food_orders.append(baked_food)
  226.  
  227.     def order_drink(self, drink: Drink):
  228.         self.drink_orders.append(drink)
  229.  
  230.     def get_bill(self):
  231.         return sum([d.price for d in self.drink_orders]) + sum([f.price for f in self.food_orders])
  232.  
  233.     def clear(self):
  234.         self.drink_orders = []
  235.         self.food_orders = []
  236.         self.number_of_people = 0
  237.         self.is_reserved = False
  238.  
  239.     def free_table_info(self):
  240.         if not self.is_reserved:
  241.             return f"Table: {self.table_number}" + \
  242.                    f'\nType: {self.__class__.__name__}' \
  243.                    + f"\nCapacity: {self.capacity}"
  244.  
  245. =============================================================================================
  246. # file name: outside_table.py
  247.  
  248. from project.baked_food.baked_food import BakedFood
  249. from project.drink.drink import Drink
  250. from project.table.table import Table
  251.  
  252.  
  253. class OutsideTable(Table):
  254.     def __init__(self, table_number: int, capacity: int):
  255.         super().__init__(table_number, capacity)
  256.  
  257.     @property
  258.     def table_number(self):
  259.         return self.__table_number
  260.  
  261.     @table_number.setter
  262.     def table_number(self, value):
  263.         if not 51 <= value <= 100:
  264.             raise ValueError("Outside table's number must be between 51 and 100 inclusive!")
  265.         self.__table_number = value
  266.  
  267.     def reserve(self, number_of_people):
  268.         if self.capacity >= number_of_people:
  269.             self.number_of_people = number_of_people
  270.             self.is_reserved = True
  271.  
  272.     def order_food(self, baked_food: BakedFood):
  273.         self.food_orders.append(baked_food)
  274.  
  275.     def order_drink(self, drink: Drink):
  276.         self.drink_orders.append(drink)
  277.  
  278.     def get_bill(self):
  279.         return sum([d.price for d in self.drink_orders]) + sum([f.price for f in self.food_orders])
  280.  
  281.     def clear(self):
  282.         self.drink_orders = []
  283.         self.food_orders = []
  284.         self.number_of_people = 0
  285.         self.is_reserved = False
  286.  
  287.     def free_table_info(self):
  288.         if not self.is_reserved:
  289.             return f"Table: {self.table_number}" + \
  290.                    f'\nType: {self.__class__.__name__}' \
  291.                    + f"\nCapacity: {self.capacity}"
  292.  
  293.  
  294. =============================================================================================
  295. # file name: bakery.py
  296.  
  297. from project.baked_food.bread import Bread
  298. from project.baked_food.cake import Cake
  299. from project.drink.tea import Tea
  300. from project.drink.water import Water
  301. from project.table.inside_table import InsideTable
  302. from project.table.outside_table import OutsideTable
  303.  
  304.  
  305. class Bakery:
  306.     def __init__(self, name):
  307.         self.name = name
  308.         self.food_menu = []
  309.         self.drinks_menu = []
  310.         self.tables_repository = []
  311.         self.total_income = 0
  312.  
  313.     @property
  314.     def name(self):
  315.         return self.__name
  316.  
  317.     @name.setter
  318.     def name(self, value):
  319.         if value.strip() == "":
  320.             raise ValueError("Name cannot be empty string or white space!")
  321.         self.__name = value
  322.  
  323.     def add_food(self, food_type: str, name: str, price: float):
  324.         food_mapper = {'Bread': Bread, 'Cake': Cake}
  325.         if food_type in food_mapper.keys():
  326.             if name in [b.name for b in self.food_menu]:
  327.                 raise Exception(f"{food_type} {name} is already in the menu!")
  328.             else:
  329.                 new_food = food_mapper[food_type](name, price)
  330.                 self.food_menu.append(new_food)
  331.                 return f"Added {name} ({food_type}) to the food menu"
  332.  
  333.     def add_drink(self, drink_type: str, name: str, portion: float, brand: str):
  334.         drink_mapper = {'Water': Water, "Tea": Tea}
  335.         if drink_type in drink_mapper.keys():
  336.             if name in [d.name for d in self.drinks_menu]:
  337.                 raise Exception(f"{drink_type} {name} is already in the menu!")
  338.             else:
  339.                 new_drink = drink_mapper[drink_type](name, portion, brand)
  340.                 self.drinks_menu.append(new_drink)
  341.                 return f"Added {name} ({brand}) to the drink menu"
  342.  
  343.     def add_table(self, table_type: str, table_number: int, capacity: int):
  344.         table_mapper = {"InsideTable": InsideTable, "OutsideTable": OutsideTable}
  345.         if table_type in table_mapper.keys():
  346.             if table_number in [t.table_number for t in self.tables_repository]:
  347.                 raise Exception(f"Table {table_number} is already in the bakery!")
  348.             else:
  349.                 new_table = table_mapper[table_type](table_number, capacity)
  350.                 self.tables_repository.append(new_table)
  351.                 return f'Added table number {table_number} in the bakery'
  352.  
  353.     def reserve_table(self, number_of_people: int):
  354.         all_tables = [t for t in self.tables_repository if t.capacity >= number_of_people and not t.is_reserved]
  355.         if all_tables:
  356.             free_table = all_tables[0]
  357.             free_table.is_reserved = True
  358.             free_table.number_of_people += number_of_people
  359.             return f'Table {free_table.table_number} has been reserved for {number_of_people} people'
  360.         else:
  361.             return f'No available table for {number_of_people} people'
  362.  
  363.     def order_food(self, table_number: int, *foods_names):
  364.         searched_table = None
  365.         for table_obj in self.tables_repository:
  366.             if table_obj.table_number == table_number:
  367.                 searched_table = table_obj
  368.         if not searched_table:
  369.             return f"Could not find table {table_number}"
  370.         else:
  371.             ordered = f'Table {table_number} ordered:\n'
  372.             not_ordered = f'{self.name} does not have in the menu:\n'
  373.             for food_name in foods_names:
  374.                 if food_name in [f.name for f in self.food_menu]:
  375.                     for food_obj in self.food_menu:
  376.                         if food_obj.name == food_name:
  377.                             ordered += f'{repr(food_obj)}\n'
  378.                             searched_table.food_orders.append(food_obj)
  379.                             self.total_income += food_obj.price
  380.                 else:
  381.                     not_ordered += f"{food_name}\n"
  382.             return ordered + not_ordered.rstrip()
  383.  
  384.     def order_drink(self, table_number: int, *drinks_name):
  385.         searched_table = None
  386.         for table_obj in self.tables_repository:
  387.             if table_obj.table_number == table_number:
  388.                 searched_table = table_obj
  389.         if not searched_table:
  390.             return f"Could not find table {table_number}"
  391.         else:
  392.             ordered = f'Table {table_number} ordered:\n'
  393.             not_ordered = f'{self.name} does not have in the menu:\n'
  394.             for drink_name in drinks_name:
  395.                 if drink_name in [f.name for f in self.drinks_menu]:
  396.                     for drink_obj in self.drinks_menu:
  397.                         if drink_obj.name == drink_name:
  398.                             ordered += f'{str(drink_obj)}\n'
  399.                             searched_table.drink_orders.append(drink_obj)
  400.                             self.total_income += drink_obj.price
  401.                 else:
  402.                     not_ordered += f"{drink_name}\n"
  403.             return ordered + not_ordered.rstrip()
  404.  
  405.     def leave_table(self, table_number: int):
  406.         table = [t for t in self.tables_repository if t.table_number == table_number][0]
  407.         foods_bill = sum([f.price for f in table.food_orders])
  408.         drinks_bill = sum([f.price for f in table.drink_orders])
  409.         total_bill = foods_bill + drinks_bill
  410.         table.clear()
  411.         return f'Table: {table_number}\nBill: {total_bill:.2f}'
  412.  
  413.     def get_free_tables_info(self):
  414.         result = ""
  415.         free_tables = [t for t in self.tables_repository if not t.is_reserved]
  416.         for table_obj in free_tables:
  417.             result += f"{table_obj.free_table_info()}\n"
  418.         return result.rstrip()
  419.  
  420.     def get_total_income(self):
  421.         return f'Total income: {self.total_income:.2f}lv'
  422.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement