Загрузить файлы в «/»
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