diff --git a/backend/db/crud.py b/backend/db/crud.py index 02e961e8a97bbe1af0c2a9734783385082a23e39..dcb87c4b2e987b439793784cc8580013a7d6a972 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 4418ddd55a6baa196343a5a2a92ae8361e5ac89c..7b7b8991f5002d321dde4277dbb79e49c68192e0 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