commit ff7d6113cb361d504b7ca8582f028ff2b79b0cae Author: Роман Олюнин Date: Fri Apr 3 21:23:06 2026 +0000 Загрузить файлы в «/» diff --git a/data.txt b/data.txt new file mode 100644 index 0000000..fbfc25c --- /dev/null +++ b/data.txt @@ -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 diff --git a/report.txt b/report.txt new file mode 100644 index 0000000..3d4ecb2 --- /dev/null +++ b/report.txt @@ -0,0 +1,12 @@ +===== Отчет по кофейне ===== +Сводка по напиткам: +- Americano: 3 +- Cappuccino: 8 +- Espresso: 4 +- Latte: 7 +- Mocha: 2 +- Tea: 2 +Самый популярный напиток: Cappuccino +Топ клиентов: Maria, Olga, Petr +Общая выручка: 5430.00 руб. +============================ \ No newline at end of file diff --git a/Практика.py b/Практика.py new file mode 100644 index 0000000..d797d6a --- /dev/null +++ b/Практика.py @@ -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()