Commit ff391d73 authored by Ludovico's avatar Ludovico

Immediate time computation, first version

parent 797887c0
from django.db import models
from saclaze_back.models import *
import datetime
from django.utils import timezone
class WaitingTimeNow():
# Parameters
historical_estimates_weight = 0.4 # How important previous estimations are (see waitingtimefactory.py)
estimation_decay_rate = 0.85 # Observations get less relevant with each passing minute
anomalous_value_threshold = 10.0 # Observations within this factor of the median are retained
def minutes_difference(self, now, my_date_time):
time_diff = now - my_date_time
if time_diff.days == 0:
minutes_diff = time_diff.seconds//60
else:
minutes_diff = 86400
return minutes_diff
def compute_waiting_time(self, location):
"""
Returns "real-time" estimation for a given place's waiting time
:param location:
:return:
"""
now = datetime.datetime.now() # TODO: properly account for timezone here
observed_times = ObservedWaitingTime.objects.filter(day_of_the_week=now.weekday(), location=location)
observation_data = [[x.waiting_time.seconds,
self.minutes_difference(now, x.timestamp.replace(tzinfo=None))] for x in observed_times]
# Removing data older than 20 minutes
observation_data = [x for x in observation_data if x[1] <= 20]
observation_data = sorted(observation_data)
# Computing median
l = len(observation_data)
if l % 2 == 0 and l > 1:
median_time = observation_data[l//2][0]/2+observation_data[l//2+1][0]/2
else:
median_time = observation_data[l//2][0]
# Removing extreme values
observation_data = [x for x in observation_data if median_time * self.anomalous_value_threshold >
x[0] > median_time / self.anomalous_value_threshold]
immediate_average = sum([x[0] for x in observation_data])
immediate_weights = sum([x[1] for x in observation_data])
immediate_average /= immediate_weights
print(f"Average of immediate waiting times: {immediate_average}")
now_minus_ten_minutes = now - timedelta(minutes=10)
historical_time = EstimatedWaitingTime.objects.filter(location=location, time__gte=now_minus_ten_minutes,
time__lte=now, day_of_the_week=now.weekday())[0]
print(f"Average of historical waiting times: {historical_time.waiting_time.seconds}")
if len(observation_data)>0:
global_average = \
(1-self.historical_estimates_weight)*immediate_average + \
self.historical_estimates_weight*historical_time.waiting_time.seconds
else: # No valid observations, fallback
global_average = historical_time.waiting_time.seconds
return global_average
from saclaze_back.models import *
import saclaze_back.waitingtimenow
def test():
wtn = saclaze_back.waitingtimenow.WaitingTimeNow()
location = Location.objects.get(id=1)
print(wtn.compute_waiting_time(location))
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment