diff --git a/app/car.py b/app/car.py new file mode 100644 index 00000000..a7becd0b --- /dev/null +++ b/app/car.py @@ -0,0 +1,7 @@ +from dataclasses import dataclass + + +@dataclass +class Car: + brand: str + fuel_consumption: float diff --git a/app/customer.py b/app/customer.py new file mode 100644 index 00000000..c72804aa --- /dev/null +++ b/app/customer.py @@ -0,0 +1,52 @@ +import math +from decimal import Decimal + +from app.car import Car +from app.shop import Shop + + +class Customer: + group_customers: list["Customer"] = [] + + def __init__( + self, **data + ) -> None: + self.name = data.get("name") + self.product_cart = data.get("product_cart") + self.location = data.get("location") + self.money = Decimal(data.get("money")) + self.car = Car( + data.get("car").get("brand"), + data.get("car").get("fuel_consumption")) + + def calculate_cost(self, shop: Shop, data: dict) -> Decimal: + x_coordinate, y_coordinate = self.location + x1_coordinate, y1_coordinate = shop.location + distance = Decimal(math.sqrt( + ((x1_coordinate - x_coordinate) ** 2) + + ((y1_coordinate - y_coordinate) ** 2) + )) + + car_cost_there_and_back = ( + ( + (Decimal(self.car.fuel_consumption) * distance) / Decimal(100) + ) + * Decimal(data["FUEL_PRICE"]) * 2 + ) + products_sum_price = Decimal(0) + for product, count in self.product_cart.items(): + products_sum_price += Decimal( + shop.products.get(product, 0) + ) * count + + return round((car_cost_there_and_back + products_sum_price), 2) + + @classmethod + def generate_unit(cls, data: dict) -> None: + for unit in data["customers"]: + customer = Customer(**unit) + cls.group_customers.append(customer) + + +class NotEnoughMoneyException(Exception): + """Custom exception for cases when customer doesn't have enough money""" diff --git a/app/main.py b/app/main.py index 558d7d94..d7bed54d 100644 --- a/app/main.py +++ b/app/main.py @@ -1,3 +1,44 @@ -def shop_trip(): - # write your code here - pass +import json + +from app.customer import Customer +from app.shop import Shop + + +def shop_trip() -> None: + with open("app/config.json", "r") as file: + data = json.load(file) + + Customer.generate_unit(data) + Shop.generate_shop(data) + + for customer in Customer.group_customers: + print(f"{customer.name} has {customer.money} dollars") + + best_shop, trip_cost = None, float("inf") + + for shop in Shop.shop_list: + trip_calculate = customer.calculate_cost(shop, data) + if trip_calculate < trip_cost: + trip_cost = trip_calculate + best_shop = shop + + print(f"{customer.name}'s trip to the {shop.name} " + f"costs {trip_calculate}") + + money_change = customer.money - trip_cost + if money_change < 0: + print(f"{customer.name} doesn't have enough money " + f"to make a purchase in any shop" + ) + return + + print(f"{customer.name} rides to {best_shop.name}") + + best_shop.get_service(customer) + + print(f"{customer.name} rides home") + print(f"{customer.name} now has {round(money_change, 2)} dollars\n") + + +if __name__ == "__main__": + shop_trip() diff --git a/app/shop.py b/app/shop.py new file mode 100644 index 00000000..a69fda0a --- /dev/null +++ b/app/shop.py @@ -0,0 +1,45 @@ +import datetime + + +class Shop: + shop_list: list["Shop"] = [] + + def __init__(self, **data) -> None: + self.name = data.get("name") + self.location = data.get("location") + self.products = data.get("products") + + @classmethod + def generate_shop(cls, data: dict) -> None: + for shop in data["shops"]: + store = Shop(**shop) + cls.shop_list.append(store) + + def get_service(self, customer: any) -> float: + now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S") + + products_sum_price = 0 + sales_details = [] + for product, count in customer.product_cart.items(): + price = self.products.get(product) + total_product_cost = price * count + products_sum_price += total_product_cost + + sales_details.append( + f"{count} {product}s " + f"for {self.format_amount(total_product_cost)} dollars") + + print(f"\nDate: {now}") + print(f"Thanks, {customer.name}, for your purchase!") + print("You have bought:") + for detail in sales_details: + print(f"{detail}") + print(f"Total cost is {round(products_sum_price, 2)} dollars") + print("See you again!\n") + return products_sum_price + + @staticmethod + def format_amount(amount: float) -> str: + amount_str = "{:.2f}".format(amount).rstrip("0").rstrip(".") + + return amount_str