diff --git a/apps/wei/forms/surveys/base.py b/apps/wei/forms/surveys/base.py index 030f9078..d7fb79b2 100644 --- a/apps/wei/forms/surveys/base.py +++ b/apps/wei/forms/surveys/base.py @@ -50,15 +50,19 @@ class WEIBusInformation: self.bus.information = d self.bus.save() - def free_seats(self, surveys: List["WEISurvey"] = None): - size = self.bus.size - already_occupied = WEIMembership.objects.filter(bus=self.bus).count() + def free_seats(self, surveys: List["WEISurvey"] = None, quotas=None): + if not quotas: + size = self.bus.size + already_occupied = WEIMembership.objects.filter(bus=self.bus).count() + quotas = {self.bus: size - already_occupied} + + quota = quotas[self.bus] valid_surveys = sum(1 for survey in surveys if survey.information.valid and survey.information.get_selected_bus() == self.bus) if surveys else 0 - return size - already_occupied - valid_surveys + return quota - valid_surveys - def has_free_seats(self, surveys=None): - return self.free_seats(surveys) > 0 + def has_free_seats(self, surveys=None, quotas=None): + return self.free_seats(surveys, quotas) > 0 class WEISurveyAlgorithm: @@ -86,14 +90,20 @@ class WEISurveyAlgorithm: """ Queryset of all first year registrations """ - return WEIRegistration.objects.filter(wei__year=cls.get_survey_class().get_year(), first_year=True) + if not hasattr(cls, '_registrations'): + cls._registrations = WEIRegistration.objects.filter(wei__year=cls.get_survey_class().get_year(), + first_year=True).all() + + return cls._registrations @classmethod def get_buses(cls) -> QuerySet: """ Queryset of all buses of the associated wei. """ - return Bus.objects.filter(wei__year=cls.get_survey_class().get_year(), size__gt=0) + if not hasattr(cls, '_buses'): + cls._buses = Bus.objects.filter(wei__year=cls.get_survey_class().get_year(), size__gt=0).all() + return cls._buses @classmethod def get_bus_information(cls, bus): @@ -135,7 +145,10 @@ class WEISurvey: """ The WEI associated to this kind of survey. """ - return WEIClub.objects.get(year=cls.get_year()) + if not hasattr(cls, '_wei'): + cls._wei = WEIClub.objects.get(year=cls.get_year()) + + return cls._wei @classmethod def get_survey_information_class(cls): diff --git a/apps/wei/forms/surveys/wei2021.py b/apps/wei/forms/surveys/wei2021.py index 24538045..a9205a3f 100644 --- a/apps/wei/forms/surveys/wei2021.py +++ b/apps/wei/forms/surveys/wei2021.py @@ -1,6 +1,8 @@ # Copyright (C) 2018-2021 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later + import time +from functools import lru_cache from random import Random from django import forms @@ -135,15 +137,18 @@ class WEISurvey2021(WEISurvey): """ return self.information.step == 20 + @lru_cache() def score(self, bus): if not self.is_complete(): raise ValueError("Survey is not ended, can't calculate score") bus_info = self.get_algorithm_class().get_bus_information(bus) return sum(bus_info.scores[getattr(self.information, 'word' + str(i))] for i in range(1, 21)) / 20 + @lru_cache() def scores_per_bus(self): return {bus: self.score(bus) for bus in self.get_algorithm_class().get_buses()} + @lru_cache() def ordered_buses(self): values = list(self.scores_per_bus().items()) values.sort(key=lambda item: -item[1])