|
|
@ -721,15 +721,24 @@ def hlavni_problemy_rocniku(rocnik, jen_verejne=True): |
|
|
|
|
|
|
|
return hlavni_problemy |
|
|
|
|
|
|
|
def hlavni_problemy_cisla(cislo): |
|
|
|
""" Vrátí seznam všech problémů s body v daném čísle, které již nemají nadproblém. """ |
|
|
|
hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all() |
|
|
|
|
|
|
|
def problemy_cisla(cislo): |
|
|
|
""" Vrátí seznam všech problémů s body v daném čísle. """ |
|
|
|
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] |
|
|
|
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čí |
|
|
|
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čí |
|
|
|
|
|
|
|
return problemy |
|
|
|
|
|
|
|
|
|
|
|
def hlavni_problemy_cisla(cislo, problemy=None): |
|
|
|
""" Vrátí seznam všech problémů s body v daném čísle, které již nemají nadproblém. """ |
|
|
|
if problemy is None: |
|
|
|
problemy = problemy_cisla(cislo) |
|
|
|
|
|
|
|
# hlavní problémy čísla |
|
|
|
# (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) |
|
|
@ -744,6 +753,27 @@ def hlavni_problemy_cisla(cislo): |
|
|
|
|
|
|
|
return hlavni_problemy |
|
|
|
|
|
|
|
|
|
|
|
def podproblemy_v_cislu(cislo, problemy=None, hlavni_problemy=None): |
|
|
|
""" Vrátí seznam všech problémů s body v daném čísle v poli 'indexovaném' tématy. """ |
|
|
|
if problemy is None: |
|
|
|
problemy = problemy_cisla(cislo) |
|
|
|
if hlavni_problemy is None: |
|
|
|
hlavni_problemy = hlavni_problemy_cisla(cislo, problemy) |
|
|
|
|
|
|
|
podproblemy = dict((hp.id, []) for hp in hlavni_problemy) |
|
|
|
hlavni_problemy = set(hlavni_problemy) |
|
|
|
podproblemy[-1] = [] |
|
|
|
|
|
|
|
for problem in problemy: |
|
|
|
h_problem = hlavni_problem(problem) |
|
|
|
if h_problem in hlavni_problemy: |
|
|
|
podproblemy[h_problem.id].append(problem) |
|
|
|
else: |
|
|
|
podproblemy[-1].append(problem) |
|
|
|
|
|
|
|
return podproblemy |
|
|
|
|
|
|
|
def body_resitelu(resitele, za, odjakziva=True): |
|
|
|
""" Funkce počítající počty bodů pro zadané řešitele, |
|
|
|
buď odjakživa do daného ročníku/čísla anebo za daný ročník/číslo. |
|
|
@ -940,8 +970,8 @@ class RadekVysledkovkyCisla(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, body_odjakziva, rok): |
|
|
|
def __init__(self, poradi, resitel, body_problemy_sezn, |
|
|
|
body_cislo, body_rocnik, body_odjakziva, rok, body_podproblemy, body_podproblemy_iter): |
|
|
|
self.resitel = resitel |
|
|
|
self.rocnik_resitele = resitel.rocnik(rok) |
|
|
|
self.body_cislo = body_cislo |
|
|
@ -950,7 +980,9 @@ class RadekVysledkovkyCisla(object): |
|
|
|
self.poradi = poradi |
|
|
|
self.body_problemy_sezn = body_problemy_sezn |
|
|
|
self.titul = resitel.get_titul(body_odjakziva) |
|
|
|
|
|
|
|
self.body_podproblemy = body_podproblemy |
|
|
|
self.body_podproblemy_iter = body_podproblemy_iter # TODELETE |
|
|
|
|
|
|
|
|
|
|
|
def pricti_body(slovnik, resitel, body): |
|
|
|
""" Přiřazuje danému řešiteli body do slovníku. """ |
|
|
@ -1039,11 +1071,81 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): |
|
|
|
pricti_body(nadproblem_slovnik, resitel, body) |
|
|
|
return hlavni_problemy_slovnik, cislobody |
|
|
|
|
|
|
|
|
|
|
|
def secti_body_za_cislo_podle_temat(cislo, aktivni_resitele, podproblemy=None, temata=None): |
|
|
|
""" Spočítá u řešitelů body za číslo za úlohy v jednotlivých hlavních problémech (témata).""" |
|
|
|
if temata is None: |
|
|
|
temata = hlavni_problemy_cisla(cislo) |
|
|
|
|
|
|
|
if podproblemy is None: |
|
|
|
podproblemy_v_cislu(cislo, hlavni_problemy=temata) |
|
|
|
|
|
|
|
body_slovnik = {} |
|
|
|
for tema in temata: |
|
|
|
body_slovnik[tema.id] = {} |
|
|
|
for problem in podproblemy[tema.id]: |
|
|
|
body_slovnik[tema.id][problem.id] = {} |
|
|
|
body_slovnik[-1] = {} |
|
|
|
for problem in podproblemy[-1]: |
|
|
|
body_slovnik[-1][problem.id] = {} |
|
|
|
|
|
|
|
# zakládání prázdných záznamů pro řešitele |
|
|
|
for ar in aktivni_resitele: |
|
|
|
for tema in temata: |
|
|
|
for problem in podproblemy[tema.id]: |
|
|
|
body_slovnik[tema.id][problem.id][ar.id] = "" |
|
|
|
|
|
|
|
for problem in podproblemy[-1]: |
|
|
|
body_slovnik[-1][problem.id][ar.id] = "" |
|
|
|
|
|
|
|
temata = set(t.id for t in temata) |
|
|
|
|
|
|
|
# vezmeme všechna řešení s body do daného čísla |
|
|
|
reseni_do_cisla = Reseni.objects.prefetch_related('problem', 'resitele', |
|
|
|
'hodnoceni_set').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: |
|
|
|
|
|
|
|
# řešení může řešit více problémů |
|
|
|
for prob in list(reseni.problem.all()): |
|
|
|
nadproblem = hlavni_problem(prob) |
|
|
|
if nadproblem.id in temata: |
|
|
|
nadproblem_slovnik = body_slovnik[nadproblem.id] |
|
|
|
else: |
|
|
|
nadproblem_slovnik = body_slovnik[-1] |
|
|
|
|
|
|
|
problem_slovnik = nadproblem_slovnik[prob.id] |
|
|
|
|
|
|
|
# a mít více hodnocení |
|
|
|
for hodn in list(reseni.hodnoceni_set.all()): |
|
|
|
body = hodn.body |
|
|
|
|
|
|
|
# a mít více řešitelů |
|
|
|
for resitel in list(reseni.resitele.all()): |
|
|
|
if resitel not in aktivni_resitele: |
|
|
|
print("Skipping {}".format(resitel.id)) |
|
|
|
continue |
|
|
|
pricti_body(problem_slovnik, resitel, body) |
|
|
|
return body_slovnik |
|
|
|
|
|
|
|
|
|
|
|
# TODELETE |
|
|
|
class FixedIterator: |
|
|
|
def next(self): |
|
|
|
return self.niter.__next__() |
|
|
|
|
|
|
|
def __init__(self, niter): |
|
|
|
self.niter = niter |
|
|
|
# TODELETE |
|
|
|
|
|
|
|
|
|
|
|
def vysledkovka_cisla(cislo, context=None): |
|
|
|
if context is None: |
|
|
|
context = {} |
|
|
|
|
|
|
|
hlavni_problemy = hlavni_problemy_cisla(cislo) |
|
|
|
problemy = problemy_cisla(cislo) |
|
|
|
hlavni_problemy = hlavni_problemy_cisla(cislo, problemy) |
|
|
|
## 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 |
|
|
@ -1075,6 +1177,10 @@ def vysledkovka_cisla(cislo, context=None): |
|
|
|
|
|
|
|
temata_a_spol = list(filter(ne_clanek_ne_konfera, hlavni_problemy)) |
|
|
|
|
|
|
|
# získáme body u jednotlivých témat |
|
|
|
podproblemy = podproblemy_v_cislu(cislo, problemy, temata_a_spol) |
|
|
|
problemy_slovnik = secti_body_za_cislo_podle_temat(cislo, aktivni_resitele, podproblemy, temata_a_spol) |
|
|
|
|
|
|
|
# def not_empty(value): |
|
|
|
# return value != '' |
|
|
|
# |
|
|
@ -1084,20 +1190,26 @@ def vysledkovka_cisla(cislo, context=None): |
|
|
|
|
|
|
|
for ar_id in setrizeni_resitele_id: |
|
|
|
# získáme seznam bodů za problémy pro daného řešitele |
|
|
|
problemy = [] |
|
|
|
body_problemy = [] |
|
|
|
body_podproblemy = [] |
|
|
|
for hp in temata_a_spol: |
|
|
|
problemy.append(hlavni_problemy_slovnik[hp.id][ar_id]) |
|
|
|
body_problemy.append(hlavni_problemy_slovnik[hp.id][ar_id]) |
|
|
|
body_podproblemy.append([problemy_slovnik[hp.id][it.id][ar_id] for it in podproblemy[hp.id]]) |
|
|
|
if je_nejake_ostatni: |
|
|
|
problemy.append(hlavni_problemy_slovnik[-1][ar_id]) |
|
|
|
body_problemy.append(hlavni_problemy_slovnik[-1][ar_id]) |
|
|
|
body_podproblemy.append([problemy_slovnik[-1][it.id][ar_id] for it in podproblemy[-1]]) |
|
|
|
# vytáhneme informace pro daného řešitele |
|
|
|
radek = RadekVysledkovkyCisla( |
|
|
|
poradi[i], # pořadí |
|
|
|
Resitel.objects.get(id=ar_id), # řešitel (z id) |
|
|
|
problemy, # seznam bodů za hlavní problémy čísla |
|
|
|
body_problemy, # seznam bodů za hlavní problémy čísla |
|
|
|
cislobody[ar_id], # body za číslo |
|
|
|
setrizeni_resitele_body[i], # body za ročník (spočítané výše s pořadím) |
|
|
|
resitel_odjakzivabody_slov[ar_id], # body odjakživa |
|
|
|
cislo.rocnik) # ročník semináře pro zjištění ročníku řešitele |
|
|
|
cislo.rocnik, |
|
|
|
body_podproblemy, # body všech podproblémů |
|
|
|
FixedIterator(body_podproblemy.__iter__()) # TODELETE |
|
|
|
) # ročník semináře pro zjištění ročníku řešitele |
|
|
|
radky_vysledkovky.append(radek) |
|
|
|
i += 1 |
|
|
|
|
|
|
@ -1106,6 +1218,9 @@ def vysledkovka_cisla(cislo, context=None): |
|
|
|
context['radky_vysledkovky'] = radky_vysledkovky |
|
|
|
context['problemy'] = temata_a_spol |
|
|
|
context['ostatni'] = je_nejake_ostatni |
|
|
|
pt = [podproblemy[it.id] for it in temata_a_spol]+[podproblemy[-1]] |
|
|
|
context['podproblemy'] = pt |
|
|
|
context['podproblemy_iter'] = FixedIterator(pt.__iter__()) # TODELETE |
|
|
|
#context['v_cisle_zadane'] = TODO |
|
|
|
#context['resene_problemy'] = resene_problemy |
|
|
|
return context |
|
|
|