-
Notifications
You must be signed in to change notification settings - Fork 697
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Solution? #553
base: master
Are you sure you want to change the base?
Solution? #553
Changes from all commits
e09abc2
73237b5
a1d8e81
63a57ec
d9af3b5
1f0c89f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from dataclasses import dataclass | ||
|
||
|
||
@dataclass | ||
class Car: | ||
brand: str = None | ||
fuel_consumption: float = None |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import datetime | ||
from math import sqrt | ||
|
||
from app.car import Car | ||
from app.shop import Shop | ||
|
||
|
||
class Customer: | ||
def __init__(self, | ||
name: str, | ||
product_cart: dict, | ||
location: list, | ||
money: float, | ||
car: dict) -> None: | ||
self.name = name | ||
self.product_cart = product_cart | ||
self.location = location | ||
self.money = money | ||
self.car = Car(**car) | ||
|
||
def choose_the_cheapest_shop_visit( | ||
self, | ||
shops: list[Shop], | ||
fuel_price: float | ||
) -> tuple: | ||
|
||
print(f"{self.name} has {self.money} dollars") | ||
best_price = best_shop = None | ||
|
||
for shop in shops: | ||
total_trip_price_shop = self.money_spent_on_products(shop) | ||
total_trip_price_shop += self.money_spent_on_fuel(shop, fuel_price) | ||
|
||
print(f"{self.name}'s trip to the {shop.name} " | ||
f"costs {total_trip_price_shop}") | ||
|
||
if ( | ||
not best_price | ||
or total_trip_price_shop | ||
< best_price | ||
): | ||
best_price = total_trip_price_shop | ||
best_shop = shop | ||
return best_price, best_shop | ||
|
||
def ride_home(self, best_shop_visit_price: float) -> None: | ||
print(f"{self.name} rides home\n{self.name} now has " | ||
f"{self.money - best_shop_visit_price} dollars\n") | ||
|
||
def money_spent_on_products(self, shop: Shop) -> float: | ||
total_products_price = 0 | ||
for money_customer_need, shop_item_price in ( | ||
zip(self.product_cart.values(), shop.products.values()) | ||
): | ||
total_products_price += money_customer_need * shop_item_price | ||
return total_products_price | ||
|
||
def money_spent_on_fuel(self, shop: Shop, fuel_price: float) -> float: | ||
one_way_distance = sqrt( | ||
(self.location[0] - shop.location[0]) ** 2 | ||
+ (self.location[1] - shop.location[1]) ** 2 | ||
) | ||
money_fuel_spent = round(self.car.fuel_consumption | ||
* fuel_price / 100 * one_way_distance * 2, 2) | ||
return money_fuel_spent | ||
|
||
def calculate_if_enough_money( | ||
self, | ||
best_shop_visit_price: float, | ||
best_shop_instance: Shop | ||
) -> bool: | ||
if self.money >= best_shop_visit_price: | ||
print(f"{self.name} rides to {best_shop_instance.name}\n") | ||
return True | ||
|
||
print(f"{self.name} doesn't have enough " | ||
f"money to make a purchase in any shop") | ||
return False | ||
|
||
def interaction_with_cashier(self, best_shop_instance: Shop) -> None: | ||
str_date = datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S") | ||
print(f"Date: {str_date}\n" | ||
f"Thanks, {self.name}, for your purchase!\n" | ||
"You have bought:") | ||
|
||
paper_check, cart_price = self._checkout_for_products( | ||
shop=best_shop_instance | ||
) | ||
|
||
for products_amount_and_price in paper_check: | ||
print(products_amount_and_price) | ||
|
||
print(f"Total cost is {cart_price} dollars\nSee you again!\n") | ||
|
||
def _checkout_for_products(self, shop: Shop) -> tuple[list[str], float]: | ||
total_cart_price = 0 | ||
full_paper_check = [] | ||
|
||
for products_amount_customer_need, (product_name, product_price) in ( | ||
zip(self.product_cart.values(), shop.products.items()) | ||
): | ||
full_product_price = products_amount_customer_need * product_price | ||
# tests fail without it, they want rounded if it can be rounded | ||
if full_product_price == int(full_product_price): | ||
full_product_price = int(full_product_price) | ||
total_cart_price += full_product_price | ||
|
||
paper_check = (f"{products_amount_customer_need} {product_name}s " | ||
f"for {full_product_price} dollars") | ||
full_paper_check.append(paper_check) | ||
|
||
return full_paper_check, total_cart_price |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import json | ||
|
||
|
||
def load_complete_json(filepath: str) -> dict: | ||
with open(filepath, "r") as file: | ||
data = json.load(file) | ||
return data |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,23 @@ | ||
def shop_trip(): | ||
# write your code here | ||
pass | ||
from app.customer import Customer | ||
from app.load_jsons import load_complete_json | ||
from app.shop import Shop | ||
|
||
|
||
def shop_trip() -> None: | ||
data = load_complete_json("app/config.json") | ||
shops = [Shop(**shop) for shop in data.get("shops")] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have general questions about the structure of your code:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the hardest part is to refactor the code after you already wrote it and it's all over the modules, so you need to tear it appart again :D |
||
fuel_price = data.get("FUEL_PRICE") | ||
|
||
for customer_data in data.get("customers"): | ||
customer = Customer(**customer_data) | ||
best_price, best_shop = customer.choose_the_cheapest_shop_visit( | ||
shops=shops, fuel_price=fuel_price | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here you could move all those methods calls on customer to a separate method (e.g. complete_shop_trip ) and call these methods in a chain inside of the class. Here you would just call complete_shop_trip on Customer and thats it. |
||
) | ||
is_enough_money = customer.calculate_if_enough_money( | ||
best_shop_visit_price=best_price, best_shop_instance=best_shop | ||
) | ||
if not is_enough_money: | ||
continue | ||
|
||
customer.interaction_with_cashier(best_shop_instance=best_shop) | ||
customer.ride_home(best_shop_visit_price=best_price) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from dataclasses import dataclass | ||
|
||
|
||
@dataclass | ||
class Shop: | ||
name: str = None | ||
location: list[int] = None | ||
products: dict[str:float] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your Customer class has a lot of methods some of which could be moved to a different class. Not a mistake it's just a not so good practice to have one class that does it all and the others do nothing. Her for example you could move interaction with cashier to the shop because it doesn't really have to do anything with the customer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was figthing with circular imports, so decided to do it all in customer :(