@ -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()))