From 2a85c1c9873dbbb9c17c684a7dcdcaad807a1f71 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 20 Nov 2019 23:56:51 +0100 Subject: [PATCH] =?UTF-8?q?views.py=20|=20p=C5=99eps=C3=A1na=20funkce=20po?= =?UTF-8?q?=C4=8D=C3=ADtaj=C3=ADc=C3=AD=20po=C5=99ad=C3=AD=20ve=20v=C3=BDs?= =?UTF-8?q?ledkovce=20podle=20bod=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/views.py | 105 ++++++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/seminar/views.py b/seminar/views.py index 3dc29596..fbf8c46e 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -260,25 +260,35 @@ class ArchivView(generic.ListView): ### Výsledky -def sloupec_s_poradim(vysledky): - # počet řešitelů ve výsledkovce nad aktuálním - lepsich_resitelu = 0 - - poradi_l = [] - # projdeme skupiny řešitelů se stejným počtem bodů - for skupina in (list(x) for _, x in groupby(vysledky, lambda x: x.body)): - - # připravíme si obsahy buněk ve sloupci pořadí pro skupinu - if len(skupina) == 1: - poradi_l += ["{}.".format(lepsich_resitelu + 1)] - # je-li účastníků se stejným počtem bodů víc, - # pořadí (rozsah X.-Y.) je jen u prvního +# ze seznamu všech bodů vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.) +def sloupec_s_poradim(seznam_s_body): + aktualni_poradi = 1 + sloupec_s_poradim = [] + + # seskupíme seznam všech bodů podle hodnot + for index in range(0, len(seznam_s_body)): + # pokud je pořadí větší než číslo řádku, tak jsme vypsali větší rozsah a chceme + # vypsat už jen prázdné místo, než dojdeme na správný řádek + if (index+1) < aktualni_poradi: + sloupec_s_poradim.append("") + continue + velikost_skupiny = 0 + # zjistíme počet po sobě jdoucích stejných hodnot + while seznam_s_body[index] == seznam_s_body[index + velikost_skupiny]: + velikost_skupiny = velikost_skupiny + 1 + # na konci musíme ošetřit přetečení seznamu + if (index + velikost_skupiny) > len(seznam_s_body) - 1: + break + # pokud je velikost skupiny 1, vypíšu pořadí + if velikost_skupiny == 1: + sloupec_s_poradim.append("{}.".format(aktualni_poradi)) + # pokud je skupina větší, vypíšu rozsah else: - poradi_l += ["{}.–{}.".format(lepsich_resitelu + 1, lepsich_resitelu + len(skupina))] + [""] * (len(skupina)-1) - lepsich_resitelu += len(skupina) - #pomlcka je opravdu pomlcka v unicode!!dulezite pro vysledkovku v TeXu - - return poradi_l + sloupec_s_poradim.append("{}.–{}.".format(aktualni_poradi, + aktualni_poradi+velikost_skupiny-1)) + # zvětšíme aktuální pořadí o tolik, kolik pozic bylo přeskočeno + aktualni_poradi = aktualni_poradi + velikost_skupiny + return sloupec_s_poradim # spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy def __soucet_resitele_problemu(problem, resitel, cislo, soucet): @@ -323,6 +333,7 @@ def hlavni_problemy_cisla(cislo): # zunikátnění hlavni_problemy_set = set(hlavni_problemy) hlavni_problemy = list(hlavni_problemy_set) + hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku) # setřídit podle t1, t2, c3, ... return hlavni_problemy @@ -331,7 +342,7 @@ def hlavni_problemy_cisla(cislo): def body_resitele_v_cisle(resitel, cislo): hlavni_problemy = hlavni_problemy_cisla(cislo) for h in hlavni_problemy: - body_resitele = body_resitele + body_resitele_problemu_v_cisle(resitel, cislo) + body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, resitel, cislo) # TODO: je rozdíl mezi odevzdanou úlohou za 0 a tím, když řešitel nic neodevzdal # řešit přes kontrolu velikosti množiny řešení daného problému do daného čísla? # Tady to ale nevadí, tady se počítá součet za číslo. @@ -456,19 +467,16 @@ class ProblemView(generic.DetailView): class VysledkyResitele(object): """Pro daného řešitele ukládá počet bodů za jednotlivé úlohy a celkový - počet bodů za konkrétní číslo.""" + počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" - def __init__(self, resitel): + def __init__(self, resitel, cislo, rocnik): resitel_jmeno = resitel.osoba.jmeno resitel_prijmeni = resitel.osoba.prijmeni - body = {} - body_rocnik = 0 - - def body_za_cislo(self): - return sum(body.values()) - - def body_za_rocnik(self): - return body_rocnik + self.cislo = cislo + body_cislo = body_resitele_v_cisle(resitel, cislo) + body = [] + self.rocnik = rocnik + body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) class CisloView(generic.DetailView): model = Cislo @@ -504,17 +512,18 @@ class CisloView(generic.DetailView): #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) radky_vysledkovky = [] for ar in aktivni_resitele: - # získáme výsledky řešitele - součty přes jednotlivé hlavní problémy - vr = VysledkyResitele(ar) - # ukládání součtu bodů za všechny hlavní problémy => součet bodů za číslo - vr.body_cislo = body_resitele_v_cisle(ar, cislo) - # výpočet bodů za ročník do daného čísla (aby fungovalo i pro starší čísla) - vr.body_rocnik = body_resitele_v_rocniku(ar, cislo.rocnik, cislo) + # získáme výsledky řešitele - součty přes číslo a ročník + vr = VysledkyResitele(ar, cislo, cislo.rocnik) + for hp in hlavni_problemy: + ar.body.append(body_resitele_problemu_v_cisle(hp, resitel, cislo)) radky_vysledkovky.append(vr) - ## TODO: seřadit řešitele podle bodů v daném ročníku - ## řazení viz fce výše - pochopit a případně přepsat - + ## TODO: + ## vytvořit každému řešiteli objekt nesoucí jeho data + ## setřídit tyto objekty podle bodů + ## vygenerovat sloupec s pořadím pomocí stejně zvané funkce + ## předat to do kontextu + # XXX # problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku())) # #setridi problemy podle typu a poradi zadani @@ -1013,16 +1022,24 @@ def logoutView(request): return render(request, 'seminar/login.html', {'form': form}) +def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data): + msg = "{}, form_hash:{}".format(msg,hash(form_data)) + logger.warn(msg) + gdpr_logger.warn(msg+", form:{}".format(form_data)) + + def prihlaskaView(request): + generic_logger = logging.getLogger('seminar.prihlaska') err_logger = logging.getLogger('seminar.prihlaska.problem') form_logger = logging.getLogger('seminar.prihlaska.form') if request.method == 'POST': form = PrihlaskaForm(request.POST) + # TODO vyresit, co se bude v jakych situacich zobrazovat if form.is_valid(): + generic_logger.info("Form valid") fcd = form.cleaned_data - form_hash = hash(frozenset(fcd.items())) - fcd["hash"] = form_hash - form_logger.info(fcd) + form_hash = hash(fcd) + form_logger.info(fcd,form_hash=form_hash) with transaction.atomic(): u = User.objects.create_user( @@ -1051,7 +1068,8 @@ def prihlaskaView(request): o.stat = fcd['stat'] else: # Unknown country - log it - err_logger.warn("Unknown country {}. Form hash:{}".format(fcd['stat_text'],form_hash)) + msg = "Unknown country {}".format(fcd['stat_text']) + err_logger.warn(msg,form_hash=form_hash) o.save() o.user = u @@ -1068,7 +1086,8 @@ def prihlaskaView(request): r.skola = fcd['skola'] else: # Unknown school - log it - err_logger.warn("Unknown school {}, {}. Form hash:{}".format(fcd['skola_nazev'],fcd['skola_adresa'],form_hash)) + msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa']) + err_logger.warn(msg,form_hash=form_hash) r.save()