import os # 1. Загрузка заказов из файла def load_orders(filepath: str) -> list[dict]: orders = [] try: with open(filepath, 'r', encoding='utf-8') as file: for line in file: line = line.strip() if not line: continue parts = line.split(',') if len(parts) != 4: continue try: user_id = int(parts[0].strip()) item_name = parts[1].strip() quantity = int(parts[2].strip()) price = float(parts[3].strip()) except ValueError: continue total = quantity * price orders.append({ 'user_id': user_id, 'item_name': item_name, 'quantity': quantity, 'price': price, 'total': total }) except FileNotFoundError: print(f"Ошибка: файл {filepath} не найден.") except Exception as e: print(f"Ошибка при чтении файла: {e}") return orders # 2. Валидация заказов (удаление некорректных) def validate_orders(orders: list[dict]) -> list[dict]: """ Отбрасывает заказы с quantity <= 0, price <= 0 или пустым item_name. """ valid_orders = [] for order in orders: if (order['quantity'] > 0 and order['price'] > 0 and order['item_name'].strip() != ''): valid_orders.append(order) return valid_orders # 3. Группировка заказов по пользователям def group_by_user(orders: list[dict]) -> dict[int, list[dict]]: """ Группирует заказы по user_id. """ grouped = {} for order in orders: uid = order['user_id'] if uid not in grouped: grouped[uid] = [] grouped[uid].append(order) return grouped # 4. Расчет общей суммы трат пользователя def calculate_user_total(user_orders: list[dict]) -> float: """ Суммирует все значения 'total' для одного пользователя. """ return sum(order['total'] for order in user_orders) # 5. Поиск самого дорогого товара (по цене за единицу) def find_most_expensive_item(orders: list[dict]) -> tuple[str, float]: """ Возвращает (название, цена) товара с максимальной price. """ if not orders: return ('', 0.0) most_expensive = max(orders, key=lambda x: x['price']) return (most_expensive['item_name'], most_expensive['price']) # 6. Применение скидки ко всем заказам (возвращает новый список) def apply_discount(orders: list[dict], discount_percent: float) -> list[dict]: """ Уменьшает поле 'total' на discount_percent. Возвращает новый список заказов, не изменяя исходный. """ discounted_orders = [] for order in orders: new_order = order.copy() new_order['total'] = order['total'] * (1 - discount_percent / 100.0) discounted_orders.append(new_order) return discounted_orders # 7. Фильтрация товаров по минимальной цене за единицу def filter_by_price_threshold(orders: list[dict], min_price: float) -> list[dict]: """ Возвращает заказы, у которых price >= min_price. """ return [order for order in orders if order['price'] >= min_price] # 8. Получение уникальных названий товаров def get_unique_items(orders: list[dict]) -> set[str]: """ Возвращает множество уникальных item_name. """ return {order['item_name'] for order in orders} # 9. Генерация текстового отчета def generate_report(stats: dict) -> str: """ stats ожидается с ключами: - unique_users (int) - total_revenue (float) - most_expensive_item (tuple (name, price)) - unique_items (set или list) """ report_lines = [] report_lines.append("=" * 50) report_lines.append("ОТЧЕТ ПО ЗАКАЗАМ ИНТЕРНЕТ-МАГАЗИНА") report_lines.append("=" * 50) report_lines.append(f"Всего уникальных пользователей: {stats['unique_users']}") report_lines.append(f"Общая выручка (без скидок): {stats['total_revenue']:.2f} руб.") item_name, item_price = stats['most_expensive_item'] report_lines.append(f"Самый дорогой товар: {item_name} (цена за ед.: {item_price:.2f} руб.)") report_lines.append(f"Уникальных товаров в ассортименте: {len(stats['unique_items'])}") report_lines.append("Список товаров:") for item in sorted(stats['unique_items']): report_lines.append(f" - {item}") report_lines.append("=" * 50) return "\n".join(report_lines) # 10. Сохранение отчета в файл def save_report(filepath: str, report_text: str) -> bool: """ Сохраняет отчет в файл. Возвращает True при успехе. """ try: os.makedirs(os.path.dirname(filepath), exist_ok=True) with open(filepath, 'w', encoding='utf-8') as file: file.write(report_text) return True except Exception as e: print(f"Ошибка при сохранении отчета: {e}") return False # ГЛАВНАЯ ФУНКЦИЯ (демонстрация работы всех 10 функций) def main(): print("=== Система анализа заказов интернет-магазина ===\n") data_dir = "data" # Создаем папку, если её нет os.makedirs(data_dir, exist_ok=True) # Путь к файлу с данными test_file = os.path.join(data_dir, "orders_data.txt") # Создаем тестовый файл с данными, если его нет if not os.path.exists(test_file): print("Создаю тестовый файл с данными...") sample_data = [ "101, Laptop, 1, 1200.00\n", "102, Mouse, -2, 25.50\n", # некорректный "101, Mouse, 1, 25.50\n", "103, Monitor, 0, 300.00\n", # некорректный "101, Keyboard, 1, 80.00\n", "102, Laptop, 1, 1200.00\n", "104, USB-C Cable, 3, 15.00\n", "105, , 1, 10.00\n" # пустое имя товара ] with open(test_file, 'w', encoding='utf-8') as f: f.writelines(sample_data) print(f"Файл создан: {test_file}\n") # Шаг 1: Загрузка заказов print("1. Загружаю заказы из файла...") raw_orders = load_orders(test_file) print(f" Загружено записей: {len(raw_orders)}") # Шаг 2: Валидация print("2. Валидация заказов...") valid_orders = validate_orders(raw_orders) invalid_count = len(raw_orders) - len(valid_orders) print(f" Отброшено некорректных записей: {invalid_count}") print(f" Осталось корректных заказов: {len(valid_orders)}") if not valid_orders: print("Нет корректных заказов для обработки. Завершение.") return # Шаг 3: Группировка по пользователям и расчет трат print("\n3. Аналитика по пользователям:") grouped = group_by_user(valid_orders) print(f" Уникальных пользователей: {len(grouped)}") for uid, orders_list in grouped.items(): total_spent = calculate_user_total(orders_list) print(f" Пользователь {uid}: потратил {total_spent:.2f} руб., заказов: {len(orders_list)}") # Шаг 4: Самый дорогой товар most_expensive = find_most_expensive_item(valid_orders) print(f"\n4. Самый дорогой товар (по цене за ед.): {most_expensive[0]} — {most_expensive[1]:.2f} руб.") # Шаг 5: Уникальные товары unique_items = get_unique_items(valid_orders) print(f"\n5. Уникальных товаров в ассортименте: {len(unique_items)}") print(f" {sorted(unique_items)}") # Шаг 6: Применение скидки print("\n6. Применение скидки 10% ко всем заказам...") original_total = sum(order['total'] for order in valid_orders) discounted_orders = apply_discount(valid_orders, 10.0) discounted_total = sum(order['total'] for order in discounted_orders) print(f" Общая сумма до скидки: {original_total:.2f} руб.") print(f" Общая сумма после скидки: {discounted_total:.2f} руб.") # Шаг 7: Фильтрация дорогих товаров (цена >= 100) expensive_orders = filter_by_price_threshold(valid_orders, 100.0) print(f"\n7. Товаров дороже 100 руб. (за ед.): {len(expensive_orders)}") for order in expensive_orders: print(f" - {order['item_name']}: {order['price']:.2f} руб., {order['quantity']} шт.") # Шаг 8: Формирование отчета stats = { 'unique_users': len(grouped), 'total_revenue': original_total, 'most_expensive_item': most_expensive, 'unique_items': unique_items } report_text = generate_report(stats) # Шаг 9: Вывод отчета print("\n" + report_text) # Шаг 10: Сохранение отчета в файл report_path = os.path.join(data_dir, "report.txt") success = save_report(report_path, report_text) if success: print(f"\nОтчет успешно сохранен в файл: {report_path}") else: print("\nНе удалось сохранить отчет.") print("\n=== Работа программы завершена ===") # Точка входа if __name__ == "__main__": main()