From 1d7935303c9895bb84949b21c015bdbfce71e66a Mon Sep 17 00:00:00 2001 From: ALEXSim Date: Fri, 24 Apr 2026 23:03:23 +0300 Subject: [PATCH] =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D1=8B=20=D0=B2=D1=81=D0=B5=20=D1=84=D1=83?= =?UTF-8?q?=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20=D0=B8=20=D0=BE=D1=81=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BD=D0=BE=D0=B9=20=D1=81=D1=86=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 6 + cart_processor.py | 291 ---------------------------------------------- data/cart.txt | 7 -- data/receipt.txt | 19 --- 4 files changed, 6 insertions(+), 317 deletions(-) create mode 100644 .idea/misc.xml delete mode 100644 cart_processor.py delete mode 100644 data/cart.txt delete mode 100644 data/receipt.txt diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..dcb78c5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/cart_processor.py b/cart_processor.py deleted file mode 100644 index ccab334..0000000 --- a/cart_processor.py +++ /dev/null @@ -1,291 +0,0 @@ -""" -Модуль обработки корзины интернет-магазина -""" - -import os -from typing import List, Dict, Tuple - - -def load_cart(filepath: str) -> List[Dict]: - """ - Загружает корзину из файла. - Формат строки: название|цена|количество|категория - """ - cart = [] - - try: - with open(filepath, 'r', encoding='utf-8') as file: - for line_num, line in enumerate(file, 1): - line = line.strip() - if not line: - continue - - parts = line.split('|') - if len(parts) != 4: - print(f"Предупреждение: строка {line_num} имеет неверный формат, пропущена") - continue - - try: - name = parts[0].strip() - price = float(parts[1].strip()) - quantity = int(parts[2].strip()) - category = parts[3].strip() - - if price < 0 or quantity <= 0: - print(f"Предупреждение: строка {line_num} содержит недопустимые значения, пропущена") - continue - - cart.append({ - 'name': name, - 'price': price, - 'quantity': quantity, - 'category': category - }) - except ValueError: - print(f"Предупреждение: строка {line_num} содержит нечисловые значения, пропущена") - continue - except FileNotFoundError: - print(f"Ошибка: файл {filepath} не найден. Создайте файл с данными.") - return [] - - return cart - - -def calculate_item_total(item: Dict) -> float: - """Вычисляет общую стоимость одного товара (цена × количество)""" - return item['price'] * item['quantity'] - - -def apply_category_discount(cart: List[Dict], category: str, discount_percent: float) -> List[Dict]: - """ - Применяет скидку к товарам указанной категории. - Возвращает новый список (не изменяет исходный). - """ - if discount_percent < 0 or discount_percent > 100: - raise ValueError("Скидка должна быть в диапазоне 0-100%") - - new_cart = [] - discount_factor = 1 - discount_percent / 100 - - for item in cart: - new_item = item.copy() - if item['category'].lower() == category.lower(): - new_price = item['price'] * discount_factor - new_item['price'] = max(0, round(new_price, 2)) # цена не может быть отрицательной - new_cart.append(new_item) - - return new_cart - - -def calculate_subtotal(cart: List[Dict]) -> float: - """Вычисляет общую сумму всех товаров в корзине""" - total = sum(calculate_item_total(item) for item in cart) - return round(total, 2) - - -def apply_bulk_discount(subtotal: float, total_quantity: int, threshold: int, discount_percent: float) -> float: - """ - Применяет скидку на общую сумму, если количество товаров превышает порог. - """ - if threshold <= 0 or discount_percent < 0 or discount_percent > 100: - raise ValueError("Недопустимые параметры скидки") - - if total_quantity >= threshold: - discount_amount = subtotal * (discount_percent / 100) - return round(subtotal - discount_amount, 2) - return subtotal - - -def calculate_delivery_cost(subtotal: float, free_threshold: float, base_cost: float = 5.0) -> float: - """ - Рассчитывает стоимость доставки. - Бесплатно, если сумма заказа >= порога. - """ - if free_threshold < 0 or base_cost < 0: - raise ValueError("Стоимость не может быть отрицательной") - - if subtotal >= free_threshold: - return 0.0 - return base_cost - - -def find_most_expensive_item(cart: List[Dict]) -> Dict: - """Возвращает товар с максимальной итоговой стоимостью""" - if not cart: - return {} - - most_expensive = max(cart, key=calculate_item_total) - return most_expensive - - -def group_by_category(cart: List[Dict]) -> Dict[str, List[Dict]]: - """Группирует товары по категориям""" - groups = {} - for item in cart: - category = item['category'] - if category not in groups: - groups[category] = [] - groups[category].append(item) - return groups - - -def detect_duplicates(cart: List[Dict]) -> List[str]: - """Находит дубликаты товаров (по названию без учёта регистра)""" - name_counts = {} - for item in cart: - name_lower = item['name'].lower() - name_counts[name_lower] = name_counts.get(name_lower, 0) + 1 - - duplicates = [item['name'] for item in cart - if name_counts[item['name'].lower()] > 1] - - # Убираем дубликаты в возвращаемом списке - return list(set(duplicates)) - - -def generate_receipt(cart: List[Dict], delivery_cost: float, final_total: float) -> str: - """ - Формирует текстовый чек - """ - if not cart: - return "Корзина пуста" - - # Заголовок чека - receipt = [] - receipt.append("=" * 50) - receipt.append("ЧЕК ПОКУПАТЕЛЯ".center(50)) - receipt.append("=" * 50) - receipt.append(f"{'Товар':<20} {'Кол-во':>6} {'Цена':>10} {'Итого':>10}") - receipt.append("-" * 50) - - # Строки товаров - for item in cart: - name = item['name'][:18] # Обрезаем длинные названия - quantity = item['quantity'] - price = item['price'] - total = calculate_item_total(item) - - receipt.append(f"{name:<20} {quantity:>6} {price:>10.2f} {total:>10.2f}") - - receipt.append("-" * 50) - - # Информация о доставке и итоге - subtotal = calculate_subtotal(cart) - receipt.append(f"{'Подытог:':<40} {subtotal:>10.2f}") - receipt.append(f"{'Доставка:':<40} {delivery_cost:>10.2f}") - receipt.append("-" * 50) - receipt.append(f"{'ИТОГО К ОПЛАТЕ:':<40} {final_total:>10.2f}") - receipt.append("=" * 50) - receipt.append("Спасибо за покупку!".center(50)) - - return "\n".join(receipt) - - -def save_to_file(content: str, filepath: str) -> None: - """Сохраняет содержимое в файл (создаёт директорию при необходимости)""" - # Создаём директорию, если её нет - directory = os.path.dirname(filepath) - if directory and not os.path.exists(directory): - os.makedirs(directory) - - with open(filepath, 'w', encoding='utf-8') as file: - file.write(content) - - print(f"Чек сохранён в файл: {filepath}") - - -def print_cart(cart: List[Dict]) -> None: - """Выводит содержимое корзины в читаемом виде""" - print("\nСодержимое корзины:") - print("-" * 60) - for item in cart: - total = calculate_item_total(item) - print( - f" {item['name']:<20} | {item['price']:>8.2f} x {item['quantity']} = {total:>10.2f} | Кат: {item['category']}") - print("-" * 60) - - -def main(): - """Главная функция программы""" - print("=" * 60) - print("СИСТЕМА УПРАВЛЕНИЯ ЗАКАЗАМИ ИНТЕРНЕТ-МАГАЗИНА") - print("=" * 60) - - # 1. Загрузка корзины из файла - cart = load_cart("data/cart.txt") - if not cart: - print("Нет данных для обработки. Программа завершена.") - return - - # 2. Вывод содержимого корзины - print_cart(cart) - - # 3. Расчёт начальной суммы - subtotal = calculate_subtotal(cart) - print(f"\n1. Промежуточная сумма (без скидок): {subtotal:.2f} руб.") - - # 4. Применение скидки на категорию "Электроника" - print("\n2. Применяем скидку 15% на категорию 'Электроника'...") - discounted_cart = apply_category_discount(cart, "Электроника", 15) - subtotal_after_cat_discount = calculate_subtotal(discounted_cart) - print(f" Сумма после категорийной скидки: {subtotal_after_cat_discount:.2f} руб.") - - # 5. Подсчёт общего количества товаров - total_quantity = sum(item['quantity'] for item in discounted_cart) - print(f"\n3. Общее количество товаров в корзине: {total_quantity} шт.") - - # 6. Применение bulk-скидки (если количество >= 5) - subtotal_after_bulk = subtotal_after_cat_discount - if total_quantity >= 5: - subtotal_after_bulk = apply_bulk_discount(subtotal_after_cat_discount, total_quantity, 5, 10) - print(f" Применена bulk-скидка 10% (порог 5 шт.)") - print(f" Сумма после bulk-скидки: {subtotal_after_bulk:.2f} руб.") - else: - print(f" Bulk-скидка не применена (нужно {5} товаров, имеется {total_quantity})") - - # 7. Расчёт стоимости доставки - delivery_cost = calculate_delivery_cost(subtotal_after_bulk, 2000.0, 300.0) - if delivery_cost == 0: - print(f"\n4. Доставка: БЕСПЛАТНО (сумма заказа >= 2000 руб.)") - else: - print(f"\n4. Стоимость доставки: {delivery_cost:.2f} руб.") - - # 8. Поиск самого дорогого товара - most_expensive = find_most_expensive_item(discounted_cart) - if most_expensive: - expensive_total = calculate_item_total(most_expensive) - print(f"\n5. Самый дорогой товар: {most_expensive['name']} ({expensive_total:.2f} руб.)") - - # 9. Группировка по категориям - print("\n6. Группировка товаров по категориям:") - grouped = group_by_category(discounted_cart) - for category, items in grouped.items(): - category_total = calculate_subtotal(items) - items_count = sum(item['quantity'] for item in items) - print(f" • {category}: {items_count} шт., сумма {category_total:.2f} руб.") - - # 10. Поиск дубликатов - duplicates = detect_duplicates(discounted_cart) - if duplicates: - print(f"\n7. ВНИМАНИЕ: Найдены дубликаты товаров: {', '.join(duplicates)}") - else: - print("\n7. Дубликаты товаров не обнаружены") - - # 11. Формирование итоговой суммы к оплате - final_total = subtotal_after_bulk + delivery_cost - - # 12. Генерация чека - receipt = generate_receipt(discounted_cart, delivery_cost, final_total) - print("\n" + receipt) - - # 13. Сохранение чека в файл - save_to_file(receipt, "data/receipt.txt") - - # 14. Финальное сообщение - print("\n" + "=" * 60) - print("✅ Программа успешно завершена!") - print("=" * 60) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/data/cart.txt b/data/cart.txt deleted file mode 100644 index 89f4de5..0000000 --- a/data/cart.txt +++ /dev/null @@ -1,7 +0,0 @@ -Ноутбук|55000|1|Электроника -Мышь|1200|2|Электроника -Книга|800|3|Книги -Чехол для телефона|900|1|Аксессуары -Клавиатура|2500|1|Электроника -Наушники|3500|1|Электроника -Блокнот|150|4|Канцелярия \ No newline at end of file diff --git a/data/receipt.txt b/data/receipt.txt deleted file mode 100644 index 80444ea..0000000 --- a/data/receipt.txt +++ /dev/null @@ -1,19 +0,0 @@ -================================================== - ЧЕК ПОКУПАТЕЛЯ -================================================== -Товар Кол-во Цена Итого --------------------------------------------------- -Ноутбук 1 46750.00 46750.00 -Мышь 2 1020.00 2040.00 -Книга 3 800.00 2400.00 -Чехол для телефона 1 900.00 900.00 -Клавиатура 1 2125.00 2125.00 -Наушники 1 2975.00 2975.00 -Блокнот 4 150.00 600.00 --------------------------------------------------- -Подытог: 57790.00 -Доставка: 0.00 --------------------------------------------------- -ИТОГО К ОПЛАТЕ: 52011.00 -================================================== - Спасибо за покупку! \ No newline at end of file