From aa575cf4f6a9ea7c171fd69fc4a300f569b5496f Mon Sep 17 00:00:00 2001 From: Aymeric Chaumont <aymeric.chaumont@student-cs.fr> Date: Wed, 6 Jul 2022 14:17:54 +0200 Subject: [PATCH] add route to get waiting time stats --- backend/db/crud.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++ backend/main.py | 7 ++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/backend/db/crud.py b/backend/db/crud.py index 02e961e..dcb87c4 100644 --- a/backend/db/crud.py +++ b/backend/db/crud.py @@ -1,7 +1,11 @@ """ Module to interact with the database """ +from datetime import date, datetime, time, timedelta +from numpy import average from sqlalchemy.orm import Session +from sqlalchemy.sql import func + from db import models, schemas @@ -24,3 +28,47 @@ def get_waiting_time(place: str, db: Session): """ Get the last estimated waiting time for the given place """ db_record = db.query(models.Records).filter(models.Records.place == place).order_by(models.Records.date.desc()).one() return db_record.waiting_time + + +def get_stats(place: str, weekday: int, min_time: time, max_time: time, interval: timedelta, db: Session): + """ Get the average waiting time for each interval between two time steps """ + + def shift_time(t: time, delta: timedelta): + return (datetime.combine(date(1, 1, 1), t) + delta).time() + + def avg_time_query(start_time, end_time): + records = db.query( + (func.round( + func.avg( + 3600 * func.extract('HOUR', models.Records.waiting_time) + + 60 * func.extract('MINUTE', models.Records.waiting_time) + + func.extract('SECOND', models.Records.waiting_time)) + )) / 60 + ).filter( + models.Records.place == place, + func.weekday(models.Records.date) == weekday, + (func.extract('HOUR', models.Records.date) > start_time.hour) | + ((func.extract('HOUR', models.Records.date) == start_time.hour) & + (func.extract('MINUTE', models.Records.date) >= start_time.minute)), + (func.extract('HOUR', models.Records.date) < end_time.hour) | + ((func.extract('HOUR', models.Records.date) == end_time.hour) & + (func.extract('MINUTE', models.Records.date) < end_time.minute)), + ).one() + if records[0]: + return int(records[0]) + return None + + def add_slot(dic, start_time, end_time): + average_waiting_time = avg_time_query(start_time, end_time) + if average_waiting_time: + key = f'{start_time.hour:02}-{start_time.minute:02}-{end_time.hour:02}-{end_time.minute:02}' + dic[key] = average_waiting_time + + + stats = {} + start_time, end_time = min_time, shift_time(min_time, interval) + while start_time < max_time: + add_slot(stats, start_time, end_time) + start_time, end_time = end_time, shift_time(end_time, interval) + + return stats diff --git a/backend/main.py b/backend/main.py index 4418ddd..7b7b899 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1,4 +1,4 @@ -from datetime import timedelta +from datetime import datetime, time, timedelta from typing import List from fastapi import Body, Depends, FastAPI from fastapi.middleware.cors import CORSMiddleware @@ -57,6 +57,11 @@ async def waiting_time(place: str, db: Session = Depends(get_db)): return crud.get_waiting_time(place, db) +@app.get('/api/{place}/stats/{day}/{start_time}/{end_time}/{interval}', response_model=int) +async def stats(place: str, day: int, start_time: time, end_time: time, interval: timedelta, db: Session = Depends(get_db)): + return crud.get_stats(place, day, start_time, end_time, interval, db) + + """ import cv2 import numpy as np -- GitLab