### Предлагается реализовать веб-сервис для обработки данных. ### Контекст задачи: - у нас есть пользователи от которых мы получаем некоторые данные - мы получаем данные каждый день, таким образом каждая точка данных соответствует некоторой дате - в рамках этой задачи будем считать что все данные имеют тип float - в результате сбора данных мы имеем массивы вида [{"date": ..., "value": ...}, {"date": ..., "value": ...}, ...] - видов (например шаги, средняя частота пульса и тп) данных может быть много, в рамках этой задачи будем считать, что они однозначно различаются по строковому названию (см. примеры запросов к АПИ ниже) - как данные попадают к нам и как они технически храняться - за рамками данной задачи ### ТЗ выглядит следующим образом: - Реализовать HTTP веб-сервис. Сервис должен предоставлять HTTP API с помощью которого можно посчитать корреляцию по Пирсону между 2 векторами данных разных типов - При расчете корреляции требуется сопоставить потоки между собой с учетом дат, то есть мы "сравниваем" два показателя за одну и ту же дату, а не как попало - Полученные результаты должны сохраняться в базу данных. - Данные сохраненные в БД также должны быть впоследствии доступны в через API. ### API - **POST /calculate** - вычисляет и сохраняет в БД метрику Принимает входные данные в JSON-формате: ``` { "user_id": int, "data": { "x_data_type": str, "y_data_type": str, "x": [ { "date": YYYY-MM-DD, "value": float, }, ... ], "y": [ { "date": YYYY-MM-DD, "value": float, }, ... ] } } ``` - **GET /correlation?x_data_type=str&y_data_type=str&user_id=int** - Отдает посчитанную метрику для конкретного пользователя и конкретных типов данных - Если для данной комбинации рассчитанных данных нет - возвращает 404 Формат ответа в случае HTTP 200: ``` { "user_id": int, "x_data_type": str, "y_data_type": str, "correlation": { "value": float, "p_value": float, } } ``` ### Необходимые допущения при реализации - данные могут быть кривые - пропуски, неверный тип и тд (к сожалению реальный мир жесток и враждебен :)) - для одной комбинации пользователь - тип данных A - тип данных Б может быть несколько расчетов, в таком случае просто обновляем метрику на основе последнего расчета, с версиями заморачиваться не нужно, все таки задача тестовая ### Минимальные требования: - язык Python (HTTP фреймворк любой, обоснованный выбор - плюс вам) - PEP8 - данные хранятся персистентно в рамках сервиса (БД любая, обоснованный выбор - плюс вам) - сборка через docker compose: отдельно БД, отдельно сервис - наличие README.md с минимально необходимыми инструкциями для запуска сервиса в Docker - результат - это ссылка на github репозиторий ### Будет совсем хорошо если: - расчет производится в фоновых процессах через очереди (не блокирует АПИ) - все это дело покрыто тестами - есть авторизация через токены ### Если что-то неочевидно / непонятно: - руководствуйтесь здравым смыслом - если вы что-то сделаете по-своему (на основании собственных допущений), но, опять же, это будет обоснованно и логично - это не минус, это часто наоборот плюс - если необходимо, можно написать нашему рекрутеру Дарье в Telegram - @mentafres ### Пример входных данных для /calculate ```json { "user_id": 42, "data": { "x_data_type": "sleep_hours", "y_data_type": "morning_pulse", "x": [ { "date": "2022-01-14", "value": 9.7 }, { "date": "2022-01-08", "value": 9.0 }, { "date": "2022-02-01", "value": 6.5 }, { "date": "2022-01-11", "value": 8.6 }, { "date": "2022-01-25", "value": 6.0 }, { "date": "2022-01-04", "value": 9.9 }, { "date": "2022-01-27", "value": 5.2 }, { "date": "2022-01-03", "value": 5.3 }, { "date": "2022-01-02", "value": 7.7 }, { "date": "2022-01-19", "value": 6.0 }, { "date": "2022-01-12", "value": 6.4 }, { "date": "2022-01-26", "value": 5.2 }, { "date": "2022-01-18", "value": 5.6 }, { "date": "2022-01-16", "value": 9.0 }, { "date": "2022-01-23", "value": 5.4 }, { "date": "2022-01-09", "value": 5.6 }, { "date": "2022-01-06", "value": 6.9 }, { "date": "2022-01-17", "value": 9.3 }, { "date": "2022-01-15", "value": 9.1 }, { "date": "2022-01-13", "value": 7.3 } ], "y": [ { "date": "2022-01-16", "value": 96 }, { "date": "2022-01-31", "value": 77 }, { "date": "2022-01-01", "value": 45 }, { "date": "2022-01-05", "value": 60 }, { "date": "2022-01-08", "value": 47 }, { "date": "2022-02-01", "value": 97 }, { "date": "2022-01-26", "value": 93 }, { "date": "2022-01-23", "value": 68 }, { "date": "2022-01-13", "value": 49 }, { "date": "2022-01-06", "value": 44 }, { "date": "2022-01-29", "value": 75 }, { "date": "2022-01-10", "value": 88 }, { "date": "2022-01-20", "value": 54 }, { "date": "2022-01-11", "value": 82 }, { "date": "2022-01-27", "value": 62 }, { "date": "2022-01-19", "value": 57 }, { "date": "2022-01-18", "value": 82 }, { "date": "2022-01-17", "value": 65 }, { "date": "2022-01-03", "value": 64 }, { "date": "2022-01-28", "value": 50 } ] } } ```