commit 9325d8a60ed6dd5af1a1a2a56c53504b43d2a9f1 Author: ohiko Date: Sat Apr 4 11:51:20 2026 +0300 Анализ продаж интернет-магазина электроники diff --git a/data/sales.json b/data/sales.json new file mode 100644 index 0000000..bbea79d --- /dev/null +++ b/data/sales.json @@ -0,0 +1,7 @@ +[ + {"id": 1, "category": "Смартфоны", "product": "iPhone 15", "price": 120000.0, "quantity": 2, "date": "2026-04-01"}, + {"id": 2, "category": "Ноутбуки", "product": "MacBook Air M2", "price": 150000.0, "quantity": 1, "date": "2026-04-01"}, + {"id": 3, "category": "Смартфоны", "product": "Samsung Galaxy S24", "price": 110000.0, "quantity": 3, "date": "2026-04-02"}, + {"id": 4, "category": "Аксессуары", "product": "AirPods Pro", "price": 25000.0, "quantity": 5, "date": "2026-04-02"}, + {"id": 5, "category": "Смартфоны", "product": "Xiaomi 14", "price": 80000.0, "quantity": 2, "date": "2026-04-03"} +] \ No newline at end of file diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..6b64fa3 --- /dev/null +++ b/src/main.py @@ -0,0 +1,35 @@ +from sales_analyzer import * +from datetime import datetime + +if __name__ == "__main__": + sales_file_path = "data/sales.json" + report_output_path = "sales_report.json" + today_str = datetime.now().strftime("%Y-%m-%d") + + all_sales = load_sales(sales_file_path) + if not all_sales: + all_sales = [] + + + all_sales = add_sale(all_sales, "Аксессуары", "Беспроводная мышь", 3500.0, 4, today_str) + print(f"Добавлена новая продажа: {all_sales[-1]}") + + + todays_sales = filter_by_date(all_sales, today_str) + print(f"\nПродажи за {today_str}: {len(todays_sales)} записей.") + + + total_revenue = calculate_revenue(all_sales) + top_category = get_top_category(all_sales) + average_price = get_average_price(all_sales) + best_selling_product = find_best_selling_product(all_sales) + + + generate_sales_report(all_sales, report_output_path) + + + print("\n--- Обзор продаж ---") + print(f"Общая выручка: {total_revenue:.2f} руб.") + print(f"Категория с наибольшей выручкой: {top_category}") + print(f"Лучший товар: {best_selling_product['product']} ({best_selling_product['quantity']} шт.)") + print(f"Средняя цена товара: {average_price:.2f} руб.") \ No newline at end of file diff --git a/src/sales_analyzer.py b/src/sales_analyzer.py new file mode 100644 index 0000000..243f74e --- /dev/null +++ b/src/sales_analyzer.py @@ -0,0 +1,110 @@ +import json +from collections import defaultdict +def load_sales(file_path: str) -> list: + """Читает JSON из файла и возвращает список продаж.""" + try: + with open(file_path, 'r', encoding='utf-8') as f: + return json.load(f) + except FileNotFoundError: + print(f"Ошибка: файл {file_path} не найден.") + return [] + except json.JSONDecodeError: + print(f"Ошибка: некорректный формат JSON в файле {file_path}.") + return [] +def calculate_revenue(sales: list) -> float: + """Вычисляет общую выручку.""" + total_revenue = 0 + for sale in sales: + revenue = sale.get('price', 0) * sale.get('quantity', 0) + total_revenue += revenue + return total_revenue +def get_top_category(sales: list) -> str: + """Определяет категорию с наибольшей выручкой.""" + category_revenue = defaultdict(float) + for sale in sales: + revenue = sale.get('price', 0) * sale.get('quantity', 0) + category_revenue[sale.get('category', 'Unknown')] += revenue + if not category_revenue: + return "Нет данных" + return max(category_revenue, key=category_revenue.get) +def filter_by_date(sales: list, date: str) -> list: + """Возвращает продажи за указанную дату.""" + result = [] + for sale in sales: + if sale.get('date') == date: + result.append(sale) + return result +def get_average_price(sales: list) -> float: + """Вычисляет среднюю цену товара.""" + try: + return sum(sale.get('price', 0) for sale in sales) / len(sales) + except ZeroDivisionError: + return 0.0 +def find_best_selling_product(sales: list) -> dict: + """Находит товар с максимальным количеством проданных единиц.""" + product_quantity = defaultdict(int) + for sale in sales: + product_name = sale.get('product') + quantity = sale.get('quantity') + if product_name and isinstance(quantity, (int, float)) and quantity > 0: + product_quantity[product_name] += quantity + if not product_quantity: + return {"product": "Нет данных", "quantity": 0} + best_product_name = max(product_quantity, key=product_quantity.get) + return {"product": best_product_name, "quantity": product_quantity[best_product_name]} + +def count_products_by_category(sales: list) -> dict: + """Подсчитывает количество уникальных товаров в каждой категории.""" + result = {} + for sale in sales: + category = sale.get('category', 'Unknown') + product = sale.get('product', 'Unknown Product') + if category not in result: + result[category] = [] + if product not in result[category]: + result[category].append(product) + return {cat: len(prods) for cat, prods in result.items()} +def get_daily_sales_stats(sales: list) -> dict: + """Возвращает словарь с датами и общей выручкой за каждый день.""" + daily_revenue = {} + for sale in sales: + revenue = sale.get('price', 0) * sale.get('quantity', 0) + date = sale.get('date', 'Unknown Date') + daily_revenue[date] = daily_revenue.get(date, 0) + revenue + return daily_revenue +def add_sale(sales: list, category: str, product: str, price: float, quantity: int, date: str) -> list: + """Добавляет новую продажу.""" + new_id = max([sale.get('id', 0) for sale in sales], default=0) + 1 + new_sale = { + "id": new_id, + "category": category, + "product": product, + "price": price, + "quantity": quantity, + "date": date + } + sales.append(new_sale) + return sales +def generate_sales_report(sales: list, output_file: str) -> None: + """Формирует и сохраняет отчёт в файл.""" + total_revenue = calculate_revenue(sales) + top_category = get_top_category(sales) + best_selling_product = find_best_selling_product(sales) + daily_stats = get_daily_sales_stats(sales) + products_by_category = count_products_by_category(sales) + average_price = get_average_price(sales) + report_data = { + "общая выручка": round(total_revenue, 2), + "категорию с наибольшими продажами": top_category, + "самый продаваемый товар": best_selling_product, + "продажи по дням": daily_stats, + "количество уникальных товаров": products_by_category, + "среднюю цену товара": round(average_price, 2), + "число продаж": len(sales) + } + try: + with open(output_file, 'w', encoding='utf-8') as f: + json.dump(report_data, f, indent=4, ensure_ascii=False) + print(f"Отчёт сохранен в файл: {output_file}") + except IOError: + print(f"Ошибка: не удалось записать в файл {output_file}.") \ No newline at end of file