From 80de63ab73ee542f93f82ddc001637efb26d5647 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 25 Nov 2020 04:45:23 +0100 Subject: [PATCH 1/3] =?UTF-8?q?P=C5=99eps=C3=A1ny=20tituly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 99 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 17 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 57a44404..3f654247 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -309,25 +309,90 @@ class Resitel(SeminarModelBase): return sum(h.body for h in list(vsechna_hodnoceni)) - def get_titul(self, celkove_body=None): - "Vrati titul" - if celkove_body is None: - celkove_body = self.vsechny_body() + def get_titul(self, body=None): + "Vrati titul jako řetězec." + + # Nejprve si zadefinujeme titul + from enum import Enum + from functools import total_ordering + @total_ordering + class Titul(Enum): + """ Třída reprezentující možné tituly. Hodnoty jsou dvojice (dolní hranice, stringifikace). """ + nic = (0, '') + bc = (20, 'Bc.') + mgr = (50, 'Mgr.') + dr = (100, 'Dr.') + doc = (200, 'Doc.') + prof = (500, 'Prof.') + akad = (1000, 'Akad.') + + def __lt__(self, other): + return True if self.value[0] < other.value[0] else False + def __eq__(self, other): # Měla by být implicitní, ale klidně explicitně. + return True if self.value[0] == other.value[0] else False + + def __str__(self): + return self.value[1] + + @classmethod + def z_bodu(cls, body): + aktualni = cls.nic + # TODO: ověřit, že to funguje + for titul in cls: # Kdyžtak použít __members__.items() + if titul.value[0] <= body: + aktualni = titul + else: + break + return aktualni + + # Titul pro 26. ročník + stary_titul = None + if body is None: + # Hledáme body v databázi + # V listopadu 2020 jsme se na filosofické schůzce shodli o změně hranic titulů: + # - body z 25. ročníku a dříve byly shledány dvakrát hodnotnějšími + # - proto se započítávají dvojnásobně a byly posunuté hranice titulů + # - staré tituly se ale nemají odebrat, pokud řešitel v t.č. minulém (26.) ročníku měl titul, má ho mít pořád. + hodnoceni_do_25_rocniku = Hodnoceni.objects.filter(cislo_body__rocnik__rocnik__lte=25,reseni__in=self.reseni_set.all()) + novejsi_hodnoceni = Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()).difference(hodnoceni_do_25_rocniku) + + def body_z_hodnoceni(hh : list): + return sum(h.body for h in hh) + + stare_body = body_z_hodnoceni(hodnoceni_do_25_rocniku) + nove_body = body_z_hodnoceni(novejsi_hodnoceni) + logicke_body = 2*stare_body + nove_body + + + hodnoceni_do_26_rocniku = Hodnoceni.objects.filter(cislo_body__rocnik__rocnik__lte=26,reseni__in=self.reseni_set.all()) + def titul_do_26_rocniku(body): + """ Původní hranice bodů za tituly """ + if body < 10: + return Titul.nic + elif body < 20: + return titul.bc + elif body < 50: + return titul.mgr + elif body < 100: + return titul.dr + elif body < 200: + return titul.doc + elif body < 500: + return titul.prof + else: + return titul.akad + stary_titul = titul_do_26_rocniku(body_z_hodnoceni(hodnoceni_do_26_rocniku)) - if celkove_body < 10: - return '' - elif celkove_body < 20: - return 'Bc.' - elif celkove_body < 50: - return 'Mgr.' - elif celkove_body < 100: - return 'Dr.' - elif celkove_body < 200: - return 'Doc.' - elif celkove_body < 500: - return 'Prof.' else: - return 'Akad.' + # Prostě titul podle aktuálních bodů + logicke_body = body + + titul = Titul.z_bodu(logicke_body) + if stary_titul is None: + return str(titul) + return str(max(titul, stary_titul)) + + def __str__(self): return self.osoba.plne_jmeno() From 9d7fedd0ac7412aa91cf6975191562f2cb7721b6 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 25 Nov 2020 05:08:41 +0100 Subject: [PATCH 2/3] Fix --- seminar/models.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 3f654247..563b1e62 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -370,17 +370,17 @@ class Resitel(SeminarModelBase): if body < 10: return Titul.nic elif body < 20: - return titul.bc + return Titul.bc elif body < 50: - return titul.mgr + return Titul.mgr elif body < 100: - return titul.dr + return Titul.dr elif body < 200: - return titul.doc + return Titul.doc elif body < 500: - return titul.prof + return Titul.prof else: - return titul.akad + return Titul.akad stary_titul = titul_do_26_rocniku(body_z_hodnoceni(hodnoceni_do_26_rocniku)) else: From 4096f94e682469afe71d9948420db35fa19c86dc Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 25 Nov 2020 23:10:24 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Spr=C3=A1vn=C3=A9=20po=C4=8D=C3=ADt=C3=A1n?= =?UTF-8?q?=C3=AD=20star=C3=BDch=20bod=C5=AF=20do=20titul=C5=AF=20a=20v?= =?UTF-8?q?=C3=BDsledkovek?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 100 +++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 42 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 563b1e62..bd1397b4 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -345,52 +345,68 @@ class Resitel(SeminarModelBase): break return aktualni - # Titul pro 26. ročník - stary_titul = None + # Hledáme body v databázi + # V listopadu 2020 jsme se na filosofické schůzce shodli o změně hranic titulů: + # - body z 25. ročníku a dříve byly shledány dvakrát hodnotnějšími + # - proto se započítávají dvojnásobně a byly posunuté hranice titulů + # - staré tituly se ale nemají odebrat, pokud řešitel v t.č. minulém (26.) ročníku měl titul, má ho mít pořád. + hodnoceni_do_25_rocniku = Hodnoceni.objects.filter(cislo_body__rocnik__rocnik__lte=25,reseni__in=self.reseni_set.all()) + novejsi_hodnoceni = Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()).difference(hodnoceni_do_25_rocniku) + + def body_z_hodnoceni(hh : list): + return sum(h.body for h in hh) + + stare_body = body_z_hodnoceni(hodnoceni_do_25_rocniku) if body is None: - # Hledáme body v databázi - # V listopadu 2020 jsme se na filosofické schůzce shodli o změně hranic titulů: - # - body z 25. ročníku a dříve byly shledány dvakrát hodnotnějšími - # - proto se započítávají dvojnásobně a byly posunuté hranice titulů - # - staré tituly se ale nemají odebrat, pokud řešitel v t.č. minulém (26.) ročníku měl titul, má ho mít pořád. - hodnoceni_do_25_rocniku = Hodnoceni.objects.filter(cislo_body__rocnik__rocnik__lte=25,reseni__in=self.reseni_set.all()) - novejsi_hodnoceni = Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()).difference(hodnoceni_do_25_rocniku) - - def body_z_hodnoceni(hh : list): - return sum(h.body for h in hh) - - stare_body = body_z_hodnoceni(hodnoceni_do_25_rocniku) nove_body = body_z_hodnoceni(novejsi_hodnoceni) - logicke_body = 2*stare_body + nove_body - - - hodnoceni_do_26_rocniku = Hodnoceni.objects.filter(cislo_body__rocnik__rocnik__lte=26,reseni__in=self.reseni_set.all()) - def titul_do_26_rocniku(body): - """ Původní hranice bodů za tituly """ - if body < 10: - return Titul.nic - elif body < 20: - return Titul.bc - elif body < 50: - return Titul.mgr - elif body < 100: - return Titul.dr - elif body < 200: - return Titul.doc - elif body < 500: - return Titul.prof - else: - return Titul.akad - stary_titul = titul_do_26_rocniku(body_z_hodnoceni(hodnoceni_do_26_rocniku)) - else: - # Prostě titul podle aktuálních bodů - logicke_body = body + # Zjistíme, kolik bodů jsou staré, tedy hodnotnější + nove_body = max(0, body - stare_body) # Všechny body nad počet původních hodnotnějších + stare_body = min(stare_body, body) # Skutečný počet hodnotnějších bodů + logicke_body = 2*stare_body + nove_body + - titul = Titul.z_bodu(logicke_body) - if stary_titul is None: - return str(titul) - return str(max(titul, stary_titul)) + # Titul se určí následovně: + # - Pokud se řeší body, které jsou starší, než do 26 ročníku (včetně), dáváme tituly postaru. + # - Jinak dáváme tituly po novu... + # - ... ale titul se nesmí odebrat, pokud se zmenšil. + def titul_do_26_rocniku(body): + """ Původní hranice bodů za tituly """ + if body < 10: + return Titul.nic + elif body < 20: + return Titul.bc + elif body < 50: + return Titul.mgr + elif body < 100: + return Titul.dr + elif body < 200: + return Titul.doc + elif body < 500: + return Titul.prof + else: + return Titul.akad + + hodnoceni_do_26_rocniku = Hodnoceni.objects.filter(cislo_body__rocnik__rocnik__lte=26,reseni__in=self.reseni_set.all()) + novejsi_body = body_z_hodnoceni( + Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()) + .difference(hodnoceni_do_26_rocniku) + ) + starsi_body = body_z_hodnoceni(hodnoceni_do_26_rocniku) + if body is not None: + # Ještě z toho vybereme ty správně staré body + novejsi_body = max(0, body - starsi_body) + starsi_body = min(starsi_body, body) + + # Titul pro 26. ročník + stary_titul = titul_do_26_rocniku(starsi_body) + # Titul podle aktuálních pravidel + novy_titul = Titul.z_bodu(logicke_body) + + if novejsi_body == 0: + # Žádné nové body -- titul podle starých pravidel + return str(stary_titul) + return str(max(novy_titul, stary_titul)) def __str__(self):