|
|
@ -1,6 +1,7 @@ |
|
|
|
import seminar.models as m |
|
|
|
from django.db.models import Q, Sum, Count |
|
|
|
from seminar.utils import aktivniResitele, resi_v_rocniku, cisla_rocniku, hlavni_problemy_rocniku, hlavni_problem, hlavni_problemy_cisla, problemy_cisla, podproblemy_v_cislu |
|
|
|
from seminar.utils import aktivniResitele, resi_v_rocniku, cisla_rocniku, hlavni_problem, hlavni_problemy_f, problemy_cisla, podproblemy_v_cislu |
|
|
|
import time |
|
|
|
### Výsledky |
|
|
|
|
|
|
|
def sloupec_s_poradim(setrizene_body): |
|
|
@ -126,15 +127,16 @@ class RadekVysledkovkyRocniku(object): |
|
|
|
|
|
|
|
def setrid_resitele_a_body(slov_resitel_body): |
|
|
|
setrizeni_resitele_id = [dvojice[0] for dvojice in slov_resitel_body] |
|
|
|
setrizeni_resitele = [m.Resitel.objects.get(id=i) for i in setrizeni_resitele_id] |
|
|
|
setrizene_body = [dvojice[1] for dvojice in slov_resitel_body] |
|
|
|
return setrizeni_resitele_id, setrizeni_resitele, setrizene_body |
|
|
|
return setrizeni_resitele_id, setrizene_body |
|
|
|
|
|
|
|
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" |
|
|
|
""" |
|
|
|
|
|
|
|
start = time.time() |
|
|
|
|
|
|
|
## 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 |
|
|
@ -150,7 +152,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): |
|
|
|
resitel_rocnikbody_sezn = secti_body_za_rocnik(rocnik, aktivni_resitele) |
|
|
|
|
|
|
|
# setřídíme řešitele podle počtu bodů a získáme seznam s body od nejvyšších po nenižší |
|
|
|
setrizeni_resitele_id, setrizeni_resitele, setrizene_body = setrid_resitele_a_body(resitel_rocnikbody_sezn) |
|
|
|
setrizeni_resitele_id, setrizene_body = setrid_resitele_a_body(resitel_rocnikbody_sezn) |
|
|
|
poradi = sloupec_s_poradim(setrizene_body) |
|
|
|
|
|
|
|
# získáme body odjakživa |
|
|
@ -159,6 +161,10 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): |
|
|
|
# vytvoříme jednotlivé sloupce výsledkovky |
|
|
|
radky_vysledkovky = [] |
|
|
|
i = 0 |
|
|
|
setrizeni_resitele_dict = {} # Tento slovnik se vyrab |
|
|
|
for r in m.Resitel.objects.filter(id__in=setrizeni_resitele_id).select_related('osoba'): |
|
|
|
setrizeni_resitele_dict[r.id] = r |
|
|
|
|
|
|
|
for ar_id in setrizeni_resitele_id: |
|
|
|
# seznam počtu bodů daného řešitele pro jednotlivá čísla |
|
|
|
body_cisla_sezn = [] |
|
|
@ -168,7 +174,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): |
|
|
|
# vytáhneme informace pro daného řešitele |
|
|
|
radek = RadekVysledkovkyRocniku( |
|
|
|
poradi[i], # pořadí |
|
|
|
m.Resitel.objects.get(id=ar_id), # řešitel (z id) |
|
|
|
setrizeni_resitele_dict[ar_id], # řešitel (z id) |
|
|
|
body_cisla_sezn, # seznam bodů za čísla |
|
|
|
setrizene_body[i], # body za ročník (spočítané výše s pořadím) |
|
|
|
resitel_odjakzivabody_slov[ar_id], # body odjakživa |
|
|
@ -176,7 +182,11 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): |
|
|
|
radky_vysledkovky.append(radek) |
|
|
|
i += 1 |
|
|
|
|
|
|
|
end = time.time() |
|
|
|
print("Vysledkovka rocniku",end-start) |
|
|
|
|
|
|
|
return radky_vysledkovky |
|
|
|
|
|
|
|
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).""" |
|
|
@ -225,17 +235,18 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): |
|
|
|
# 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ů) |
|
|
|
|
|
|
|
print("Scitam cislo",cislo) |
|
|
|
|
|
|
|
if hlavni_problemy is None: |
|
|
|
hlavni_problemy = hlavni_problemy_cisla(cislo) |
|
|
|
hlavni_problemy = hlavni_problemy_f(problemy_cisla(cislo)) |
|
|
|
|
|
|
|
def ne_clanek_ne_konfera(problem): |
|
|
|
return not(isinstance(problem.get_real_instance(), m.Clanek) or isinstance(problem.get_real_instance(), m.Konfera)) |
|
|
|
inst = problem.get_real_instance() |
|
|
|
return not(isinstance(inst, m.Clanek) or isinstance(inst, m.Konfera)) |
|
|
|
|
|
|
|
temata_a_spol = list(filter(ne_clanek_ne_konfera, hlavni_problemy)) |
|
|
|
|
|
|
|
def cosi(problem): |
|
|
|
return problem.id |
|
|
|
|
|
|
|
hlavni_problemy_slovnik = {} |
|
|
|
for hp in temata_a_spol: |
|
|
|
hlavni_problemy_slovnik[hp.id] = {} |
|
|
@ -257,6 +268,7 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): |
|
|
|
reseni_do_cisla = m.Reseni.objects.prefetch_related('problem', 'resitele', |
|
|
|
'hodnoceni_set').filter(hodnoceni__cislo_body=cislo) |
|
|
|
|
|
|
|
start = time.time() |
|
|
|
# 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: |
|
|
@ -280,13 +292,15 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): |
|
|
|
continue |
|
|
|
pricti_body(cislobody, resitel, body) |
|
|
|
pricti_body(nadproblem_slovnik, resitel, body) |
|
|
|
end = time.time() |
|
|
|
print("for cykly:", end-start) |
|
|
|
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) |
|
|
|
temata = hlavni_problemy_f(problemy_cisla(cislo)) |
|
|
|
|
|
|
|
if podproblemy is None: |
|
|
|
podproblemy_v_cislu(cislo, hlavni_problemy=temata) |
|
|
@ -356,7 +370,7 @@ def vysledkovka_cisla(cislo, context=None): |
|
|
|
if context is None: |
|
|
|
context = {} |
|
|
|
problemy = problemy_cisla(cislo) |
|
|
|
hlavni_problemy = hlavni_problemy_cisla(cislo, problemy) |
|
|
|
hlavni_problemy = hlavni_problemy_f(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 |
|
|
@ -373,7 +387,6 @@ def vysledkovka_cisla(cislo, context=None): |
|
|
|
|
|
|
|
# řešitelé setřídění podle bodů za číslo sestupně |
|
|
|
setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn] |
|
|
|
setrizeni_resitele = [m.Resitel.objects.get(id=i) for i in setrizeni_resitele_id] |
|
|
|
|
|
|
|
# spočítáme pořadí řešitelů |
|
|
|
setrizeni_resitele_body = [dvojice[1] for dvojice in resitel_rocnikbody_sezn] |
|
|
@ -384,6 +397,7 @@ def vysledkovka_cisla(cislo, context=None): |
|
|
|
i = 0 |
|
|
|
|
|
|
|
def ne_clanek_ne_konfera(problem): |
|
|
|
|
|
|
|
return not(isinstance(problem.get_real_instance(), m.Clanek) or isinstance(problem.get_real_instance(), m.Konfera)) |
|
|
|
|
|
|
|
temata_a_spol = list(filter(ne_clanek_ne_konfera, hlavni_problemy)) |
|
|
@ -399,6 +413,11 @@ def vysledkovka_cisla(cislo, context=None): |
|
|
|
|
|
|
|
je_nejake_ostatni = len(hlavni_problemy) - len(temata_a_spol) > 0 |
|
|
|
|
|
|
|
setrizeni_resitele_slovnik = {} |
|
|
|
setrizeni_resitele = m.Resitel.objects.filter(id__in=setrizeni_resitele_id).select_related('osoba') |
|
|
|
for r in setrizeni_resitele: |
|
|
|
setrizeni_resitele_slovnik[r.id] = r |
|
|
|
|
|
|
|
for ar_id in setrizeni_resitele_id: |
|
|
|
# získáme seznam bodů za problémy pro daného řešitele |
|
|
|
body_problemy = [] |
|
|
@ -412,7 +431,7 @@ def vysledkovka_cisla(cislo, context=None): |
|
|
|
# vytáhneme informace pro daného řešitele |
|
|
|
radek = RadekVysledkovkyCisla( |
|
|
|
poradi[i], # pořadí |
|
|
|
m.Resitel.objects.get(id=ar_id), # řešitel (z id) |
|
|
|
setrizeni_resitele_slovnik[ar_id], # řešitel (z id) |
|
|
|
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) |
|
|
|