From 84017f8ca594243600f4b1e7617cf3e25327c4e9 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 16 Oct 2019 20:11:02 +0200 Subject: [PATCH] Rozpracovane upravy views. --- seminar/views.py | 131 +++++++++++++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 50 deletions(-) diff --git a/seminar/views.py b/seminar/views.py index 57c85b65..be80a4df 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -252,6 +252,7 @@ class ArchivView(generic.ListView): context["nahledy"] = "\n".join(tags) return context +### Výsledky def sloupec_s_poradim(vysledky): # počet řešitelů ve výsledkovce nad aktuálním @@ -264,14 +265,80 @@ def sloupec_s_poradim(vysledky): # 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 + # je-li účastníků se stejným počtem bodů víc, + # pořadí (rozsah X.-Y.) je jen u prvního else: - poradi_l += [u"{}.–{}.".format(lepsich_resitelu + 1, lepsich_resitelu + len(skupina))] + [""] * (len(skupina)-1) + 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 +# 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, soucet): + # FIXME: správně je nadproblem_(typ problemu), ale to by bylo potřeba nějak + # zjistit, jaký typ nodu to vlastně je a aplikovat to ve volání funkce + + # 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__contains=resitel) + for r in reseni_resitele: + soucet += r.body + + for p in problem.nadproblem_set: + # 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): + return __soucet_resitele_problemu(problem, resitel, 0) + +# 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_set # hodnocení, která se vážou k danému číslu + + reseni = [h.reseni for h in hodnoceni] + problemy = [h.problem for h in hodnoceni] + problemy_set = set(problemy) # chceme každý problém unikátně, + problemy = (list(problemy_set)) # převedení na množinu a zpět to zaručí + + # hlavní problémy čísla + # (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) + + # zunikátnění + hlavni_problemy_set = set(hlavni_problemy) + hlavni_problemy = list(hlavni_problemy_set) + + return hlavni_problemy + + +# 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) + for h in hlavni_problemy: + body_resitele = body_resitele + body_resitele_problemu_v_cisle(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_node, do_cisla=None) + # pokud do_cisla=None, tak do posledního čísla v ročníku + # do_cisla je objekt Cislo + cislo_node = rocnik_node.firstChild + body = 0 + while not (cislo_node = None or cislo_node.cislo = do_cisla.CisloNode.next): + # druhá část zaručuje, že máme výsledky do daného čísla včetně + body = body + body_resitele_v_cisle(resitel, cislo_node.cislo) + cislo_node = cislo_node.next + return body #def vysledkovka_rocniku(rocnik, jen_verejne=True): # """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve @@ -380,11 +447,11 @@ 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 číslo.""" + počet bodů za konkrétní číslo.""" - def __init__(self, jmeno, prijmeni): - resitel_jmeno = jmeno - resitel_prijmeni = prijmeni + def __init__(self, resitel): + resitel_jmeno = resitel.osoba.jmeno + resitel_prijmeni = resitel.osoba.prijmeni body = {} body_cislo = 0 @@ -410,50 +477,12 @@ class CisloView(generic.DetailView): {'verbose_name': queryset.model._meta.verbose_name}) return obj - # 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, soucet): - # FIXME: správně je nadproblem_(typ problemu), ale to by bylo potřeba nějak - # zjistit, jaký typ nodu to vlastně je a aplikovat to ve volání funkce - - # 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__contains=resitel) - for r in reseni_resitele: - soucet += r.body - - for p in problem.nadproblem_set: - # 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 - - - def vysledky_resitele_problemu(problem, resitel, cislo): - return __soucet_resitele_problemu(problem, resitel, 0) - - def get_context_data(self, **kwargs): context = super(CisloView, self).get_context_data(**kwargs) ## TODO upravit dle nového modelu cislo = context['cislo'] - hodnoceni = cislo.hodnoceni_set # hodnocení, která se vážou k danému číslu - - reseni = [h.reseni for h in hodnoceni] - problemy = [h.problem for h in hodnoceni] - problemy_set = set(problemy) # chceme každý problém unikátně, - problemy = (list(problemy_set)) # převedení na množinu a zpět to zaručí - - # hlavní problémy čísla - # (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) - hlavni_problemy = [] - for p in problemy: - while not(p.nadproblem == None): - p = nadproblem - hlavni_problemy.append(p) - - # zunikátnění - hlavni_problemy_set = set(hlavni_problemy) - hlavni_problemy = list(hlavni_problemy_set) + hlavni_problemy = hlavni_problemy_cisla(cislo) ## 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 @@ -463,15 +492,16 @@ class CisloView(generic.DetailView): #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) radky_vysledkovky = [] for ar in aktivni_resitele: - vr = VysledkyResitele(ar.jmeno, ar.prijmeni) + vr = VysledkyResitele(ar) for h in hlavni_problemy: - body = vysledky_resitele_problemu(h, ar, cislo) - vr.body[h.kod_v_rocniku] = body + body = body_resitele_problemu_v_cisle(h, ar, cislo) +# vr.body[h.kod_v_rocniku] = body vr.body_cislo = vr.body_cislo + body radky_vysledkovky.append(vr) ## TODO: spočítat počet bodů řešitele v daném ročníku a seřadit je podle toho - ## TODO: možná použít tyto funkce i v RocnikVysledkovkaView (a umístit sem nebo tam)? + ## řazení viz fce výše - pochopit a případně přepsat + ## počet bodů udělat ve fce body_resitele_v_rocniku # vysledky = VysledkyKCisluZaRocnik.objects.filter(cislo = context['cislo']).\ @@ -487,6 +517,7 @@ class CisloView(generic.DetailView): # # poradi_typu = { # Problem.TYP_ULOHA: 1, + # Problem.TYP_SERIAL: 2, # Problem.TYP_ORG_CLANEK: 3, # Problem.TYP_TEMA: 4, @@ -529,7 +560,7 @@ class CisloView(generic.DetailView): # context['problemy'] = problemy # context['v_cisle_zadane'] = v_cisle_zadane # context['resene_problemy'] = resene_problemy -# return context + return context class ArchivTemataView(generic.ListView): model = Problem