From 264a3c49600eeba0bea4b7c93d48157a140edf97 Mon Sep 17 00:00:00 2001 From: user_3d Date: Thu, 6 Nov 2025 10:11:51 +0500 Subject: [PATCH] 202511061 --- main.py | 224 +++++++++++++++++++++++++++----- read.txt | 389 +------------------------------------------------------ 2 files changed, 194 insertions(+), 419 deletions(-) diff --git a/main.py b/main.py index bdea55c..0d17f6a 100644 --- a/main.py +++ b/main.py @@ -4,9 +4,7 @@ import os import sys import openpyxl - def create_tables(db_connection): - """Создает все необходимые таблицы в базе данных""" cursor = db_connection.cursor() cursor.executescript(''' @@ -64,10 +62,23 @@ def create_tables(db_connection): db_connection.commit() print("✅ Таблицы успешно созданы") - - def calculate_discount(total_quantity): - """Рассчитывает скидку на основе общего количества проданной продукции""" + """Рассчитываетссчитывает скидку на основе общего количества проданной продукции + + Args: + total_quantity (int): общее количество проданной продукции + + Returns: + tuple: кортеж содержащий: + - discount_percent (int): процент скидки + - discount_description (str): текстовое описание скидки + + Discount tiers: + - 15%: при объеме продаж от 300000 единиц + - 10%: при объеме продаж от 50000 до 300000 единиц + - 5%: при объеме продаж от 10000 до 50000 единиц + - 0%: при объеме продаж менее 10000 единиц + """ if total_quantity >= 300000: return 15, '15% (более 300000 ед.)' elif total_quantity >= 50000: @@ -76,10 +87,45 @@ def calculate_discount(total_quantity): return 5, '5% (10000-50000 ед.)' else: return 0, '0% (до 10000 ед.)' - - def get_partners(db_path='partners.db', sort_by='rating', ascending=False): - """Получает данные о партнерах с возможностью сортировки""" + """Получает данные о партнерах из базы данных с возможностью сортировки и расчета скидок + + Args: + db_path (str): путь к файлу базы данных SQLite. По умолчанию 'partners.db' + sort_by (str): поле для сортировки. Допустимые значения: + - 'rating': по рейтингу (по умолчанию) + - 'discount': по общему количеству продаж (для расчета скидки) + - 'name': по наименованию партнера + - 'type': по типу партнера и наименованию + ascending (bool): направление сортировки. + - False: по убыванию (по умолчанию) + - True: по возрастанию + + Returns: + pandas.DataFrame или None: DataFrame с данными партнеров или None в случае ошибки + + Структура возвращаемого DataFrame: + - Тип партнера + - Наименование партнера + - Директор + - Электронная почта + - Телефон + - Юридический адрес + - ИНН + - Рейтинг + - Дата создания + - total_quantity: общее количество продаж (скрытое поле) + - Скидка: процент скидки на основе total_quantity + - Текст_скидки: текстовое описание скидки + + Raises: + sqlite3.Error: ошибки работы с базой данных + Exception: другие возможные ошибки + + Example: + >>> df = get_partners(sort_by='discount', ascending=True) + >>> df = get_partners('my_database.db', sort_by='name') + """ try: conn = sqlite3.connect(db_path) query = """ @@ -123,17 +169,50 @@ def get_partners(db_path='partners.db', sort_by='rating', ascending=False): df['Текст_скидки'] = df['total_quantity'].apply(lambda x: calculate_discount(x)[1]) return df - except sqlite3.Error as e: print(f"❌ Ошибка базы данных: {e}") return None except Exception as e: print(f"❌ Общая ошибка: {e}") return None - - def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'): - """Получает историю реализации продукции с разными вариантами сортировки""" + """Получает историю реализации продукции с разными вариантами сортировки + + Args: + db_path (str): путь к файлу базы данных SQLite. По умолчанию 'partners.db' + limit (int): ограничение количества возвращаемых записей. По умолчанию 50 + sort_by (str): критерий сортировки данных. Допустимые значения: + - 'date_desc': по дате продажи (новые сверху, по умолчанию) + - 'date_asc': по дате продажи (старые сверху) + - 'quantity_desc': по количеству (по убыванию) + - 'amount_desc': по общей сумме (по убыванию) + + Returns: + pandas.DataFrame или None: DataFrame с историей продаж или None в случае ошибки + + Структура возвращаемого DataFrame: + - Дата продажи: дата осуществления продажи + - Партнер: наименование партнера + - Продукция: название продукции + - Артикул: артикул продукции + - Количество: количество проданных единиц + - Цена за единицу: цена за одну единицу продукции + - Общая сумма: общая сумма продажи (рассчитывается как количество × цена) + - Тип продукции: категория продукции + + Raises: + Exception: ошибки при выполнении запроса к базе данных + + Example: + >>> # Получить последние 50 продаж + >>> df = get_sales_history() + + >>> # Получить 100 самых крупных продаж по сумме + >>> df = get_sales_history(limit=100, sort_by='amount_desc') + + >>> # Получить историю продаж в хронологическом порядке + >>> df = get_sales_history(sort_by='date_asc', limit=200) + """ try: conn = sqlite3.connect(db_path) query = """ @@ -172,9 +251,28 @@ def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'): except Exception as e: print(f"❌ Ошибка при получении истории продаж: {e}") return None - def print_partner_cards(partners_df): - """Выводит карточки партнеров в красивом формате""" + """Выводит карточки партнеров в красивом формате с рамкой + + Args: + partners_df (pandas.DataFrame): DataFrame с данными партнеров, полученный из функции get_partners() + + Returns: + None: функция выполняет только вывод в консоль + + Формат вывода: + Каждая карточка партнера оформлена в виде рамки с следующими полями: + - Тип партнера + - Наименование партнера + - Директор + - Рейтинг + - Общее количество проданных единиц (форматированное с разделителями тысяч) + - Размер и описание скидки + - Электронная почта + - Телефон + - ИНН + - Юридический адрес (обрезается до 60 символов если слишком длинный) +""" if partners_df is None or partners_df.empty: print("📭 Нет данных о партнерах") return @@ -213,8 +311,6 @@ def print_partner_cards(partners_df): print(f"║ {address_text:<67} ║") print("╚" + "═" * 69 + "╝") print() - - def print_sales_cards(sales_df): """Выводит карточки истории реализации в виде таблицы""" if sales_df is None or sales_df.empty: @@ -245,7 +341,6 @@ def print_sales_cards(sales_df): print(f"║ {date} ║ {partner.ljust(16)} ║ {product.ljust(57)} ║ {article.ljust(8)} ║ {quantity.ljust(8)} ║ {price.ljust(10)} ║ {total.ljust(18)} ║") print("╚" + "═" * 147 + "╝") - # Итоги total_quantity = sales_df['Количество'].sum() total_amount = sales_df['Общая сумма'].sum() @@ -257,7 +352,6 @@ def simple_choice(options): print("=" * 50) for i, option in enumerate(options, 1): print(f"{i}. {option}") - while True: try: choice = input(f"\nВведите номер (1-{len(options)}): ").strip() @@ -271,10 +365,46 @@ def simple_choice(options): except KeyboardInterrupt: print("\n👋 Программа прервана пользователем.") sys.exit(0) - - def check_database(): - """Проверяет загруженные данные в базе""" + """Упрощенная функция выбора опции из списка с валидацией ввода + + Args: + options (list): список строк с доступными опциями для выбора + + Returns: + str: выбранная опция из списка options + + Особенности: + - Выводит пронумерованный список опций в красивом формате + - Запрашивает ввод пользователя с валидацией + - Обрабатывает некорректный ввод и повторяет запрос + - Обрабатывает прерывание программы (Ctrl+C) с graceful shutdown + - Поддерживает ввод только цифровых значений в допустимом диапазоне + + Raises: + SystemExit: при прерывании программы пользователем (KeyboardInterrupt) + + Example: + >>> options = ["Показать всех партнеров", "История продаж", "Выход"] + >>> choice = simple_choice(options) + + ================================================== + ВЫБЕРИТЕ ОПЦИЮ: + ================================================== + 1. Показать всех партнеров + 2. История продаж + 3. Выход + + Введите номер (1-3): 2 + >>> print(choice) + "История продаж" + + Обработка ошибок: + - Некорректный ввод (не цифры): повторный запрос + - Число вне диапазона: повторный запрос + - Прерывание (Ctrl+C): graceful exit программы + - EOF (Ctrl+D в Unix): обрабатывается как некорректный ввод + """ conn = sqlite3.connect('partners.db') try: cursor = conn.cursor() @@ -286,13 +416,33 @@ def check_database(): print(f" {table}: {count} записей") finally: conn.close() - - def load_data_from_files(): - """Загружает данные из Excel файлов в базу данных""" + """Загружает данные из Excel файлов в базу данных SQLite + + Функция выполняет полную загрузку данных из четырех Excel файлов в соответствующие таблицы базы данных. + Процесс загрузки состоит из пяти этапов, выполняемых последовательно с проверкой целостности данных. + + Args: + None: имена файлов запрашиваются у пользователя через интерактивный ввод + + Returns: + None: функция выполняет операции с базой данных и выводит результаты в консоль + + Процесс загрузки: + 1. 📊 Типы партнеров - из файла партнеров извлекаются уникальные типы + 2. 👥 Партнеры - загрузка основных данных о партнерах с привязкой к типам + 3. 📦 Типы продукции - загрузка категорий продукции с коэффициентами + 4. 🏷️ Продукты - загрузка данных о продукции с привязкой к типам + 5. 💰 Продажи - загрузка истории продаж с валидацией связей и преобразованием дат + + Требуемые файлы: + - Файл с партнерами: содержит данные о партнерах и их типах + - Файл с типами продукции: содержит категории продукции и коэффициенты + - Файл с продуктами: содержит данные о продукции с привязкой к типам + - Файл с продажами: содержит историю продаж с ссылками на партнеров и продукты +""" conn = sqlite3.connect('partners.db') cursor = conn.cursor() - try: # Запрос имен файлов print("\n📁 Введите имена файлов:") @@ -391,10 +541,25 @@ def load_data_from_files(): conn.rollback() finally: conn.close() - - def display_menu(): - """Главное меню программы""" + """Главное меню программы для управления базой данных партнеров и продаж + + Функция предоставляет интерактивный интерфейс для работы с системой управления партнерами. + Реализует основной цикл программы с возможностью выбора различных операций. + + Args: + None: все параметры задаются внутри функции или запрашиваются у пользователя + + Returns: + None: функция выполняется до выбора опции выхода + + Основные функции меню: + 1. КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу) - отображение партнеров, отсортированных по рейтингу + 2. КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам) - отображение партнеров, отсортированных по уровню скидки + 3. ИСТОРИЯ РЕАЛИЗАЦИИ - просмотр последних 50 записей о продажах + 4. ЗАПОЛНЕНИЕ БД из файлов - полная переинициализация базы данных с загрузкой из Excel файлов + 5. ВЫХОД - завершение работы программы +""" menu_options = [ 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)', 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)', @@ -402,7 +567,6 @@ def display_menu(): 'ЗАПОЛНЕНИЕ БД из файлов', 'ВЫХОД' ] - while True: choice = simple_choice(menu_options) @@ -439,8 +603,6 @@ def display_menu(): elif choice == 'ВЫХОД': print("\n👋 До свидания!") break - - if __name__ == "__main__": display_menu() diff --git a/read.txt b/read.txt index 207865a..794637a 100644 --- a/read.txt +++ b/read.txt @@ -3,395 +3,8 @@ Файл с продуктами: Products_import.xlsx Файл с продажами: Partner_products_import.xlsx - -# Импортируем библиотеку SQLite3 для взаимодействия с базами данных SQLite -import sqlite3 -# Подключаем библиотеку Pandas для обработки и анализа данных -import pandas as pd -# Подключаем модуль операционной системы Python для работы с файлами и путями -import os -# Подключаем модуль sys для взаимодействия с интерпретатором Python и системой -import sys -# Подключаем библиотеку OpenPyXL для чтения и записи файлов Excel формата .xlsx -import openpyxl - - -import sqlite3 -import pandas as pd -import os -import sys -import openpyxl - -# Функция создает структуру таблиц в базе данных -def create_tables(db_connection): - """Создает все необходимые таблицы в базе данных.""" - cursor = db_connection.cursor() - - # Создание таблиц и индексов - cursor.executescript(''' - ... - ''') # Здесь прописаны запросы на создание таблиц и индексов - - db_connection.commit() - print("✅ Таблицы успешно созданы") - - -# Функция рассчитывает скидку на основе объема продаж -def calculate_discount(total_quantity): - """Рассчитывает скидку на основе общего количества проданной продукции.""" - if total_quantity >= 300000: - return 15, '15% (более 300000 ед.)' - elif total_quantity >= 50000: - return 10, '10% (50000-300000 ед.)' - elif total_quantity >= 10000: - return 5, '5% (10000-50000 ед.)' - else: - return 0, '0% (до 10000 ед.)' - - -# Функция получает данные о партнерах из базы данных -def get_partners(db_path='partners.db', sort_by='rating', ascending=False): - """Получает данные о партнерах с возможностью сортировки.""" - try: - conn = sqlite3.connect(db_path) - query = """ - ... - """ # Здесь прописан SQL-запрос для выборки данных о партнерах - - # Применяем нужную сортировку и лимитируем количество записей - if sort_by == 'discount': - query += " ORDER BY total_quantity" - elif sort_by == 'rating': - query += " ORDER BY p.rating" - elif sort_by == 'name': - query += " ORDER BY p.name" - elif sort_by == 'type': - query += " ORDER BY pt.type_name, p.name" - else: - query += " ORDER BY p.rating" - - query += " DESC" if not ascending else " ASC" - - df = pd.read_sql_query(query, conn) - conn.close() - - # Добавляем дополнительные колонки со скидкой - if not df.empty: - df['Скидка'] = df['total_quantity'].apply(lambda x: calculate_discount(x)[0]) - df['Текст_скидки'] = df['total_quantity'].apply(lambda x: calculate_discount(x)[1]) - - return df - - except sqlite3.Error as e: - print(f"❌ Ошибка базы данных: {e}") - return None - except Exception as e: - print(f"❌ Общая ошибка: {e}") - return None - - -# Функция получает историю продаж -def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'): - """Получает историю реализации продукции с разными вариантами сортировки.""" - try: - conn = sqlite3.connect(db_path) - query = """ - ... - """ # Здесь прописан SQL-запрос для выборки истории продаж - - # Применяем сортировку и ограничение числа записей - if sort_by == 'date_desc': - query += " ORDER BY s.sale_date DESC, s.created_at DESC" - elif sort_by == 'date_asc': - query += " ORDER BY s.sale_date ASC, s.created_at ASC" - elif sort_by == 'quantity_desc': - query += " ORDER BY s.quantity DESC" - elif sort_by == 'amount_desc': - query += " ORDER BY (s.quantity * s.sale_price) DESC" - else: - query += " ORDER BY s.sale_date DESC, s.created_at DESC" - - query += " LIMIT ?" - - df = pd.read_sql_query(query, conn, params=(limit,)) - conn.close() - return df - except Exception as e: - print(f"❌ Ошибка при получении истории продаж: {e}") - return None - - -# Функция выводит информацию о партнерах в красивой форме -def print_partner_cards(partners_df): - """Выводит карточки партнеров в красивом формате.""" - if partners_df is None or partners_df.empty: - print("📭 Нет данных о партнерах") - return - - # Красивый вывод карточек партнеров - for index, row in partners_df.iterrows(): - # Оформление рамки вокруг карточки - print("╔" + "═" * 69 + "╗") - print(f"║ {'КАРТОЧКА ПАРТНЕРА':^67} ║") - print("╠" + "═" * 69 + "╣") - - # Информация о партнере - print(f"║ Тип: {row['Тип партнера']}{' ':<63}║") - print(f"║ Наименование: {row['Наименование партнера']}{' ':<50}║") - print(f"║ Директор: {row['Директор']}{' ':<61}║") - print(f"║ Рейтинг: {row['Рейтинг']}{' ':<63}║") - print(f"║ Продано единиц: {row['total_quantity']:,}{' ':<52}║") - print(f"║ Скидка: {row['Текст_скидки']}{' ':<58}║") - print(f"║ {' ':<67}║") - print(f"║ Электронная почта: {row['Электронная почта']}{' ':<45}║") - print(f"║ Телефон: {row['Телефон']}{' ':<61}║") - print(f"║ {' ':<67}║") - print(f"║ ИНН: {row['ИНН']}{' ':<63}║") - print(f"║ Адрес: {row['Юридический адрес']}{' ':<59}║") - print("╚" + "═" * 69 + "╝") - print() - - -# Функция выводит историю продаж в табличном представлении -def print_sales_cards(sales_df): - """Выводит карточки истории реализации в виде таблицы.""" - if sales_df is None or sales_df.empty: - print("📭 Нет данных о продажах") - return - - # Рамка таблицы - print("╔" + "═" * 147 + "╗") - print(f"║ {'ИСТОРИЯ РЕАЛИЗАЦИИ ПРОДУКЦИИ':^145} ║") - print("╠" + "═" * 147 + "╣") - - # Заголовок таблицы - headers = ["Дата", "Партнер", "Продукция", "Артикул", "Кол-во", "Цена", "Сумма"] - print("║ {:<12} {:<18} {:<59} {:<3} {:>9} {:>8} {:>13} ║".format(*headers)) - print("╠" + "═" * 147 + "╣") - - # Вывод данных о продажах - for index, row in sales_df.iterrows(): - date = str(row['Дата продажи'])[:10] - partner = row['Партнер'] - product = row['Продукция'] - article = str(row['Артикул']) - quantity = f"{row['Количество']:,}" - price = f"{row['Цена за единицу']:,.2f}" - total = f"{row['Общая сумма']:,.2f}" - - print(f"║ {date} ║ {partner.ljust(16)} ║ {product.ljust(57)} ║ {article.ljust(8)} ║ {quantity.ljust(8)} ║ {price.ljust(10)} ║ {total.ljust(18)} ║") - - # Закрывающая рамка таблицы - print("╚" + "═" * 147 + "╝") - - # Итоговая статистика - total_quantity = sales_df['Количество'].sum() - total_amount = sales_df['Общая сумма'].sum() - print(f"📊 ИТОГО: {len(sales_df)} продаж, {total_quantity:,} единиц, общая сумма: {total_amount:,.2f} руб.") - - -# Простая функция выбора пункта меню -def simple_choice(options): - """Упрощенная функция выбора.""" - print("\n" + "=" * 50) - print("ВЫБЕРИТЕ ОПЦИЮ:") - print("=" * 50) - for i, option in enumerate(options, 1): - print(f"{i}. {option}") - - while True: - try: - choice = input(f"\nВведите номер (1-{len(options)}): ").strip() - if choice.isdigit(): - choice_num = int(choice) - if 1 <= choice_num <= len(options): - return options[choice_num - 1] - print(f"❌ Пожалуйста, введите число от 1 до {len(options)}") - except (ValueError, EOFError): - print("❌ Неверный ввод. Попробуйте еще раз.") - except KeyboardInterrupt: - print("\n👋 Программа прервана пользователем.") - sys.exit(0) - - -# Проверяет наличие данных в базе -def check_database(): - """Проверяет загруженные данные в базе.""" - conn = sqlite3.connect('partners.db') - try: - cursor = conn.cursor() - print("\n🔍 Проверка загруженных данных:") - tables = ['PartnerType', 'Partner', 'ProductType', 'Product', 'Sale'] - for table in tables: - cursor.execute(f"SELECT COUNT(*) FROM {table}") - count = cursor.fetchone()[0] - print(f" {table}: {count} записей") - finally: - conn.close() - - -# Загружает данные из Excel-файлов в базу данных -def load_data_from_files(): - """Загружает данные из Excel файлов в базу данных.""" - conn = sqlite3.connect('partners.db') - cursor = conn.cursor() - - try: - # 1. Загрузка типов партнеров - print("\n1. 📊 Загрузка типов партнеров...") - partners_df = pd.read_excel(input("Файл с партнерами: ")) - partner_types = partners_df['Тип партнера'].unique() - for partner_type in partner_types: - cursor.execute("INSERT OR IGNORE INTO PartnerType (type_name) VALUES (?)", (partner_type,)) - - # 2. Загрузка партнеров - print("2. 👥 Загрузка партнеров...") - for _, row in partners_df.iterrows(): - cursor.execute("SELECT id FROM PartnerType WHERE type_name = ?", (row['Тип партнера'],)) - partner_type_id = cursor.fetchone()[0] - - cursor.execute(""" - INSERT OR IGNORE INTO Partner - (partner_type_id, name, director, email, phone, legal_address, inn, rating) - VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", - (partner_type_id, row['Наименование партнера'], row['Директор'], - row['Электронная почта партнера'], row['Телефон партнера'], - row['Юридический адрес партнера'], row['ИНН'], row['Рейтинг']) - ) - - # 3. Загрузка типов продукции - print("3. 📦 Загрузка типов продукции...") - product_type_df = pd.read_excel(input("Файл с типами продукции: ")) - for _, row in product_type_df.iterrows(): - cursor.execute("INSERT OR IGNORE INTO ProductType (type_name, coefficient) VALUES (?, ?)", - (row['Тип продукции'], row['Коэффициент типа продукции']) - ) - - # 4. Загрузка продуктов - print("4. 🏷️ Загрузка продуктов...") - products_df = pd.read_excel(input("Файл с продуктами: ")) - for _, row in products_df.iterrows(): - cursor.execute("SELECT id FROM ProductType WHERE type_name = ?", (row['Тип продукции'],)) - product_type_id = cursor.fetchone()[0] - - cursor.execute(""" - INSERT OR IGNORE INTO Product - (product_type_id, product_name, article, min_partner_price) - VALUES (?, ?, ?, ?)""", - (product_type_id, row['Наименование продукции'], - row['Артикул'], row['Минимальная стоимость для партнера']) - ) - - # 5. Загрузка продаж - print("5. 💰 Загрузка продаж...") - sales_df = pd.read_excel(input("Файл с продажами: ")) - loaded_sales = 0 - - for _, row in sales_df.iterrows(): - # Находим ID продукта - cursor.execute("SELECT id FROM Product WHERE product_name = ?", (row['Продукция'],)) - product_result = cursor.fetchone() - if not product_result: - print(f" ⚠️ Продукт не найден: {row['Продукция']}") - continue - product_id = product_result[0] - - # Находим ID партнера - cursor.execute("SELECT id FROM Partner WHERE name = ?", (row['Наименование партнера'],)) - partner_result = cursor.fetchone() - if not partner_result: - print(f" ⚠️ Партнер не найден: {row['Наименование партнера']}") - continue - partner_id = partner_result[0] - - # Получаем цену продажи - cursor.execute("SELECT min_partner_price FROM Product WHERE id = ?", (product_id,)) - min_price_result = cursor.fetchone() - sale_price = min_price_result[0] if min_price_result else 0 - - # Преобразуем дату - sale_date = pd.to_datetime(row['Дата продажи']).strftime('%Y-%m-%d') - - # Вставляем продажу - cursor.execute(""" - INSERT INTO Sale - (product_id, partner_id, quantity, sale_date, sale_price) - VALUES (?, ?, ?, ?, ?)""", - (product_id, partner_id, row['Количество продукции'], sale_date, sale_price) - ) - loaded_sales += 1 - - conn.commit() - print(f"✅ Данные успешно загружены! Загружено {loaded_sales} продаж") - check_database() -Файл с партнерами: Partners_import.xlsx -Файл с типами продукции: Product_type_import.xlsx -Файл с продуктами: Products_import.xlsx -Файл с продажами: Partner_products_import.xlsx - - except Exception as e: - print(f"❌ Ошибка при загрузке данных: {e}") - conn.rollback() - finally: - conn.close() - - -# Основное меню программы -def display_menu(): - """Главное меню программы.""" - menu_options = [ - 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)', - 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)', - 'ИСТОРИЯ РЕАЛИЗАЦИИ', - 'ЗАПОЛНЕНИЕ БД из файлов', - 'ВЫХОД' - ] - - while True: - choice = simple_choice(menu_options) - - if choice == 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)': - print("\n🎯 КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)") - print("═" * 70) - partners = get_partners(sort_by='rating', ascending=False) - print_partner_cards(partners) - - elif choice == 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)': - print("\n📊 КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)") - print("═" * 70) - partners = get_partners(sort_by='discount', ascending=False) - print_partner_cards(partners) - - elif choice == 'ИСТОРИЯ РЕАЛИЗАЦИИ': - print("\n📈 ИСТОРИЯ РЕАЛИЗАЦИИ ПРОДУКЦИИ") - print("═" * 70) - sales = get_sales_history(limit=50) - print_sales_cards(sales) - - elif choice == 'ЗАПОЛНЕНИЕ БД из файлов': - if os.path.exists('partners.db'): - os.remove('partners.db') - print("🗑️ База данных partners.db удалена") - else: - print("ℹ️ База данных partners.db не найдена, создаем новую") - - conn = sqlite3.connect('partners.db') - create_tables(conn) - conn.close() - load_data_from_files() - - elif choice == 'ВЫХОД': - print("\n👋 До свидания!") - break - - -# Главная точка запуска программы -if __name__ == "__main__": - display_menu() - - ###1 def calculate_discount(total_quantity): -"""Рассчитывает скидку на основе общего количества проданной продукции +"""Ра""Рассчитываетссчитывает скидку на основе общего количества проданной продукции Args: total_quantity (int): общее количество проданной продукции