Skip to content

Commit 8aa9658

Browse files
committed
Added Exam Preparation/Python OOP Retake Exam - 22 August 2022
1 parent c01c09f commit 8aa9658

File tree

12 files changed

+264
-0
lines changed

12 files changed

+264
-0
lines changed

OOP/C.Exam Preparation/Python OOP Retake Exam - 22 August 2022/Structure and Functionality/project/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Client:
2+
3+
def __init__(self, phone_number: str):
4+
self.phone_number = phone_number
5+
self.shopping_cart = [] # meal objects
6+
self.bill = 0.0
7+
8+
@property
9+
def phone_number(self):
10+
return self.__phone_number
11+
12+
@phone_number.setter
13+
def phone_number(self, value):
14+
if value[0] == '0' and len(value) == 10 and value.isdigit():
15+
self.__phone_number = value
16+
else:
17+
raise ValueError("Invalid phone number!")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from project.client import Client
2+
3+
4+
class FoodOrdersApp:
5+
receipt_id = 0
6+
7+
def __init__(self):
8+
self.menu = []
9+
self.clients_list = []
10+
11+
def __check_if_client_is_registered(self, phone_number):
12+
for client in self.clients_list:
13+
if client.phone_number == phone_number:
14+
return True
15+
16+
def __validate_menu(self):
17+
if len(self.menu) < 5:
18+
raise Exception("The menu is not ready!")
19+
20+
def __find_client(self, phone_number: str):
21+
for client in self.clients_list:
22+
if client.phone_number == phone_number:
23+
return client
24+
25+
def register_client(self, phone_number: str):
26+
if self.__check_if_client_is_registered(phone_number):
27+
raise Exception('The client has already been registered!')
28+
new_client = Client(phone_number)
29+
self.clients_list.append(new_client)
30+
return f'Client {phone_number} registered successfully.'
31+
32+
def add_meals_to_menu(self, *meals):
33+
for meal in meals:
34+
if type(meal).__name__ in ["Starter", "MainDish", "Dessert"]:
35+
self.menu.append(meal)
36+
37+
def show_menu(self):
38+
if len(self.menu) < 5:
39+
raise Exception("The menu is not ready!")
40+
menu_details = []
41+
for meal in self.menu:
42+
menu_details.append(meal.details())
43+
return "\n".join(menu_details)
44+
45+
def add_meals_to_shopping_cart(self, client_phone_number: str, **meal_names_and_quantity):
46+
self.__validate_menu()
47+
if not self.__check_if_client_is_registered(client_phone_number):
48+
self.register_client(client_phone_number)
49+
client = self.__find_client(client_phone_number)
50+
meals_to_order = []
51+
current_bill = 0
52+
53+
for meal_name, meal_quantity in meal_names_and_quantity.items():
54+
for meal in self.menu:
55+
if meal.name == meal_name:
56+
if meal.quantity >= meal_quantity:
57+
meals_to_order.append(meal)
58+
current_bill += meal.price * meal_quantity
59+
break
60+
else:
61+
raise Exception(f"Not enough quantity of {type(meal).__name__}: {meal_name}!")
62+
else:
63+
raise Exception(f"{meal_name} is not on the menu!")
64+
65+
client.shopping_cart.extend(meals_to_order)
66+
client.bill += current_bill
67+
68+
for meal_name, meal_quantity in meal_names_and_quantity.items():
69+
if meal_name not in client.ordered_meals:
70+
client.ordered_meals[meal_name] = 0
71+
client.ordered_meals[meal_name] += meal_quantity
72+
for meal in self.menu:
73+
if meal.name == meal_name:
74+
meal.quantity -= meal_quantity
75+
76+
return f"Client {client_phone_number} " \
77+
f"successfully ordered {', '.join(meal.name for meal in client.shopping_cart)} " \
78+
f"for {client.bill:.2f}lv."
79+
80+
def cancel_order(self, client_phone_number: str):
81+
client = self.__find_client(client_phone_number)
82+
if not client.shopping_cart:
83+
raise Exception("There are no ordered meals!")
84+
for ordered_meal, quantity in client.ordered_meals.items():
85+
for menu_meal in self.menu:
86+
if ordered_meal == menu_meal.name:
87+
menu_meal.quantity += quantity
88+
client.shopping_cart = []
89+
client.bill = 0
90+
client.ordered_meals = {}
91+
return f"Client {client_phone_number} successfully canceled his order."
92+
93+
def finish_order(self, client_phone_number):
94+
client = self.__find_client(client_phone_number)
95+
if not client.shopping_cart:
96+
raise Exception("There are no ordered meals!")
97+
98+
total_paid_money = client.bill
99+
client.shopping_cart = []
100+
client.bill = 0
101+
client.ordered_meals = {}
102+
self.receipt_id += 1
103+
return f"Receipt #{self.receipt_id} with total amount of {total_paid_money:.2f} was successfully paid for {client_phone_number}."
104+
105+
def __str__(self):
106+
return f"Food Orders App has {len(self.menu)} meals on the menu and {len(self.clients_list)} clients."

OOP/C.Exam Preparation/Python OOP Retake Exam - 22 August 2022/Structure and Functionality/project/meals/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from project.meals.meal import Meal
2+
3+
4+
class Dessert(Meal):
5+
6+
def __init__(self, name: str, price: float, quantity: int=30):
7+
super().__init__(name, price, quantity)
8+
9+
def details(self):
10+
return f"Dessert {self.name}: {self.price:.2f}lv/piece"
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from project.meals.meal import Meal
2+
3+
4+
class MainDish(Meal):
5+
6+
def __init__(self, name: str, price: float, quantity: int=50):
7+
super().__init__(name, price, quantity)
8+
9+
def details(self):
10+
return f"Main Dish {self.name}: {self.price:.2f}lv/piece"
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
class Meal(ABC):
5+
6+
def __init__(self, name: str, price: float, quantity: int):
7+
self.name = name
8+
self.price = price
9+
self.quantity = quantity
10+
11+
@property
12+
def name(self):
13+
return self.__name
14+
15+
@name.setter
16+
def name(self, value):
17+
if len(value) == 0:
18+
raise ValueError('Name cannot be an empty string!')
19+
20+
self.__name = value
21+
22+
@property
23+
def price(self):
24+
return self.__price
25+
26+
@price.setter
27+
def price(self, value):
28+
if value <= 0:
29+
raise ValueError("Invalid price!")
30+
31+
self.__price = value
32+
33+
@abstractmethod
34+
def details(self):
35+
pass
36+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from project.meals.meal import Meal
2+
3+
4+
class Starter(Meal):
5+
6+
def __init__(self, name: str, price: float, quantity: int=60):
7+
super().__init__(name, price, quantity)
8+
9+
def details(self):
10+
return f"Starter {self.name}: {self.price:.2f}lv/piece"
11+

OOP/C.Exam Preparation/Python OOP Retake Exam - 22 August 2022/Unit Testing/test/__init__.py

Whitespace-only changes.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from unittest import TestCase, main
2+
from project.shopping_cart import ShoppingCart
3+
4+
5+
class TestShoppingCart(TestCase):
6+
7+
def setUp(self) -> None:
8+
self.shopping_cart = ShoppingCart("Fantastico", 16.50)
9+
10+
def test_successful_initialization(self):
11+
self.assertEqual("Fantastico", self.shopping_cart.shop_name)
12+
self.assertEqual(16.50, self.shopping_cart.budget)
13+
self.assertEqual({}, self.shopping_cart.products)
14+
15+
def test_invalid_shop_name(self):
16+
with self.assertRaises(ValueError) as ve:
17+
test = ShoppingCart("one", 1)
18+
19+
self.assertEqual("Shop must contain only letters and must start with capital letter!", str(ve.exception))
20+
21+
with self.assertRaises(ValueError) as ve:
22+
test2 = ShoppingCart("O123", 1)
23+
24+
self.assertEqual("Shop must contain only letters and must start with capital letter!", str(ve.exception))
25+
26+
def test_add_to_cart_product_price_equal_or_more_than_100(self):
27+
with self.assertRaises(ValueError) as ve:
28+
self.shopping_cart.add_to_cart("Gold ball", 100)
29+
30+
self.assertEqual("Product Gold ball cost too much!", str(ve.exception))
31+
32+
def test_successful_add_to_cart(self):
33+
result = self.shopping_cart.add_to_cart("Carrots 2X", 4)
34+
self.assertEqual(4, self.shopping_cart.products["Carrots 2X"])
35+
self.assertEqual("Carrots 2X product was successfully added to the cart!", result)
36+
37+
def test_removing_unexisting_product_from_cart(self):
38+
with self.assertRaises(ValueError) as ve:
39+
self.shopping_cart.remove_from_cart("Potatoes")
40+
41+
self.assertEqual("No product with name Potatoes in the cart!", str(ve.exception))
42+
43+
def test_remove_product_from_cart(self):
44+
self.shopping_cart.products = {"Carrots 2X": 4}
45+
result = self.shopping_cart.remove_from_cart("Carrots 2X")
46+
self.assertEqual({}, self.shopping_cart.products)
47+
self.assertEqual("Product Carrots 2X was successfully removed from the cart!", result)
48+
49+
def test_combining_shops(self):
50+
second_shop = ShoppingCart("Factory", 18.90)
51+
fantastico_factory = self.shopping_cart + second_shop
52+
self.assertEqual("ShoppingCart", type(fantastico_factory).__name__)
53+
self.assertEqual("FantasticoFactory", fantastico_factory.shop_name)
54+
self.assertEqual(35.40, fantastico_factory.budget)
55+
self.assertEqual({}, fantastico_factory.products)
56+
57+
def test_unsuccessful_buy_products(self):
58+
self.shopping_cart.products = {"Carrot 7X": 26, "Lemonade": 3.40, "Bread": 1.50}
59+
60+
with self.assertRaises(ValueError) as ve:
61+
self.shopping_cart.buy_products()
62+
63+
self.assertEqual("Not enough money to buy the products! Over budget with 14.40lv!", str(ve.exception))
64+
65+
def test_successful_buy_products(self):
66+
self.shopping_cart.products = {"Milk": 2.45}
67+
result = self.shopping_cart.buy_products()
68+
self.assertEqual('Products were successfully bought! Total cost: 2.45lv.', result)
69+
70+
71+
if __name__ == '__main__':
72+
main()

0 commit comments

Comments
 (0)