From d99e4064e83b14c97104ccdad68a0eba10e5196a Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 19 Feb 2020 22:51:23 +0100 Subject: [PATCH 1/3] pridani cisla do urls, zmena defaultniho parametru pro testovaci data, opravovani vysledkovky cisla ve views (aktualne nefunkcni) --- seminar/testutils.py | 2 +- seminar/urls.py | 2 +- seminar/views.py | 11 +++++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/seminar/testutils.py b/seminar/testutils.py index 82ec58fe..3ede409c 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -545,7 +545,7 @@ def gen_novinky(rnd, organizatori): def otec_syn(otec, syn): bratr = otec.first_child - syn.ucc = bratr + syn.succ = bratr otec.first_child = syn syn.save() otec.save() diff --git a/seminar/urls.py b/seminar/urls.py index bc1c89a8..c4f7f479 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -23,7 +23,7 @@ urlpatterns = [ path('archiv/temata/', views.ArchivTemataView.as_view()), path('rocnik//', views.RocnikView.as_view(), name='seminar_rocnik'), - #path('cislo/./', views.CisloView.as_view(), name='seminar_cislo'), + path('cislo/./', views.CisloView.as_view(), name='seminar_cislo'), path('problem//', views.ProblemView.as_view(), name='seminar_problem'), #path('problem/(?P\d+)/(?P\d+)/', views.PrispevekView.as_view(), name='seminar_problem_prispevek'), diff --git a/seminar/views.py b/seminar/views.py index e174ab28..abb1ad77 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -430,11 +430,12 @@ def sloupec_s_poradim(seznam_s_body): def __soucet_resitele_problemu(problem, resitel, cislo, soucet): # sečteme body za daný problém přes všechna řešení daného problému # od daného řešitele - reseni_resitele = problem.hodnoceni_set.filter(reseni__resitele=resitel, + reseni_resitele = Reseni.objects.filter(resitele__in=resitel) + hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele, cislo_body=cislo) # XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains # nebo in - for r in reseni_resitele: + for r in hodnoceni_resitele: soucet += r.body # a přičteme k tomu hodnocení všech podproblémů @@ -450,7 +451,8 @@ def body_resitele_problemu_v_cisle(problem, resitel, cislo): # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém def hlavni_problemy_cisla(cislo): - hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all() # hodnocení, která se vážou k danému číslu + hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all() + # hodnocení, která se vážou k danému číslu reseni = [h.reseni for h in hodnoceni] problemy = [h.problem for h in hodnoceni] @@ -585,7 +587,8 @@ class RocnikView(generic.DetailView): #context['vysledkovka'] = vysledkovka_rocniku(context["rocnik"]) #context['vysledkovka_s_neverejnymi'] = vysledkovka_rocniku(context["rocnik"], jen_verejne=False) - context['temata_v_rocniku'] = verejna_temata(context["rocnik"]) + #context['temata_v_rocniku'] = verejna_temata(context["rocnik"]) + # FIXME: opravit vylistování témat v ročníku return context From caa274460d79ca9033c10242f752ab1c412759f1 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 11 Mar 2020 23:00:54 +0100 Subject: [PATCH 2/3] =?UTF-8?q?nepadaj=C3=ADc=C3=AD=20(ale=20nezobrazuj?= =?UTF-8?q?=C3=ADc=C3=AD=20se)=20verze=20v=C3=BDsledkovky=20v2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/templates/seminar/archiv/cislo.html | 16 +- seminar/views.py | 235 +++++++++++++------- 2 files changed, 157 insertions(+), 94 deletions(-) diff --git a/seminar/templates/seminar/archiv/cislo.html b/seminar/templates/seminar/archiv/cislo.html index d8b030c8..63788e06 100644 --- a/seminar/templates/seminar/archiv/cislo.html +++ b/seminar/templates/seminar/archiv/cislo.html @@ -67,21 +67,21 @@ {% endfor %} Za číslo Za ročník - Odjakživa - {% for rv in vysledkovka %} + {#Odjakživa#} + {% for rv in radky_vysledkovky %} {% autoescape off %}{{ rv.poradi }}{% endautoescape %} - {% if rv.titul %} - {{ rv.titul }}MM + {% if rv.resitel.get_titul != "" %} + {{ rv.resitel.get_titul }}MM {% endif %} - {{ rv.resitel.plne_jmeno }} - {% for b in rv.body_ulohy %} + {{ rv.resitel.osoba.plne_jmeno }} + {% for b in rv.hlavni_problemy_body %} {{ b }} {% endfor %} {{ rv.body_cislo }} - {{ rv.body_celkem_rocnik }} - {{ rv.body_celkem_odjakziva }} + {{ rv.body_rocnik }} + {# {{ rv.body_celkem_odjakziva }}#} {% endfor %} diff --git a/seminar/views.py b/seminar/views.py index abb1ad77..298e8e0e 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -426,28 +426,34 @@ def sloupec_s_poradim(seznam_s_body): 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): - # sečteme body za daný problém přes všechna řešení daného problému - # od daného řešitele - reseni_resitele = Reseni.objects.filter(resitele__in=resitel) - hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele, - cislo_body=cislo) - # XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains - # nebo in - for r in hodnoceni_resitele: - soucet += r.body - - # a přičteme k tomu hodnocení všech podproblémů - for p in problem.podproblem.all(): - # i přes jméno by to měla být množina jeho podproblémů - soucet += __soucet_resitele_problemu(p, resitel, soucet) - return soucet - -# spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele -def body_resitele_problemu_v_cisle(problem, resitel, cislo): - # probably FIXED: nezohledňuje číslo, do kterého se body počítají - return __soucet_resitele_problemu(problem, resitel, cislo, 0) +## 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): +# # sečteme body za daný problém přes všechna řešení daného problému +# # od daného řešitele +# reseni_resitele = s.Reseni_Resitele.objects.filter(resitele=resitel) +# hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele, +# cislo_body=cislo) +# # XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains +# # nebo in +# for r in hodnoceni_resitele: +# soucet += r.body +# +# # a přičteme k tomu hodnocení všech podproblémů +# for p in problem.podproblem.all(): +# # i přes jméno by to měla být množina jeho podproblémů +# soucet += __soucet_resitele_problemu(p, resitel, soucet) +# return soucet + +## spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele +#def body_resitele_problemu_v_cisle(problem, resitel, cislo): +# # probably FIXED: nezohledňuje číslo, do kterého se body počítají +# return __soucet_resitele_problemu(problem, resitel, cislo, 0) + +# pro daný problém vrátí jeho nejvyšší nadproblém +def hlavni_problem(problem): + while not(problem.nadproblem == None): + problem = problem.nadproblem + return problem # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém def hlavni_problemy_cisla(cislo): @@ -463,9 +469,7 @@ def hlavni_problemy_cisla(cislo): # (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) hlavni_problemy = [] for p in problemy: - while not(p.nadproblem == None): - p = p.nadproblem - hlavni_problemy.append(p) + hlavni_problemy.append(hlavni_problem(p)) # zunikátnění hlavni_problemy_set = set(hlavni_problemy) @@ -474,38 +478,54 @@ def hlavni_problemy_cisla(cislo): return hlavni_problemy -def body_resitele_odjakziva(resitel): - body = 0 - resitelova_hodnoceni = Hodnoceni.objects.select_related('body').all().filter(reseni_resitele=resitel) - # TODO: v radku nahore chceme _in nebo _contains - for hodnoceni in resitelova_hodnoceni: - body = body + hodnoceni.body - return body +# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník +def body_resitelu_za_rocnik(rocnik, aktivni_resitele): + body_za_rocnik = {} + # inicializujeme na 0 pro všechny aktivní řešitele + for ar in aktivni_resitele: + body_za_rocnik[str(ar.id)] = 0 + + # spočítáme body řešitelům přes všechna řešení s hodnocením v daném ročníku + reseni = Reseni.objects.filter(hodnoceni__cislo_body__rocnik=rocnik) + for res in reseni: + for resitel in res.resitele.all(): + for hodn in res.hodnoceni.all(): + body_za_rocnik[str(resitel.id)] += hodn.body + return body_za_rocnik + +#def body_resitele_odjakziva(resitel): +# body = 0 +# resitelova_hodnoceni = Hodnoceni.objects.select_related('body').all().filter(reseni_resitele=resitel) +# # TODO: v radku nahore chceme _in nebo _contains +# for hodnoceni in resitelova_hodnoceni: +# body = body + hodnoceni.body +# return body # spočítá součet všech bodů řešitele za dané číslo -def body_resitele_v_cisle(resitel, cislo): - hlavni_problemy = hlavni_problemy_cisla(cislo) - body_resitele = 0 - for h in hlavni_problemy: - 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. - return body_resitele +#def body_resitele_v_cisle(resitel, cislo): +# hlavni_problemy = hlavni_problemy_cisla(cislo) +# body_resitele = 0 +# for h in hlavni_problemy: +# 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. +# return body_resitele # spočítá součet všech bodů řešitele za daný rok (nebo jen do daného čísla včetně) -def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): - # pokud do_cisla=None, tak do posledního čísla v ročníku - # do_cisla je objekt Cislo - cisla = rocnik.cisla.all() # funkce vrátí pole objektů - # Cislo už lexikograficky setřízené, viz models - body = 0 - for cislo in cisla: - if cislo.poradi == do_cisla.poradi: break - # druhá část zaručuje, že máme výsledky do daného čísla včetně - body = body + body_resitele_v_cisle(resitel, cislo) - return body - +#def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): +# # pokud do_cisla=None, tak do posledního čísla v ročníku +# # do_cisla je objekt Cislo +# cisla = rocnik.cisla.all() # funkce vrátí pole objektů +# # Cislo už lexikograficky setřízené, viz models +# body = 0 +# for cislo in cisla: +# if cislo.poradi == do_cisla.poradi: break +# # druhá část zaručuje, že máme výsledky do daného čísla včetně +# body = body + body_resitele_v_cisle(resitel, cislo) +# return body + +# TODO: předělat na nový model #def vysledkovka_rocniku(rocnik, jen_verejne=True): # """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve # formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" @@ -612,19 +632,17 @@ class ProblemView(generic.DetailView): return context -class VysledkyResitele(object): - """Pro daného řešitele ukládá počet bodů za jednotlivé úlohy a celkový - počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" +class RadekVysledkovky(object): + """Obsahuje věci, které se hodí vědět při konstruování výsledkovky. + Umožňuje snazší práci v templatu (lepší, než seznam).""" - def __init__(self, resitel, cislo, rocnik): + def __init__(self, poradi, resitel, body_problemy_sezn, body_cislo, body_rocnik): self.resitel = resitel - self.cislo = cislo - self.body_cislo = body_resitele_v_cisle(resitel, cislo) - self.body = [] - self.rocnik = rocnik - self.body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) - self.body_celkem_odjakziva = resitel.vsechny_body() - self.poradi = 0 + self.body_cislo = body_cislo + self.body_rocnik = body_rocnik +# TODO self.body_celkem_odjakziva = odjakziva + self.poradi = poradi + self.body_problemy_sezn = body_problemy_sezn class CisloView(generic.DetailView): model = Cislo @@ -648,48 +666,93 @@ class CisloView(generic.DetailView): def get_context_data(self, **kwargs): context = super(CisloView, self).get_context_data(**kwargs) - ## TODO upravit dle nového modelu cislo = context['cislo'] hlavni_problemy = hlavni_problemy_cisla(cislo) + # TODO setřídit hlavní problémy čísla podle id, ať jsou ve stejném pořadí pokaždé + # pro každý hlavní problém zavedeme slovník s body za daný hlavní problém + # pro jednotlivé řešitele (slovník slovníků hlavních problémů) + hlavni_problemy_slovnik = {} + for hp in hlavni_problemy: + hlavni_problemy_slovnik[str(hp.id)] = {} ## TODO dostat pro tyto problémy součet v daném čísle pro daného řešitele ## TODO možná chytřeji vybírat aktivní řešitele - ## chceme letos něco poslal + # aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají + # u alespoň jedné hodnoty něco jiného než NULL aktivni_resitele = Resitel.objects.filter( rok_maturity__gte=cislo.rocnik.druhy_rok()) # TODO: zkusit hodnoceni__rocnik... #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) - radky_vysledkovky = [] + # zakládání prázdných záznamů pro řešitele + cislobody = {} for ar in aktivni_resitele: - # získáme výsledky řešitele - součty přes číslo a ročník - vr = VysledkyResitele(ar, cislo, cislo.rocnik) + # řešitele převedeme na řetězec pomocí unikátního id + cislobody[str(ar.id)] = "" for hp in hlavni_problemy: - vr.body.append( - body_resitele_problemu_v_cisle(hp, ar, cislo)) - radky_vysledkovky.append(vr) - - # setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů - radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) - - # generujeme sloupec s pořadím pomocí stejně zvané funkce - pocty_bodu = [rv.body_rocnik for rv in radky_vysledkovky] - sloupec_poradi = sloupec_s_poradim(pocty_bodu) + slovnik = hlavni_problemy_slovnik[str(hp.id)] + slovnik[str(ar.id)] = "" + + # vezmeme všechna řešení s body do daného čísla + reseni_do_cisla = Reseni.objects.filter(hodnoceni__cislo_body=cislo) - # každému řádku výsledkovky přidáme jeho pořadí - i = 0 - for rv in radky_vysledkovky: - rv.poradi = sloupec_poradi[i] - i = i + 1 + # projdeme všechna řešení do čísla a přičteme body každému řešiteli do celkových + # bodů i do bodů za problém + for reseni in reseni_do_cisla: + body = reseni.hodnoceni.body + problem = reseni.problem + nadproblem = hlavni_problem(problem) + nadproblem_slovnik = hlavni_problemy_slovnik[str(nadproblem.id)] + for resitel in reseni.resitele: + # testujeme na None, pokud první řešení daného řešitele, předěláme na 0 + # (v dalším kroku přičteme reálný počet bodů), rozlišujeme tím mezi 0 a + # neodevzdaným řešením + if cislobody[str(resitel.id)] == "": + cislobody[str(resitel.id)] = 0 + cislobody[str(resitel.id)] += body + + if nadproblem_slovnik[str(resitel.id)] == "": + nadproblem_slovnik[str(resitel.id)] = 0 + nadproblem_slovnik[str(resitel.id)] += body + + # zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně + resitel_rocnikbody_slov = body_resitelu_za_rocnik(cislo.rocnik, aktivni_resitele) + resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(), + key = lambda x: x[1], reverse = True) + + # řešitelé setřídění podle bodů za číslo sestupně + setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn] + setrizeni_resitele = [Resitel.objects.get(id=i) for i in setrizeni_resitele_id] + + # vytvoříme jednotlivé sloupce výsledkovky + radky_vysledkovky = [] + rocnik_body = [] + cislo_body = [] + hlavni_problemy_body = [] + for ar_id in setrizeni_resitele_id: + # vytáhneme ze slovníků body pro daného řešitele + rocnik_body.append(resitel_rocnikbody_slov[ar_id]) + cislo_body.append(cislobody[ar_id]) + problemy = [] + for hp in hlavni_problemy: + problemy.append(hlavni_problemy_slovnik[str(hp.id)][ar_id]) + hlavni_problemy_body.append(problemy) + # pořadí určíme pomocí funkce, které dáme celkové body za ročník vzestupně + poradi = sloupec_s_poradim(rocnik_body) + + radky_vysledkovky = [] + for i in range(0, len(setrizeni_resitele_id)): + radek = RadekVysledkovky(poradi[i], setrizeni_resitele[i], + hlavni_problemy_body[i], cislo_body[i], rocnik_body[i]) + radky_vysledkovky.append(radek) # vytahané informace předáváme do kontextu context['cislo'] = cislo - context['radky_vysledkovky'] = radky_vysledkovky + context['radky_vysledkovky'] = radky_vysledkovky context['problemy'] = hlavni_problemy # context['v_cisle_zadane'] = TODO # context['resene_problemy'] = resene_problemy #XXX testovat #XXX opravit to, že se nezobrazují body za jednotlivé úlohy - return context # problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku())) From 64074d5dc6cbd82daebd3c6591d6e090cae88857 Mon Sep 17 00:00:00 2001 From: Anet Date: Thu, 19 Mar 2020 01:31:00 +0100 Subject: [PATCH 3/3] =?UTF-8?q?views:=20skoro=20funk=C4=8Dn=C3=AD=20v?= =?UTF-8?q?=C3=BDsledkovka,=20probl=C3=A9my=20s=20body=20odjak=C5=BEiva,?= =?UTF-8?q?=20dotazy=20do=20datab=C3=A1ze=20u=C5=BE=20jinak=20rozumn=C4=9B?= =?UTF-8?q?=20rychl=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/views/views_all.py | 104 +++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 26 deletions(-) diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index 3065e037..3dcf1331 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -477,6 +477,35 @@ def hlavni_problemy_cisla(cislo): return hlavni_problemy +# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník +# POZOR! Aktuálně počítá jen za posledních 10 let od zadaného ročníku +def body_resitelu_odjakziva(rocnik, resitele): + body_odjakziva = {} + + for r in resitele: + body_odjakziva[str(r.id)] = 0 +# # Body za posledních 10 let je dobrá aproximace pro naše potřeby (výsledkovka +# # s aktivními řešiteli) +# +# body_pred_roky = [] +# for i in range(0, 10): +# body_pred_roky.append(body_resitelu_za_rocnik(rocnik-i, resitele)) +# +# for r in resitele: +# for i in range(0,10): +# body_odjakziva[str(r.id)] += body_pred_roky[i][str(r.id)] + + +# Nasledující řešení je sice správné, ale moc pomalé: + for res in Reseni.objects.prefetch_related('resitele', 'hodnoceni').all(): + for r in res.resitele.all(): + # daný řešitel nemusí být v naší podmnožině + if r not in resitele: continue + + for hodn in res.hodnoceni.all(): + pricti_body(body_odjakziva, r, hodn.body) + return body_odjakziva + # vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník def body_resitelu_za_rocnik(rocnik, aktivni_resitele): body_za_rocnik = {} @@ -485,11 +514,11 @@ def body_resitelu_za_rocnik(rocnik, aktivni_resitele): body_za_rocnik[str(ar.id)] = 0 # spočítáme body řešitelům přes všechna řešení s hodnocením v daném ročníku - reseni = Reseni.objects.filter(hodnoceni__cislo_body__rocnik=rocnik) + reseni = Reseni.objects.prefetch_related('resitele', 'hodnoceni').filter(hodnoceni__cislo_body__rocnik=rocnik) for res in reseni: for resitel in res.resitele.all(): for hodn in res.hodnoceni.all(): - body_za_rocnik[str(resitel.id)] += hodn.body + pricti_body(body_za_rocnik, resitel, hodn.body) return body_za_rocnik #def body_resitele_odjakziva(resitel): @@ -635,13 +664,26 @@ class RadekVysledkovky(object): """Obsahuje věci, které se hodí vědět při konstruování výsledkovky. Umožňuje snazší práci v templatu (lepší, než seznam).""" - def __init__(self, poradi, resitel, body_problemy_sezn, body_cislo, body_rocnik): + def __init__(self, poradi, resitel, body_problemy_sezn, + body_cislo, body_rocnik, body_odjakziva): self.resitel = resitel self.body_cislo = body_cislo self.body_rocnik = body_rocnik -# TODO self.body_celkem_odjakziva = odjakziva + self.body_celkem_odjakziva = body_odjakziva self.poradi = poradi self.body_problemy_sezn = body_problemy_sezn + + +# přiřazuje danému řešiteli body do slovníku +def pricti_body(slovnik, resitel, body): + # testujeme na None (""), pokud je to první řešení + # daného řešitele, předěláme na 0 + # (v dalším kroku přičteme reálný počet bodů), + # rozlišujeme tím mezi 0 a neodevzdaným řešením + if slovnik[str(resitel.id)] == "": + slovnik[str(resitel.id)] = 0 + + slovnik[str(resitel.id)] += body class CisloView(generic.DetailView): model = Cislo @@ -678,8 +720,8 @@ class CisloView(generic.DetailView): ## TODO možná chytřeji vybírat aktivní řešitele # aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají # u alespoň jedné hodnoty něco jiného než NULL - aktivni_resitele = Resitel.objects.filter( - rok_maturity__gte=cislo.rocnik.druhy_rok()) + aktivni_resitele = list(Resitel.objects.filter( + rok_maturity__gte=cislo.rocnik.druhy_rok())) # TODO: zkusit hodnoceni__rocnik... #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) # zakládání prázdných záznamů pro řešitele @@ -692,66 +734,76 @@ class CisloView(generic.DetailView): slovnik[str(ar.id)] = "" # vezmeme všechna řešení s body do daného čísla - reseni_do_cisla = Reseni.objects.filter(hodnoceni__cislo_body=cislo) + reseni_do_cisla = Reseni.objects.prefetch_related('problem', 'hodnoceni', 'resitele').filter(hodnoceni__cislo_body=cislo) # projdeme všechna řešení do čísla a přičteme body každému řešiteli do celkových # bodů i do bodů za problém for reseni in reseni_do_cisla: - body = reseni.hodnoceni.body - problem = reseni.problem - nadproblem = hlavni_problem(problem) - nadproblem_slovnik = hlavni_problemy_slovnik[str(nadproblem.id)] - for resitel in reseni.resitele: - # testujeme na None, pokud první řešení daného řešitele, předěláme na 0 - # (v dalším kroku přičteme reálný počet bodů), rozlišujeme tím mezi 0 a - # neodevzdaným řešením - if cislobody[str(resitel.id)] == "": - cislobody[str(resitel.id)] = 0 - cislobody[str(resitel.id)] += body - - if nadproblem_slovnik[str(resitel.id)] == "": - nadproblem_slovnik[str(resitel.id)] = 0 - nadproblem_slovnik[str(resitel.id)] += body + + # řešení může řešit více problémů + for prob in list(reseni.problem.all()): + nadproblem = hlavni_problem(prob) + nadproblem_slovnik = hlavni_problemy_slovnik[str(nadproblem.id)] + + # a více hodnocení + for hodn in list(reseni.hodnoceni.all()): + body = hodn.body + + # a více řešitelů + for resitel in list(reseni.resitele.all()): + pricti_body(cislobody, resitel, body) + pricti_body(nadproblem_slovnik, resitel, body) # zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně resitel_rocnikbody_slov = body_resitelu_za_rocnik(cislo.rocnik, aktivni_resitele) resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(), key = lambda x: x[1], reverse = True) - + + # získáme body odjakživa + resitel_odjakzivabody_slov = body_resitelu_odjakziva(cislo.rocnik.druhy_rok(), + aktivni_resitele) + # řešitelé setřídění podle bodů za číslo sestupně setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn] setrizeni_resitele = [Resitel.objects.get(id=i) for i in setrizeni_resitele_id] # vytvoříme jednotlivé sloupce výsledkovky radky_vysledkovky = [] + odjakziva_body = [] rocnik_body = [] cislo_body = [] hlavni_problemy_body = [] for ar_id in setrizeni_resitele_id: # vytáhneme ze slovníků body pro daného řešitele + odjakziva_body.append(resitel_odjakzivabody_slov[ar_id]) rocnik_body.append(resitel_rocnikbody_slov[ar_id]) cislo_body.append(cislobody[ar_id]) problemy = [] for hp in hlavni_problemy: problemy.append(hlavni_problemy_slovnik[str(hp.id)][ar_id]) hlavni_problemy_body.append(problemy) + print("{}: body za problémy - {}, číslobody - {}, ročníkbody - {}, odjakživabody - ".format(ar_id, problemy, cislobody[ar_id], resitel_rocnikbody_slov[ar_id])) # pořadí určíme pomocí funkce, které dáme celkové body za ročník vzestupně poradi = sloupec_s_poradim(rocnik_body) radky_vysledkovky = [] for i in range(0, len(setrizeni_resitele_id)): radek = RadekVysledkovky(poradi[i], setrizeni_resitele[i], - hlavni_problemy_body[i], cislo_body[i], rocnik_body[i]) + hlavni_problemy_body[i], cislo_body[i], rocnik_body[i], + odjakziva_body[i]) radky_vysledkovky.append(radek) + print("Přikládám {}-tý řádek.".format(i)) + print("Následuje předávání do kontextu.") # vytahané informace předáváme do kontextu context['cislo'] = cislo context['radky_vysledkovky'] = radky_vysledkovky context['problemy'] = hlavni_problemy # context['v_cisle_zadane'] = TODO # context['resene_problemy'] = resene_problemy - #XXX testovat - #XXX opravit to, že se nezobrazují body za jednotlivé úlohy + #XXX nefungují body odjakživa - asi typový problém + #XXX nefungují tituly - možná korelace s výše uvedeným problémem + print("Předávám kontext.") return context # problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku()))