Завершить ETL-проект и документацию
This commit is contained in:
1 parent
2ec0b38d95
commit
93b1478226
6 files changed
+669
-41
No files matched your search
+48
-40
@@ -1,79 +1,87 @@
|
||||
# Журнал работы с ИИ
|
||||
# Отчёт о работе с ИИ
|
||||
|
||||
## 12 ноября 2026 — осмотр проекта
|
||||
Работа велась по этапам 12 ноября 2026 года. ИИ помогал с планированием, кодом, тестами и документацией. Этот отчёт описывает фактический ход работы. Запросы ниже пересказаны; исходные тексты собраны в [prompts.md](prompts.md).
|
||||
|
||||
**Запрос пользователя.** Подготовить по этапам ETL-пайплайн для очистки CSV и агрегации выручки по дням и категориям в SQLite. Сохранять исходный CSV, учитывать причины отбраковки, проверить идемпотентность, подготовить три аналитических запроса с результатами, README и готовую базу. Вести журнал по фактически выполненной работе. Проверки писать на pytest. Оставить `main.py` в корне для объединения этапов, функции разместить в `src/`, пути вычислять от корня проекта.
|
||||
## 1. План и правила обработки
|
||||
|
||||
**Проверки.** Осмотр корня проекта через PowerShell показал `.git/` и `.gitignore`. Прочитан `.gitignore`, проверено состояние Git. Исходный CSV, код и тесты отсутствовали. Файл `AGENTS.md` в корне проекта и родительских каталогах не обнаружен. Дополнительная команда `rg --files` завершилась ошибкой канала запуска. Список содержимого корня получен через `Get-ChildItem -Force`.
|
||||
**Задача.** Разобрать требования и выбрать простое решение для CSV → очистка → SQLite → аналитика.
|
||||
|
||||
**Решение.** Первый этап реализации пользователь пока не указал. Работа ограничена осмотром и созданием журнала. Схема CSV и правила расчёта выручки пока не определены. Тесты не запускались.
|
||||
**Решение.** Использовать стандартную библиотеку Python, SQLite и pytest. Оставить `main.py` точкой запуска, разделить чтение, очистку, отчёты и загрузку по модулям. Деньги хранить в копейках, а цену разбирать через Decimal. Подробные правила записаны в [плане](implementation_plan.md).
|
||||
|
||||
## 12 ноября 2026 — план реализации
|
||||
До написания кода определили разницу между точными дублями, одинаковыми заказами после нормализации и конфликтами ID. Первоначальное описание одной причины отбраковки уточнили: у записи может быть несколько ошибок полей, но итоговый статус у неё один.
|
||||
|
||||
**Запрос пользователя.** Изучить проект и подготовить краткий план без кода пайплайна. Зафиксировать заданную модель заказа, денежные ограничения, порядок обработки дублей, нумерацию записей CSV, интерфейсы модулей, полную транзакционную перезагрузку, критерии готовности и неоднозначности.
|
||||
## 2. Генерация исходных данных
|
||||
|
||||
**Принятые решения.** В [плане реализации](implementation_plan.md) описаны пять полей заказа, точный разбор цены через Decimal, хранение денег в копейках и проверка диапазона INTEGER. Точные дубли определяются по исходным полям до валидации. Конфликты ID проверяются по всей группе валидных заказов до выбора представителя. Для отчёта у каждой отброшенной записи одна причина и логический номер после заголовка, начиная с единицы.
|
||||
**Задача.** Создать 1500 синтетических записей с гарантированными примерами ошибок.
|
||||
|
||||
**Разделение работы.** Чтение, очистка и загрузка распределены между тремя модулями в src/. Дневные агрегаты строятся в SQLite при полной перезагрузке двух таблиц в одной транзакции. В плане отдельно отмечены предлагаемые параметры CSV и определения аналитических запросов.
|
||||
**Результат.** Генератор использует `Random(42)` и даты с 1 января по 31 марта 2024 года. В набор добавлены пропуски, неверные даты и числа, точный дубль, дубль с другим форматом даты и конфликт ID. Персональных данных нет.
|
||||
|
||||
**Фактические проверки и изменения.** Повторный осмотр через rg и Git показал только .gitignore и ранее созданный журнал. Прочитан журнал, проверено отсутствие AGENTS.md в каталогах проекта и документации и по пути к корню диска. Добавлен план и обновлён журнал. Код пайплайна не создавался, pytest не запускался.
|
||||
**Проверка.** Два запуска дали одинаковый CSV. Первые два теста проверили количество записей и воспроизводимость. Для тестов создано виртуальное окружение; после неудачной попытки установки через настроенный источник pytest установлен из PyPI.
|
||||
|
||||
## 12 ноября 2026 — генератор синтетических заказов
|
||||
## 3. Чтение и очистка
|
||||
|
||||
**Запрос пользователя.** Создать воспроизводимый CSV на 1500 записей с seed=42, заданными дублями и ошибками. Запустить генератор и тесты количества записей и воспроизводимости на временных файлах.
|
||||
**Задача.** Сохранить исходные значения и номера записей, нормализовать поля и объяснить отбраковку.
|
||||
|
||||
**Решения.** В `src/generate_data.py` используется локальный `Random(42)`. Корректные даты выбираются из диапазона 01.01.2024–31.03.2024 включительно. Цены формируются из целых копеек, категории выбираются из фиксированного списка. Для трёх заказов добавляется по одной копии — точной, с другой записью той же даты и с изменённым количеством. Для остальных заданных случаев изменено по одному полю в отдельных заказах. Записи перемешиваются тем же генератором. CSV синтетический, без персональных данных. Кодировка UTF-8 и перевод строки LF заданы явно.
|
||||
**Результат.** Читатель проверяет заголовок и структуру CSV. Очистка собирает ошибки независимых полей, проверяет деньги и обрабатывает дубли в два этапа. Конфликты определяются среди валидных записей; ошибочная строка сама по себе не делает корректный заказ конфликтным.
|
||||
|
||||
**Окружение.** В доступном Python 3.14.4 отсутствовал pytest. Создана локальная .venv. Первая попытка установки не нашла дистрибутив, затем из PyPI установлен pytest 9.2.0.
|
||||
**Проверка.** Прошли 32 теста. Проверены даты, обязательные поля, деньги на границе SQLite INTEGER, переполнение выручки, дубли, конфликты и сохранность источника. Каждый исходный номер оказался ровно в одном результате: принятом или отброшенном.
|
||||
|
||||
**Проверки.** Команда `python -m src.generate_data` выполнена дважды. SHA-256 файла `data/raw_orders.csv` после обоих запусков совпал — `c4b9ffd2eb24c6c79b6a3e2436f3bd348ba86696a1aeb9b7e3083af65c799c67`. Чтение через csv.DictReader подтвердило пять заданных колонок, 1500 записей, один точный дубль и по одному пустому значению в каждом поле. ID 1, 2 и 3 встретились по два раза. Запуск `.\.venv\Scripts\python.exe -m pytest -q` завершился результатом `2 passed in 0.08s`. Оба теста используют tmp_path.
|
||||
## 4. Дополнительная проверка предложений ИИ
|
||||
|
||||
## 12 ноября 2026 — чтение и очистка
|
||||
**Задача.** Проверить крайние случаи и улучшить тесты без переписывания рабочей логики.
|
||||
|
||||
**Запрос пользователя.** Реализовать extract.py и transform.py, сохранить номер и исходные значения отклонённой записи, вернуть все обнаруженные ошибки полей, проверить дубли, конфликты, точность расчётов и сохранность CSV.
|
||||
**Что изменилось.** Первоначальные тесты генератора проверяли размер и повторяемость файла, но не наличие всех запланированных ошибок. Добавлена такая проверка, а также тесты неверной UTF-8, отказа доступа, многострочных полей, порядка записей и большой суммы с точностью до копейки. Список полей CSV стал общим для генератора и читателя.
|
||||
|
||||
**Решения и изменения.** csv.reader в строгом режиме читает UTF-8 с поддержкой BOM и нумерует логические записи после заголовка. Нечитаемый файл, ошибка разбора CSV или неверный заголовок прерывают обработку. Для читаемой записи неверной ширины сохраняются все исходные поля. Точный дубль получает только причину повтора. Для остальных структурно корректных записей собираются ошибки независимых полей. Выручка проверяется при пригодных для расчёта цене и количестве. Среди валидных заказов сначала определяется наличие конфликта во всей группе ID. Номер источника сохраняется и у принятого заказа, но исключён из сравнения нормализованных значений. План обновлён согласно уточнению о нескольких причинах.
|
||||
**Что не стали менять.** Другой ИИ предложил заменить расчёт через `as_integer_ratio()`, переименовать атрибут отбраковки и использовать `.get()` для категории. При разборе текущего кода эти замечания не подтвердились: расчёт точный, атрибуты согласованы, наличие колонки проверяет читатель. Предложения не приняли.
|
||||
|
||||
**Фактические проверки.** Полный запуск pytest дал 32 passed. На синтетическом raw_orders.csv обработаны 1500 записей, приняты 1482, отброшены 18. Из них 14 имели ошибки значений, одна оказалась точным дублем, одна — нормализованным, две отклонены из-за конфликта ID. Проверено, что номера от 1 до 1500 встречаются в совокупном результате ровно по одному разу. Байты CSV до и после обработки совпали, SHA-256 — `c4b9ffd2eb24c6c79b6a3e2436f3bd348ba86696a1aeb9b7e3083af65c799c67`.
|
||||
**Проверка.** После расширения покрытия прошли 38 тестов. Ошибок существующей логики очистки новые тесты не выявили. Рабочий CSV не изменился.
|
||||
|
||||
## 12 ноября 2026 — дополнительные проверки генерации, чтения и очистки
|
||||
## 5. Отчёт качества и экспорт
|
||||
|
||||
**Запрос пользователя.** Проверить запланированные примеры в CSV, обработку ошибок файла, нумерацию, деньги и приоритет причин отбраковки. Устранить повтор схемы CSV и уточнить план экспорта и аналитики.
|
||||
**Задача.** Сохранить очищенные заказы, отклонённые записи и статистику.
|
||||
|
||||
**Изменения.** Генератор использует FIELDS из extract.py. Добавлено шесть тестов. Они проверяют содержимое созданного во временной папке CSV, неверную кодировку, отказ при открытии файла (подмена PermissionError), многострочное поле с CRLF и нумерацию после него, смешанную группу дублей и конфликтов с проверкой порядка обоих списков, расчёт большой суммы с точностью до копейки. Новые проверки прошли на существующей логике очистки.
|
||||
**Результат.** Созданы `clean_orders.csv`, `rejected_rows.csv` и `quality_report.json` в `outputs/`. CSV записываются в UTF-8 с BOM. В отбраковке сохраняются исходные поля и все причины. Итоговая причина — первая по порядку проверок; отдельные счётчики проблем могут пересекаться.
|
||||
|
||||
**План.** Уточнены состав clean_orders.csv и учёт нескольких причин у одной отброшенной записи. Для будущих отчётов принят календарь между крайними датами принятых заказов. Для аномалий каждой категории учитываются нулевые дни, используется стандартное отклонение генеральной совокупности и строгий двусторонний порог 2σ. При периоде короче семи дней или нулевой дисперсии результат пуст.
|
||||
**Проверка.** Прошли 40 тестов. Проверены баланс строк, несколько ошибок у записи, обратное чтение исходных значений, повторный экспорт и пустой результат.
|
||||
|
||||
**Проверки.** Через существующую .venv выполнен полный pytest до изменений (32 passed) и после (38 passed). На исходном CSV принято 1482 заказа, отклонено 18. SHA-256 перед работой и после проверок совпал — `c4b9ffd2eb24c6c79b6a3e2436f3bd348ba86696a1aeb9b7e3083af65c799c67`. Повторно сгенерированный во временной папке CSV побайтово совпал с исходным.
|
||||
## 6. SQLite и полный запуск
|
||||
|
||||
## 12 ноября 2026 — уточнение аналитики и пути экспорта
|
||||
**Задача.** Объединить обработку в `python main.py` и обеспечить безопасный повторный запуск.
|
||||
|
||||
По запросу пользователя в плане закреплён путь `outputs/clean_orders.csv` относительно корня проекта. Динамику показываем по общей дневной выручке всех категорий, одной строкой на дату. Аномалии ищем отдельно по дневной выручке каждой категории, используя её собственные среднее и стандартное отклонение.
|
||||
**Результат.** Заказы и дневные агрегаты полностью заменяются в одной транзакции. Агрегация выполняется в SQLite. При ошибке загрузки предыдущие данные сохраняются. Отчёты записываются после фиксации базы; при сбое программа сообщает, что база уже обновлена.
|
||||
|
||||
## 12 ноября 2026 — статистика и экспорт результатов
|
||||
**Проверка.** Прошли 45 тестов. Интеграционные проверки запускали копию проекта во временной папке: повторная загрузка, совпадение CSV с базой, откат при переполнении суммы, повреждённый вход и набор без принятых заказов. Отдельно проверен сбой экспорта после обновления базы.
|
||||
|
||||
**Запрос пользователя.** Создать quality.py, выгрузить два CSV в UTF-8 с BOM и отчёт JSON, проверить баланс, повторный запуск и пустой снимок. Предусмотреть сохранение после успешной загрузки БД.
|
||||
## 7. SQL-аналитика
|
||||
|
||||
**Решения.** Модуль принимает результаты очистки и отдельное число исходных записей. Проверяет сумму статусов и покрытие всех исходных номеров без повторов. Итоговая причина — первая из обнаруженных в порядке проверок. Отдельные счётчики проблем включают все обнаруженные причины и могут пересекаться. В CSV отбраковки заголовок источника, исходные значения и причины представлены JSON-массивами. Так сохраняются порядок колонок, пустые и лишние поля. Состав чистого CSV уточнён в плане до шести запрошенных колонок. При сборке пайплайна save_outputs будет вызываться после успешного завершения транзакции БД.
|
||||
**Задача.** Подготовить топ категорий, дневную динамику и поиск аномалий с сохранёнными результатами.
|
||||
|
||||
**Фактические проверки.** Через существующую .venv выполнен полный pytest — 40 passed. Временный пример проверил несколько причин у одной записи, порядок, кодировку, обратное чтение значений, побайтовое совпадение при повторном экспорте и замену снимка пустым с долей null. Проверено отклонение несогласованных количеств и повторяющихся номеров. Для текущего этапа три файла созданы прямым вызовом экспорта после очистки. Чтение результатов из outputs подтвердило 1482 принятых и 18 отброшенных из 1500, доля 0,988. Суммы обоих счётчиков на этом наборе равны 18. SHA-256 исходного CSV до и после совпал.
|
||||
**Уточнение по ходу работы.** В раннем плане аномалией считался рост категории более чем вдвое к предыдущему наблюдению. Затем выбрали отклонение более чем на два стандартных отклонения. После обсуждения оставили отдельный расчёт для каждой категории, а динамику — общей по всем категориям. Путь чистого CSV уточнили до `outputs/clean_orders.csv`.
|
||||
|
||||
## 12 ноября 2026 — транзакционная загрузка и запуск пайплайна
|
||||
**Результат.** Запросы используют календарь с нулевыми днями внутри периода. Аномалии не выдаются для периода короче семи дней и при нулевой дисперсии. Метод не учитывает сезонность и может выделять обычные продажи редкой категории, поэтому результат считается поводом для проверки, а не доказательством ошибки.
|
||||
|
||||
**Запрос пользователя.** Реализовать схему SQLite, полную загрузку заказов и дневных агрегатов и команду python main.py. Проверить повторяемость данных, согласованность CSV, обработку пустого снимка и сохранность предыдущих данных при сбое.
|
||||
**Проверка.** Прошёл 51 тест. Проверены сортировка, пропущенные дни, рост и падение, постоянная выручка, короткий период, точная граница 2σ и пустая база. Тесты не изменили рабочую базу.
|
||||
|
||||
**Решения.** В sql/schema.sql заданы первичные ключи и ограничения значений. src/database.py открывает одну транзакцию до создания и очистки таблиц, вставляет заказы с параметрами, строит daily_category_revenue одним группирующим запросом и фиксирует обе таблицы вместе. main.py проверяет статистику до записи базы. После фиксации он передаёт готовый отчёт в save_reports. Если экспорт завершается ошибкой, CLI указывает, что база уже обновлена, и сохраняет исходную диагностику. Ранее использовавшийся интерфейс save_outputs сохранён.
|
||||
## 8. Итоговые проверки и комплект сдачи
|
||||
|
||||
**Фактические проверки.** В существующей .venv прошли все 45 тестов. Пять новых интеграционных тестов запускали копию проекта во временном каталоге из другой рабочей папки. Переполнение суммы группы откатило изменения обеих таблиц. Испорченный CSV сохранил прежний снимок. Набор без принятых заказов очистил обе таблицы. Сбой экспорта после фиксации базы завершил CLI с ненулевым кодом и сообщением об обновлённой БД.
|
||||
Подготовлены README, база, исходные и очищенные данные, отбраковка, отчёт качества, SQL-запросы и их результаты. В Git исключены окружение, кэши и секреты. Для исходного CSV закреплены окончания строк LF, база отмечена как двоичный файл.
|
||||
|
||||
На рабочем синтетическом CSV команда python main.py создала outputs/orders.db. Вход — 1500 записей, приняты 1482, отброшены 18. Получено 438 групп по дате и категории. Суммарная выручка в обеих таблицах составила 1 687 705 899 копеек. Содержимое обеих таблиц сравнили до и после повторного запуска, заказы сверили по всем шести полям с clean_orders.csv. SHA-256 исходного CSV совпал с исходным замером. Аналитические запросы остаются следующим этапом.
|
||||
Проверка в новом окружении на Python 3.14.4 с SQLite 3.50.4 и pytest 9.2.0 воспроизвела генерацию и запуск с нуля. Все 51 тест прошли. В рабочем окружении повторные запуски дали те же строки таблиц и текстовые отчёты. `integrity_check` вернул `ok`; деньги дополнительно пересчитаны по исходным ценам через Decimal.
|
||||
|
||||
## 12 ноября 2026 — SQL-аналитика и Markdown-отчёт
|
||||
| Результат | Значение |
|
||||
|---|---:|
|
||||
| Исходных записей | 1500 |
|
||||
| Принято | 1482 |
|
||||
| Отброшено | 18 |
|
||||
| Ошибки значений | 14 |
|
||||
| Точные / нормализованные дубли | 1 / 1 |
|
||||
| Конфликтующие записи | 2 |
|
||||
| Группы «дата + категория» | 438 |
|
||||
| Выручка | 1 687 705 899 копеек |
|
||||
| Строки результатов: топ / динамика / аномалии | 5 / 91 / 18 |
|
||||
|
||||
**Запрос пользователя.** Подключить три запроса к main.py, сохранить фактические результаты и пояснения в outputs/query_results.md, проверить запросы на временных базах.
|
||||
Исходный CSV сохранил SHA-256:
|
||||
`c4b9ffd2eb24c6c79b6a3e2436f3bd348ba86696a1aeb9b7e3083af65c799c67`.
|
||||
|
||||
**Решения.** Запросы читают дневную витрину. Рейтинг ограничен пятью категориями согласно плану. Динамика включает календарные пропуски и изменение общей выручки к предыдущему дню. Для аномалий календарь общий, среднее и дисперсия отдельные для каждой категории. Перед AVG вычитается минимум категории, чтобы лучше сохранять небольшие различия при большой выручке. Метод сравнивает квадрат отклонения с четырьмя дисперсиями. Все три результата получаются в одной транзакции чтения, денежные колонки отчёта выражены в копейках.
|
||||
|
||||
**Фактические проверки.** В существующей .venv прошёл 51 тест. На временных базах проверены сортировка при равной выручке, пропущенный день, рост и падение по отдельным категориям, постоянный ряд, короткий период, точная граница в два стандартных отклонения и пустой снимок. Контрольная сумма рабочей базы до и после тестов совпала.
|
||||
|
||||
**Запуск на данных проекта.** При первом запуске Windows отказала в замене clean_orders.csv после фиксации БД. После разрешённого повторного запуска python main.py завершился успешно. Для чтения созданного отчёта при проверке также потребовался доступ вне песочницы. Все строки трёх результатов сверены с Markdown. Получены 5 категорий, 91 календарный день и 18 аномальных пар «дата и категория». SHA-256 исходного CSV совпал с ранее зафиксированным.
|
||||
+498
@@ -0,0 +1,498 @@
|
||||
# Исходные промпты проекта
|
||||
|
||||
Запросы приведены в порядке их появления в чате. Пометки в квадратных скобках обозначают пропущенные команды терминала.
|
||||
|
||||
## Оглавление
|
||||
|
||||
1. [Постановка задачи и правила работы](#stage-1)
|
||||
2. [План реализации и модель данных](#stage-2)
|
||||
3. [Генерация синтетических данных](#stage-3)
|
||||
4. [Чтение и очистка заказов](#stage-4)
|
||||
5. [Проверка модулей и расширение тестов](#stage-5)
|
||||
6. [Уточнение аналитики и пути экспорта](#stage-6)
|
||||
7. [Статистика качества и экспорт](#stage-7)
|
||||
8. [Транзакционная загрузка и сборка пайплайна](#stage-8)
|
||||
9. [SQL-запросы и отчёт по выручке](#stage-9)
|
||||
10. [Финальная проверка и подготовка к публикации](#stage-10)
|
||||
11. [Сбор исходных промптов](#stage-11)
|
||||
12. [Проверка перед сдачей](#stage-12)
|
||||
|
||||
<a id="stage-1"></a>
|
||||
|
||||
## 1. Постановка задачи и правила работы
|
||||
|
||||
Ты выступаешь в роли опытного Senior Data Engineer и помогаешь мне выполнить тестовое задание на позицию Data Engineer и разобраться в принятых решениях.
|
||||
|
||||
Задание:
|
||||
Построить простой и надёжный ETL-пайплайн:
|
||||
CSV > очистка > агрегация выручки по дням и категориям > SQLite.
|
||||
|
||||
Необходимо:
|
||||
1. Обработать дубли, пропуски и разные форматы дат.
|
||||
2. Показать количество отброшенных строк и причины.
|
||||
3. Подготовить три SQL-запроса с результатами: топ категорий, динамика выручки, аномалии.
|
||||
4. Обеспечить идемпотентность: повторный запуск не дублирует данные.
|
||||
5. Подготовить README, готовую базу и лог работы с ИИ.
|
||||
Технологии:
|
||||
- Python 3.11+.
|
||||
- Стандартная библиотека: csv, sqlite3, decimal и другие необходимые модули.
|
||||
- pytest для тестов.
|
||||
- Дополнительные зависимости — только при обоснованной необходимости.
|
||||
|
||||
Общие правила:
|
||||
- Создавай и изменяй реальные файлы в рабочей папке.
|
||||
- Сначала изучай существующие файлы и применимые инструкции.
|
||||
- Не переписывай готовые части без необходимости.
|
||||
- Не создавай интерфейс, сервер, Docker и сложную архитектуру.
|
||||
- Не выполняй git commit и git push без отдельного указания.
|
||||
- Не выдумывай результаты тестов, показатели качества, ошибки ИИ и затраченное время.
|
||||
- Явно отмечай допущения и синтетическое происхождение данных.
|
||||
- Не изменяй исходный CSV при обработке.
|
||||
- Объясняй важные решения простым языком.
|
||||
- Работай только над текущим этапом, не переходи к следующему самостоятельно.
|
||||
- В конце этапа кратко сообщай: что создано, что проверено, какие ограничения остались.
|
||||
- Если запуск проверки недоступен, прямо сообщай об этом.
|
||||
|
||||
Веди docs/ai_work_log.md по реальной истории:
|
||||
- мои запросы;
|
||||
- принятые решения;
|
||||
- обнаруженные ошибки и изменения;
|
||||
- фактически выполненные проверки.
|
||||
Не придумывай историю работы.
|
||||
|
||||
main.py остаётся в корне и только объединяет этапы.
|
||||
Необходимые функции размещаются в src/.
|
||||
Пути к ресурсам определяются относительно корня проекта, а не текущей рабочей папки.
|
||||
|
||||
<a id="stage-2"></a>
|
||||
|
||||
## 2. План реализации и модель данных
|
||||
|
||||
Изучи рабочую папку и подготовь краткий план реализации без написания кода пайплайна.
|
||||
|
||||
Зафиксируй модель данных:
|
||||
- Одна строка — один заказ с одним товаром.
|
||||
- order_id — положительное целое число.
|
||||
- order_date — дата заказа.
|
||||
- category — категория товара.
|
||||
- quantity — положительное целое число.
|
||||
- unit_price — цена единицы в рублях.
|
||||
- Выручка = quantity × unit_price.
|
||||
- Все заказы завершены.
|
||||
- Возвраты, скидки, бесплатные товары и несколько валют не рассматриваются.
|
||||
|
||||
Правила обработки:
|
||||
1. Все поля обязательны, кроме category.
|
||||
2. Пустую category заменять на «Не указана».
|
||||
3. Категории очищать от внешних и повторяющихся пробелов, приводить к единому регистру.
|
||||
4. Даты принимать только в форматах YYYY-MM-DD и DD.MM.YYYY.
|
||||
5. Итоговый формат даты — YYYY-MM-DD.
|
||||
6. quantity должна быть целой и строго положительной.
|
||||
7. unit_price должна быть строго положительной.
|
||||
8. Цену разбирать через Decimal, разрешая точку или запятую как десятичный разделитель, без разделителей тысяч.
|
||||
9. Цены с более чем двумя знаками после разделителя отклонять.
|
||||
10. NaN, Infinity и другие неконечные числовые значения отклонять.
|
||||
11. Деньги хранить и суммировать целым числом копеек.
|
||||
12. Значения должны помещаться в целые числа SQLite, включая рассчитанную выручку.
|
||||
|
||||
Порядок обработки дублей:
|
||||
- Сначала удалять точные дубли значений исходных полей, оставляя первое вхождение.
|
||||
- Затем нормализовать и проверить оставшиеся записи.
|
||||
- Среди валидных записей одинаковые ID с одинаковыми нормализованными значениями считать дублями.
|
||||
- Одинаковые ID с разными нормализованными значениями считать конфликтом и отклонять все записи такой группы.
|
||||
- Невалидные записи не участвуют в поиске конфликтов среди валидных.
|
||||
- Все эти правила явно описать как принятые решения.
|
||||
|
||||
Для каждой исходной записи сохранять номер записи в CSV.
|
||||
Не путать номер записи с физической строкой файла: CSV может содержать многострочные поля.
|
||||
|
||||
Предложи простые интерфейсы функций между модулями.
|
||||
Выбери одно место для расчёта агрегатов.
|
||||
Для SQLite используем полную перезагрузку обеих таблиц в одной транзакции.
|
||||
|
||||
Опиши критерии готовности и возможные неоднозначности.
|
||||
Измени docs/ai_work_log.md с фактическими решениями.
|
||||
|
||||
<a id="stage-3"></a>
|
||||
|
||||
## 3. Генерация синтетических данных
|
||||
|
||||
Реализуй src/generate_data.py.
|
||||
|
||||
Требования:
|
||||
- Создать data/raw_orders.csv.
|
||||
- Ровно 1500 записей без учёта заголовка, включая дубли и ошибочные записи.
|
||||
- Поля: order_id, order_date, category, quantity, unit_price.
|
||||
- Использовать локальный генератор случайных чисел с seed=42.
|
||||
- Использовать фиксированный диапазон дат.
|
||||
- Не использовать текущую дату или случайный порядок, зависящий от окружения.
|
||||
- Повторный запуск должен создавать идентичное содержимое CSV.
|
||||
- Большая часть записей должна быть корректной.
|
||||
|
||||
Гарантированно добавить:
|
||||
- точные дубли;
|
||||
- одинаковые заказы с разными допустимыми форматами даты;
|
||||
- конфликтующие order_id;
|
||||
- пропуски в разных полях;
|
||||
- некорректные даты;
|
||||
- пробелы и различный регистр категорий;
|
||||
- дробные, нулевые, отрицательные и нечисловые значения quantity;
|
||||
- нулевые, отрицательные и нечисловые цены;
|
||||
- цены с лишними десятичными знаками.
|
||||
|
||||
Использовать синтетические данные без персональной информации.
|
||||
Не подгонять данные под красивые аналитические результаты.
|
||||
|
||||
Команда запуска:
|
||||
[Команда терминала опущена.]
|
||||
|
||||
Добавь тесты количества записей и воспроизводимости.
|
||||
Тесты должны использовать временные файлы.
|
||||
|
||||
Запусти генератор и тесты. Сообщай только фактические результаты.
|
||||
Обнови лог работы с ИИ.
|
||||
|
||||
<a id="stage-4"></a>
|
||||
|
||||
## 4. Чтение и очистка заказов
|
||||
|
||||
Реализуй src/extract.py и src/transform.py по согласованным правилам.
|
||||
|
||||
extract.py:
|
||||
- чтение CSV;
|
||||
- проверка обязательных заголовков;
|
||||
- проверка количества полей в записях;
|
||||
- присвоение номера исходной записи;
|
||||
- понятные сообщения о проблемах файла.
|
||||
|
||||
Отсутствующий файл, неверные заголовки и повреждённая структура CSV — критические ошибки.
|
||||
Ошибочные значения отдельных записей — причины отбраковки.
|
||||
Полностью пустую запись внутри данных не игнорировать молча.
|
||||
|
||||
transform.py:
|
||||
- нормализация категорий и дат;
|
||||
- проверка обязательных значений;
|
||||
- проверка числовых полей;
|
||||
- обработка точных и нормализованных дублей;
|
||||
- обработка конфликтующих ID;
|
||||
- расчёт unit_price_kopecks и revenue_kopecks.
|
||||
|
||||
Не используй float для денежных расчётов.
|
||||
Не исправляй неизвестные значения догадками.
|
||||
Не округляй некорректные цены молча.
|
||||
|
||||
Результат:
|
||||
1. Принятые записи:
|
||||
order_id, order_date, category, quantity,
|
||||
unit_price_kopecks, revenue_kopecks.
|
||||
2. Отброшенные записи:
|
||||
номер исходной записи, исходные значения и список причин.
|
||||
|
||||
Каждая исходная запись получает ровно один итоговый статус.
|
||||
Удалённые дубли также считаются отброшенными.
|
||||
Одна отклонённая запись может иметь несколько ошибок полей.
|
||||
Не приписывай ей проверки, которые не выполнялись после более раннего исключения.
|
||||
|
||||
Добавь тесты:
|
||||
- допустимые и некорректные даты;
|
||||
- отсутствующие поля;
|
||||
- пустая категория;
|
||||
- точный дубль;
|
||||
- дубль после нормализации;
|
||||
- конфликт ID;
|
||||
- невалидная запись с ID валидного заказа;
|
||||
- дробное количество;
|
||||
- точный расчёт денег;
|
||||
- неконечные и слишком большие числа;
|
||||
- несколько ошибок в одной записи;
|
||||
- пустой CSV с корректным заголовком.
|
||||
|
||||
Проверь, что исходный файл не изменяется.
|
||||
Запусти тесты и обнови лог.
|
||||
|
||||
<a id="stage-5"></a>
|
||||
|
||||
## 5. Проверка модулей и расширение тестов
|
||||
|
||||
Посмотри модули в src, тесты, план реализации и журнал работы с ИИ. Сделай точечные улучшения, без переписывания проекта и переименований ради стиля. SQLite и аналитику пока не реализуй.
|
||||
|
||||
Что нужно:
|
||||
- Дополнить тесты генератора: проверить, что все запланированные дубли, конфликты, пропуски и неверные значения действительно есть в данных.
|
||||
- Проверить чтение CSV: неверную UTF-8, ошибку доступа, многострочные поля и правильную нумерацию записей.
|
||||
- Проверить очистку: точность денег, порядок обработки дублей и конфликтов, несколько причин ошибок, баланс и порядок записей.
|
||||
- Убрать дублирование списка полей CSV простым способом, без лишних модулей.
|
||||
- Уточнить план: добавить clean_orders.csv, несколько причин отбраковки, дни с нулевой выручкой и поиск аномалий по отклонению более чем на два стандартных отклонения. При числе дней меньше 7 или нулевой дисперсии аномалии не выдавать.
|
||||
|
||||
Не меняй рабочую логику без необходимости. Если найдёшь баг, сначала воспроизведи его тестом. Недостаток тестов сам по себе не называй ошибкой реализации.
|
||||
|
||||
Запусти тесты через существующую .venv, проверь, что raw_orders.csv не изменился, и обнови журнал фактическими результатами. Кратко перечисли изменения, результаты проверок и оставшиеся проблемы.
|
||||
|
||||
Коммит и push не делай.
|
||||
|
||||
<a id="stage-6"></a>
|
||||
|
||||
## 6. Уточнение аналитики и пути экспорта
|
||||
|
||||
Уточни план реализации и журнал работы с ИИ: аномалии будем искать отдельно по каждой категории, а динамику показывать по общей дневной выручке.
|
||||
|
||||
Также исправь путь очищенного CSV на outputs/clean_orders.csv.
|
||||
|
||||
В журнале зафиксируй текущее уточнение, не переписывая историю. Код пока не изменяй, коммит и push не делай.
|
||||
|
||||
<a id="stage-7"></a>
|
||||
|
||||
## 7. Статистика качества и экспорт
|
||||
|
||||
Реализуй src/quality.py: формирование статистики и сохранение CSV/JSON.
|
||||
|
||||
Создаваемые файлы:
|
||||
|
||||
1. outputs/clean_orders.csv
|
||||
Поля:
|
||||
order_id, order_date, category, quantity,
|
||||
unit_price_kopecks, revenue_kopecks.
|
||||
|
||||
2. outputs/rejected_rows.csv
|
||||
Номер исходной записи, исходные значения и причины отбраковки.
|
||||
Причины сохранять в однозначном формате.
|
||||
|
||||
3. outputs/quality_report.json
|
||||
- число исходных записей;
|
||||
- число принятых;
|
||||
- число отброшенных;
|
||||
- разбивка по итоговым причинам отбраковки;
|
||||
- счётчики отдельных обнаруженных проблем;
|
||||
- доля принятых записей.
|
||||
|
||||
Обязательно:
|
||||
- исходные = принятые + отброшенные;
|
||||
- каждая запись учитывается один раз в итоговых количествах;
|
||||
- счётчики проблем могут пересекаться — явно поясни это;
|
||||
- при пустом входном наборе долю принятых укажи как null;
|
||||
- статистика получается из реальных результатов обработки.
|
||||
|
||||
CSV сохраняй в utf-8-sig для корректного отображения кириллицы в Excel.
|
||||
Порядок записей и причин должен быть детерминированным.
|
||||
При повторном запуске файлы перезаписываются.
|
||||
Пустые CSV должны содержать заголовки.
|
||||
|
||||
Модуль не должен повторно очищать данные.
|
||||
Предусмотри вызов сохранения файлов после успешной загрузки БД.
|
||||
|
||||
Добавь необходимые проверки статистики и экспорта к существующим тестам.
|
||||
Запусти их и обнови лог.
|
||||
|
||||
<a id="stage-8"></a>
|
||||
|
||||
## 8. Транзакционная загрузка и сборка пайплайна
|
||||
|
||||
Реализуй sql/schema.sql, src/database.py и main.py.
|
||||
|
||||
База: outputs/orders.db.
|
||||
|
||||
Таблица orders:
|
||||
- order_id;
|
||||
- order_date;
|
||||
- category;
|
||||
- quantity;
|
||||
- unit_price_kopecks;
|
||||
- revenue_kopecks.
|
||||
|
||||
Таблица daily_category_revenue:
|
||||
- order_date;
|
||||
- category;
|
||||
- order_count;
|
||||
- revenue_kopecks.
|
||||
|
||||
Требования:
|
||||
- первичный ключ order_id для orders;
|
||||
- составной ключ «дата + категория» для агрегатов;
|
||||
- NOT NULL и CHECK для важных инвариантов;
|
||||
- значения в SQL передавать параметрами;
|
||||
- очищенные заказы и агрегаты полностью перезагружать в одной транзакции;
|
||||
- при ошибке сохранять предыдущее содержимое обеих таблиц;
|
||||
- корректно обрабатывать пустой набор принятых записей;
|
||||
- агрегацию выполнять только в одном месте.
|
||||
|
||||
main.py должен быть коротким и вызывать функции модулей.
|
||||
|
||||
Команда:
|
||||
[Команда терминала опущена.]
|
||||
|
||||
Последовательность:
|
||||
1. Чтение CSV.
|
||||
2. Очистка и формирование статистики.
|
||||
3. Транзакционная запись заказов и агрегатов.
|
||||
4. Сохранение clean_orders.csv, rejected_rows.csv и quality_report.json.
|
||||
5. После следующего этапа — выполнение аналитических запросов и сохранение результатов.
|
||||
|
||||
При критической ошибке выводить понятное сообщение и завершаться с ненулевым кодом.
|
||||
Не сообщать об успехе до завершения всех операций.
|
||||
Не скрывать неожиданные исключения общим сообщением без диагностических деталей.
|
||||
|
||||
SQLite и отчёты не имеют общей транзакции.
|
||||
Если запись файлов не удалась после обновления БД, явно сообщать об этом.
|
||||
|
||||
Добавь интеграционные тесты:
|
||||
- полный запуск;
|
||||
- повторный запуск даёт одинаковое содержимое обеих таблиц;
|
||||
- агрегаты совпадают с заказами;
|
||||
- clean_orders.csv совпадает с orders;
|
||||
- сбой во время загрузки откатывает изменения;
|
||||
- неверный входной файл не меняет существующую базу.
|
||||
|
||||
Сравнивай данные таблиц, а не байты файла SQLite.
|
||||
Все тесты выполняй во временных каталогах.
|
||||
Запусти проверки и обнови лог.
|
||||
|
||||
<a id="stage-9"></a>
|
||||
|
||||
## 9. SQL-запросы и отчёт по выручке
|
||||
|
||||
Реализуй три SQL-запроса и подключи их выполнение к main.py.
|
||||
Не добавляй отдельный модуль, если достаточно небольшой функции в database.py.
|
||||
|
||||
1. sql/top_categories.sql
|
||||
Категория, число заказов, общая выручка.
|
||||
Сортировка по убыванию выручки и затем по категории.
|
||||
|
||||
2. sql/daily_revenue.sql
|
||||
Выручка по дням.
|
||||
Включить все дни между минимальной и максимальной датой принятых заказов.
|
||||
Дни без заказов показывать с нулём.
|
||||
Сортировка по дате.
|
||||
|
||||
3. sql/anomalies.sql
|
||||
Аномалии дневной выручки на том же календарном диапазоне.
|
||||
|
||||
Метод:
|
||||
- отклонение от среднего более чем на два стандартных отклонения;
|
||||
- дисперсия генеральной совокупности;
|
||||
- рассчитать среднее и затем средний квадрат отклонения через AVG;
|
||||
- сравнивать квадрат отклонения с четырьмя дисперсиями;
|
||||
- не использовать STDDEV и SQRT;
|
||||
- при количестве дней меньше 7 или нулевой дисперсии аномалии не выдавать.
|
||||
|
||||
Используй SQL стандартной SQLite и CTE для читаемости.
|
||||
Для пустой базы запросы должны возвращать пустой результат.
|
||||
|
||||
Денежные суммы в результатах SQL оставляй целыми копейками.
|
||||
При представлении в Markdown можно выводить рубли с двумя знаками через Decimal.
|
||||
|
||||
После [команда терминала опущена] должен появляться outputs/query_results.md:
|
||||
- краткое описание запросов;
|
||||
- фактические результаты;
|
||||
- единицы измерения;
|
||||
- пояснение метода аномалий.
|
||||
|
||||
Если аномалий нет, прямо укажи это.
|
||||
Не изменяй данные ради получения аномалий.
|
||||
|
||||
Объясни, что аномалия — сигнал для проверки, а не доказанная ошибка.
|
||||
Укажи ограничения: короткая выборка, влияние выбросов и отсутствие учёта сезонности.
|
||||
Нулевые дни внутри диапазона считаем днями без заказов — это допущение, а не подтверждение полноты исходных данных.
|
||||
|
||||
Добавь тесты запросов на маленьких контрольных наборах с известными результатами.
|
||||
Проверь явный выброс, постоянную выручку, пропущенный день и пустую базу.
|
||||
Не изменяй итоговую базу во время тестов.
|
||||
|
||||
Запусти проверки и обнови лог.
|
||||
|
||||
<a id="stage-10"></a>
|
||||
|
||||
## 10. Финальная проверка и подготовка к публикации
|
||||
|
||||
Проведи финальную проверку проекта и подготовь его к ручной публикации.
|
||||
|
||||
README.md должен содержать:
|
||||
1. Назначение проекта.
|
||||
2. Указание, что данные синтетические.
|
||||
3. Быстрый запуск в Windows PowerShell:
|
||||
создание виртуального окружения, установка pytest,
|
||||
генерация данных, запуск пайплайна, запуск тестов.
|
||||
4. Структуру проекта и назначение модулей.
|
||||
5. Этапы обработки.
|
||||
6. Правила очистки, дублей и конфликтов.
|
||||
7. Схему таблиц и единицы денежных значений.
|
||||
8. Фактические результаты качества.
|
||||
9. Описание SQL-запросов и ссылку на результаты.
|
||||
10. Механизм идемпотентности.
|
||||
11. Ограничения и допущения.
|
||||
|
||||
Проверь наличие артефактов:
|
||||
- data/raw_orders.csv;
|
||||
- outputs/clean_orders.csv;
|
||||
- outputs/rejected_rows.csv;
|
||||
- outputs/quality_report.json;
|
||||
- outputs/orders.db;
|
||||
- outputs/query_results.md;
|
||||
- docs/ai_work_log.md.
|
||||
|
||||
Исходные синтетические данные и готовые артефакты включаем в репозиторий.
|
||||
В .gitignore исключаем виртуальное окружение, кэши, секреты и временные файлы.
|
||||
Не исключай готовую SQLite-базу общим правилом *.db.
|
||||
|
||||
Проверь:
|
||||
- генератор воспроизводим;
|
||||
- исходный CSV не изменяется при обработке;
|
||||
- баланс строк сходится;
|
||||
- деньги считаются точно;
|
||||
- CSV и база содержат одинаковые очищенные заказы;
|
||||
- агрегаты соответствуют заказам;
|
||||
- повторный запуск не меняет данные;
|
||||
- SQL выполняется;
|
||||
- инструкция запуска соответствует реализации.
|
||||
|
||||
Запусти полный набор тестов и финальный пайплайн.
|
||||
Проверку чистого окружения выполни, если среда позволяет; иначе явно укажи, что она не проводилась.
|
||||
|
||||
Обнови лог ИИ по фактической истории. Не придумывай ошибки и исправления.
|
||||
Не создавай коммиты и не выполняй push.
|
||||
|
||||
В финале кратко сообщи:
|
||||
- что создано;
|
||||
- что фактически проверено;
|
||||
- результаты обработки и тестов;
|
||||
- что осталось незавершённым;
|
||||
|
||||
<a id="stage-11"></a>
|
||||
|
||||
## 11. Сбор исходных промптов
|
||||
|
||||
Создай docs/prompts.md с исходными промптами, которые я использовал при работе над проектом.
|
||||
|
||||
Бери тексты из доступной истории чата. Сохраняй формулировки, разбей по этапам и добавь оглавление. Не включай ответы ИИ и команды терминала.
|
||||
|
||||
Если полный текст запроса недоступен, не восстанавливай его по догадкам или журналу. Укажи, что оригинал не сохранился; краткое изложение явно пометь как пересказ.
|
||||
|
||||
В docs/ai_work_log.md добавь ссылку на prompts.md. Остальную историю, код и результаты проверок не меняй. Коммит и push не делай.
|
||||
|
||||
<a id="stage-12"></a>
|
||||
|
||||
## 12. Проверка перед сдачей
|
||||
|
||||
Проведи финальную подготовку проекта к сдаче по заданию Data Engineer.
|
||||
|
||||
Проверь, что на месте и согласованы:
|
||||
- код загрузки, очистки, агрегации и записи в SQLite;
|
||||
- исходный CSV, очищенные данные, отбраковка и отчёт качества;
|
||||
- готовая база;
|
||||
- три SQL-запроса и фактические результаты;
|
||||
- README, журнал ИИ и исходные промпты.
|
||||
|
||||
Не расширяй функциональность и не переименовывай файлы ради стиля.
|
||||
Если найдёшь ошибку, сначала воспроизведи её, затем исправь минимально.
|
||||
|
||||
Запусти тесты и проверь повторный запуск пайплайна. Убедись, что исходный CSV не изменился, данные не дублируются, суммы заказов и агрегатов совпадают, а clean_orders.csv соответствует базе.
|
||||
|
||||
В README добавь фактический результат тестов и проверенные версии Python, SQLite и pytest. Проверь команды запуска и ссылки. Кратко укажи ограничения, включая раздельное обновление базы и отчётов и особенности поиска аномалий.
|
||||
|
||||
Проверь доступность результатов для обычного пользователя Windows.
|
||||
|
||||
Обнови журнал только реальными действиями.
|
||||
|
||||
В конце сообщи:
|
||||
- что исправлено;
|
||||
- что проверено и с каким результатом;
|
||||
|
||||
|
||||
Reference in new issue
Block a user