Постановка задачи
Напишите программу sales_report.py, которая обрабатывает текстовый файл с данными о продажах и формирует структуру отчётов на диске.
Программа запускается из командной строки:
python sales_report.py <input_file> <output_directory>
<input_file>— путь к файлуsales_data.txtс записями о продажах.<output_directory>— папка, в которой будут созданы отчёты.
Формат входных данных
Каждая строка входного файла содержит пять полей, разделённых запятой:
имя,дата,сумма,категория,город
Пример строк:
Olivia Suarez,2024-08-02,4565,Electronics,Dallas
Jennifer Jacobs,2023-08-19,4963,Automotive,London
Erin Johnson,2024-08-29,1796,Clothing,Miami
Из даты 2024-08-02 нужно выделить год 2024 и месяц 08, чтобы сгруппировать запись по периоду.
Формат выходных данных
Для каждого года и месяца программа должна создать папку output_directory/YYYY/MM/. Внутри папки размещаются:
monthly_report.txt— общий отчёт с суммарной выручкой по каждой категории и общей суммой.- Файлы
<category>.txt— списки продаж по категории в форматедата,имя продавца,сумма, отсортированные по дате.
Пример monthly_report.txt:
Automotive,109539
Books,133160
Clothing,102001
Electronics,79403
Groceries,104387
Home Appliances,99911
Sports,78782
Full,707183
Пример файла Electronics.txt:
2025-02-01,Cynthia Maddox,538
2025-02-01,Kendra Martinez,3799
2025-02-02,Rachel Miller,1097
Пример созданной структуры
reports/
├── 2024/
│ ├── 12/
│ │ ├── monthly_report.txt
│ │ ├── Automotive.txt
├── 2025/
│ ├── 01/
│ │ ├── monthly_report.txt
│ │ ├── Clothing.txt
│ │ ├── Electronics.txt
│ ├── 02/
│ │ ├── monthly_report.txt
│ │ ├── Groceries.txt
│ │ ├── Sports.txt
План решения
-
Прочитать аргументы командной строки.
Использовать
sys.argvи проверить, что передано два аргумента. Иначе вывести подсказку и завершить программу. -
Прочитать и распарсить файл.
Открыть файл в кодировке
utf-8, прочитать строки, разбить каждую по,, проверить количество полей и преобразовать сумму вint. -
Сгруппировать данные.
Использовать
defaultdict(list)для записей по(year, month, category)иdefaultdict(lambda: defaultdict(int))для сумм по категориям внутри каждого(year, month). -
Создать файлы по категориям.
Для каждой группы
(year, month, category)отсортировать записи по дате, создать папки и записать строки в файл<category>.txt. -
Создать месячные отчёты.
Для каждого
(year, month)записать суммы по категориям вmonthly_report.txtи добавить строкуFull,<total>с общей суммой.
Почему defaultdict
Без defaultdict при каждом обращении к новому ключу пришлось бы проверять, есть ли он в словаре:
if key not in grouped:
grouped[key] = []
grouped[key].append(record)
С defaultdict(list) этот код сокращается до одной строки:
grouped[key].append(record)
Аналогично для вложенной группировки сумм: defaultdict(lambda: defaultdict(int)) автоматически создаёт внутренний счётчик для каждой новой категории.
Почему os.path.join
Разделители в путях различаются на Windows (\) и Unix (/). Если писать путь вручную, программа может не работать на другой операционной системе. os.path.join выбирает правильный разделитель автоматически.
report_file = os.path.join(output_dir, year, month, "monthly_report.txt")
Краткий итог
Практикум объединяет несколько важных навыков: чтение аргументов командной строки, парсинг текстового файла, группировку через defaultdict, создание директорий и запись отчётов. В результате получается полноценная утилита для обработки данных.