Загрузить файлы в «/»
This commit is contained in:
commit
ff7d6113cb
15
data.txt
Normal file
15
data.txt
Normal file
@ -0,0 +1,15 @@
|
||||
alice ,Latte,2,250
|
||||
IVAN,espresso,1,150
|
||||
MARIA,Cappuccino,3,220
|
||||
olga,Latte,1,250
|
||||
petr,Americano,2,180
|
||||
anna,Mocha,1,270
|
||||
maria,latte,2,250
|
||||
IVAN,Cappuccino,1,220
|
||||
sergey,Tea,2,120
|
||||
olga,Espresso,3,150
|
||||
Anna,Cappuccino,2,220
|
||||
dmitry,Americano,1,180
|
||||
petr,Latte,2,250
|
||||
maria,Mocha,1,270
|
||||
olga,cappuccino,2,220
|
||||
12
report.txt
Normal file
12
report.txt
Normal file
@ -0,0 +1,12 @@
|
||||
===== Отчет по кофейне =====
|
||||
Сводка по напиткам:
|
||||
- Americano: 3
|
||||
- Cappuccino: 8
|
||||
- Espresso: 4
|
||||
- Latte: 7
|
||||
- Mocha: 2
|
||||
- Tea: 2
|
||||
Самый популярный напиток: Cappuccino
|
||||
Топ клиентов: Maria, Olga, Petr
|
||||
Общая выручка: 5430.00 руб.
|
||||
============================
|
||||
168
Практика.py
Normal file
168
Практика.py
Normal file
@ -0,0 +1,168 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
Order = dict[str, str | int | float]
|
||||
|
||||
|
||||
def load_orders(filepath: str) -> list[Order]:
|
||||
orders: list[Order] = []
|
||||
|
||||
with open(filepath, "r", encoding="utf-8") as file:
|
||||
for line_number, raw_line in enumerate(file, start=1):
|
||||
line = raw_line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
parts = [part.strip() for part in line.split(",")]
|
||||
if len(parts) != 4:
|
||||
raise ValueError(
|
||||
f"Некорректный формат строки {line_number}: ожидалось 4 поля."
|
||||
)
|
||||
|
||||
customer, drink, quantity_text, price_text = parts
|
||||
|
||||
try:
|
||||
quantity = int(quantity_text)
|
||||
price = float(price_text)
|
||||
except ValueError as error:
|
||||
raise ValueError(
|
||||
f"Ошибка в числовых данных строки {line_number}: {line}"
|
||||
) from error
|
||||
|
||||
orders.append(
|
||||
{
|
||||
"customer": customer,
|
||||
"drink": drink.title(),
|
||||
"quantity": quantity,
|
||||
"price": price,
|
||||
}
|
||||
)
|
||||
|
||||
return orders
|
||||
|
||||
|
||||
def normalize_names(orders: list[Order]) -> list[Order]:
|
||||
normalized_orders: list[Order] = []
|
||||
|
||||
for order in orders:
|
||||
normalized_order = order.copy()
|
||||
customer = str(normalized_order["customer"]).strip()
|
||||
normalized_order["customer"] = customer.capitalize()
|
||||
normalized_orders.append(normalized_order)
|
||||
|
||||
return normalized_orders
|
||||
|
||||
|
||||
def filter_by_drink(orders: list[Order], drink: str) -> list[Order]:
|
||||
target = drink.strip().lower()
|
||||
return [
|
||||
order
|
||||
for order in orders
|
||||
if str(order["drink"]).strip().lower() == target
|
||||
]
|
||||
|
||||
|
||||
def calculate_total(orders: list[Order]) -> float:
|
||||
return sum(float(order["quantity"]) * float(order["price"]) for order in orders)
|
||||
|
||||
|
||||
def top_clients(orders: list[Order], n: int) -> list[str]:
|
||||
spent_by_client: defaultdict[str, float] = defaultdict(float)
|
||||
|
||||
for order in orders:
|
||||
customer = str(order["customer"])
|
||||
spent_by_client[customer] += float(order["quantity"]) * float(order["price"])
|
||||
|
||||
sorted_clients = sorted(
|
||||
spent_by_client.items(),
|
||||
key=lambda item: (-item[1], item[0]),
|
||||
)
|
||||
return [client for client, _ in sorted_clients[:n]]
|
||||
|
||||
|
||||
def drinks_summary(orders: list[Order]) -> dict[str, int]:
|
||||
summary: defaultdict[str, int] = defaultdict(int)
|
||||
|
||||
for order in orders:
|
||||
drink = str(order["drink"]).strip().title()
|
||||
summary[drink] += int(order["quantity"])
|
||||
|
||||
return dict(summary)
|
||||
|
||||
|
||||
def most_popular_drink(summary: dict[str, int]) -> str:
|
||||
if not summary:
|
||||
return ""
|
||||
return max(summary, key=summary.get)
|
||||
|
||||
|
||||
def average_order_value(orders: list[Order]) -> float:
|
||||
if not orders:
|
||||
return 0.0
|
||||
return round(calculate_total(orders) / len(orders), 2)
|
||||
|
||||
|
||||
def format_report(
|
||||
summary: dict[str, int], top: list[str], popular: str, total: float
|
||||
) -> str:
|
||||
drinks_lines = "\n".join(
|
||||
f"- {drink}: {quantity}" for drink, quantity in sorted(summary.items())
|
||||
)
|
||||
top_clients_line = ", ".join(top) if top else "Нет данных"
|
||||
|
||||
return (
|
||||
"===== Отчет по кофейне =====\n"
|
||||
"Сводка по напиткам:\n"
|
||||
f"{drinks_lines}\n"
|
||||
f"Самый популярный напиток: {popular}\n"
|
||||
f"Топ клиентов: {top_clients_line}\n"
|
||||
f"Общая выручка: {total:.2f} руб.\n"
|
||||
"============================"
|
||||
)
|
||||
|
||||
|
||||
def save_report(report: str, filepath: str) -> None:
|
||||
path = Path(filepath)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(report, encoding="utf-8-sig")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
base_dir = Path(__file__).resolve().parent
|
||||
data_path = base_dir / "data" / "data.txt"
|
||||
report_path = base_dir / "data" / "report.txt"
|
||||
|
||||
orders = load_orders(str(data_path))
|
||||
orders = normalize_names(orders)
|
||||
|
||||
summary = drinks_summary(orders)
|
||||
popular_drink = most_popular_drink(summary)
|
||||
|
||||
popular_orders = filter_by_drink(orders, popular_drink)
|
||||
print(f"Заказы по напитку '{popular_drink}':")
|
||||
for order in popular_orders:
|
||||
print(
|
||||
f"{order['customer']} - {order['drink']} - "
|
||||
f"{order['quantity']} шт. по {order['price']:.2f} руб."
|
||||
)
|
||||
|
||||
total = calculate_total(orders)
|
||||
top = top_clients(orders, 3)
|
||||
|
||||
average = average_order_value(orders)
|
||||
print(f"\nСредняя стоимость заказа: {average:.2f} руб.")
|
||||
|
||||
report = format_report(summary, top, popular_drink, total)
|
||||
save_report(report, str(report_path))
|
||||
|
||||
print("\nОтчет сформирован:")
|
||||
print(report)
|
||||
print(f"\nОтчет сохранен в файл: {report_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in New Issue
Block a user