@ -40,6 +40,7 @@ import traceback
import sys
import sys
import csv
import csv
import logging
import logging
import time
def verejna_temata ( rocnik ) :
def verejna_temata ( rocnik ) :
@ -340,93 +341,32 @@ class ArchivView(generic.ListView):
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
context = super ( ArchivView , self ) . get_context_data ( * * kwargs )
context = super ( ArchivView , self ) . get_context_data ( * * kwargs )
vyska = 297 # px
cisla = Cislo . objects . filter ( poradi = 1 )
sirka = 210 # px
urls = { }
# nejnovějších 10 zveřejněných čísel
# cisla = Cislo.objects.filter(verejne_db=True)[:10]
cisla = Cislo . objects . filter ( poradi = 1 ) [ : 10 ]
# op == os.path, udělá z argumentů cestu
png_dir = op . join ( settings . MEDIA_ROOT , " cislo " , " png " )
# seznam [(url obrázku, číslo)]
urls = [ ]
for i , c in enumerate ( cisla ) :
for i , c in enumerate ( cisla ) :
if not c . pdf :
if c . titulka_nahled :
continue
urls [ c . rocnik ] = c . titulka_nahled . url
filename = os . path . split ( c . pdf . file . name ) [ 1 ] . split ( " . " ) [ 0 ]
else :
png_filename = " {} - {} px.png " . format ( filename , vyska )
urls [ c . rocnik ] = op . join ( settings . MEDIA_URL , " cislo " , " png " , " default.png " )
# Pokud obrázek neexistuje nebo není aktuální, vytvoř jej
context [ " object_list " ] = urls
png_path = op . join ( png_dir , png_filename )
if not op . exists ( png_path ) or \
op . getmtime ( png_path ) < op . getmtime ( c . pdf . path ) :
subprocess . call ( [
" convert " ,
" -density " , " 300x300 " ,
" -geometry " , " {} x {} " . format ( vyska , sirka ) ,
" -background " , " white " ,
" -flatten " ,
" -rotate " , str ( 90 * i ) ,
" {} [0] " . format ( c . pdf . path ) , # titulní strana
png_path
] )
urls . append (
( op . join ( settings . MEDIA_URL , " cislo " , " png " , png_filename ) , c )
)
vyska , sirka = sirka , vyska / 2
tags = [ ]
def spirala ( urls , tags , idx ) :
""" Rekurzivně prochází urls a generuje strom elementů do tags """
if idx > = len ( urls ) :
return
img_url , cislo = urls [ idx ]
tags . append (
" <div style= ' top: {} % ;left: {} % ;width: {} % ;height: {} % ; ' > "
. format (
50 if idx % 4 == 2 else 0 ,
50 if idx % 4 == 1 else 0 ,
50 if idx % 2 == 1 else 100 ,
50 if idx > 0 and idx % 2 == 0 else 100
)
)
tags . append ( " <a href= ' {} ' title= ' {} ' > " . format (
cislo . verejne_url ( ) , cislo . kod ( )
) )
tags . append (
" <img src= ' {} ' style= ' top: {} % ;left: {} % ;width: {} % ;height: {} % ; ' > "
. format (
img_url ,
50 if idx % 4 == 3 else 0 ,
50 if idx % 4 == 2 else 0 ,
50 if idx % 2 == 0 else 100 ,
50 if idx % 2 == 1 else 100
)
)
tags . append ( " </a> " )
spirala ( urls , tags , idx + 1 )
tags . append ( " </div> " )
spirala ( urls , tags , 0 )
context [ " nahledy " ] = " \n " . join ( tags )
return context
return context
### Výsledky
### Výsledky
# ze setřízeného(!) seznamu všech bodů vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.)
# ze seznamu obsahujícího sestupně setřízené body řešitelů za daný ročník
def sloupec_s_poradim ( seznam_s_body ) :
# vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.),
# podle toho, jak jdou za sebou ve výsledkovce
def sloupec_s_poradim ( setrizene_body ) :
# ze seznamu obsahujícího setřízené body spočítáme sloupec s pořadím
aktualni_poradi = 1
aktualni_poradi = 1
sloupec_s_poradim = [ ]
sloupec_s_poradim = [ ]
# seskupíme seznam všech bodů podle hodnot
# seskupíme seznam všech bodů podle hodnot
for index in range ( 0 , len ( seznam_s _body ) ) :
for index in range ( 0 , len ( setrizene_body ) ) :
# pokud je pořadí větší než číslo řádku, tak jsme vypsali větší rozsah a chceme
# pokud je pořadí větší než číslo řádku, tak jsme vypsali větší rozsah a chceme
# vypsat už jen prázdné místo, než dojdeme na správný řádek
# vypsat už jen prázdné místo, než dojdeme na správný řádek
if ( index + 1 ) < aktualni_poradi :
if ( index + 1 ) < aktualni_poradi :
@ -434,10 +374,10 @@ def sloupec_s_poradim(seznam_s_body):
continue
continue
velikost_skupiny = 0
velikost_skupiny = 0
# zjistíme počet po sobě jdoucích stejných hodnot
# zjistíme počet po sobě jdoucích stejných hodnot
while seznam_s _body [ index ] == seznam_s _body [ index + velikost_skupiny ] :
while setrizene _body [ index ] == setrizene _body [ index + velikost_skupiny ] :
velikost_skupiny = velikost_skupiny + 1
velikost_skupiny = velikost_skupiny + 1
# na konci musíme ošetřit přetečení seznamu
# na konci musíme ošetřit přetečení seznamu
if ( index + velikost_skupiny ) > len ( seznam_s _body ) - 1 :
if ( index + velikost_skupiny ) > len ( setrizene _body ) - 1 :
break
break
# pokud je velikost skupiny 1, vypíšu pořadí
# pokud je velikost skupiny 1, vypíšu pořadí
if velikost_skupiny == 1 :
if velikost_skupiny == 1 :
@ -450,28 +390,12 @@ def sloupec_s_poradim(seznam_s_body):
aktualni_poradi = aktualni_poradi + velikost_skupiny
aktualni_poradi = aktualni_poradi + velikost_skupiny
return sloupec_s_poradim
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
# vrátí všechna čísla daného ročníku
#def __soucet_resitele_problemu(problem, resitel, cislo, soucet):
def cisla_rocniku ( rocnik , jen_verejne = True ) :
# # sečteme body za daný problém přes všechna řešení daného problému
if jen_verejne :
# # od daného řešitele
return rocnik . verejna_cisla ( )
# reseni_resitele = s.Reseni_Resitele.objects.filter(resitele=resitel)
else :
# hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele,
return rocnik . cisla . all ( )
# 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
# pro daný problém vrátí jeho nejvyšší nadproblém
def hlavni_problem ( problem ) :
def hlavni_problem ( problem ) :
@ -479,6 +403,17 @@ def hlavni_problem(problem):
problem = problem . nadproblem
problem = problem . nadproblem
return problem
return problem
def hlavni_problemy_rocniku ( rocnik , jen_verejne = True ) :
hlavni_problemy = [ ]
for cislo in cisla_rocniku ( rocnik , jen_verejne ) :
for problem in hlavni_problemy_cisla ( cislo ) :
hlavni_problemy . append ( problem )
hlavni_problemy_set = set ( hlavni_problemy )
hlavni_problemy = list ( hlavni_problemy_set )
hlavni_problemy . sort ( key = lambda k : k . kod_v_rocniku ( ) ) # setřídit podle pořadí
return hlavni_problemy
# vrátí list všech problémů s body v daném čísle, které již nemají nadproblém
# vrátí list všech problémů s body v daném čísle, které již nemají nadproblém
def hlavni_problemy_cisla ( cislo ) :
def hlavni_problemy_cisla ( cislo ) :
hodnoceni = cislo . hodnoceni . select_related ( ' problem ' , ' reseni ' ) . all ( )
hodnoceni = cislo . hodnoceni . select_related ( ' problem ' , ' reseni ' ) . all ( )
@ -504,31 +439,12 @@ def hlavni_problemy_cisla(cislo):
# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník
# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník
def body_resitelu_odjakziva ( rocnik , resitele ) :
def body_resitelu_odjakziva ( rocnik , resitele ) :
body_odjakziva = { }
# Následující řádek přidá ke každému řešiteli údaj ".body" se součtem jejich bodů
resitele_s_body = Resitel . objects . annotate ( body = Sum ( ' reseni__hodnoceni__body ' ) )
for r in resitele :
# Teď jen z QuerySetu řešitelů anotovaných body vygenerujeme slovník indexovaný řešitelským id obsahující body
body_odjakziva [ str ( r . id ) ] = 0
# ... ale jen ro řešitele, které dostaneme jako parametr.
# POZOR! Aktuálně počítá jen za posledních 10 let od zadaného ročníku
# TODO: Zjistit, co ten parametr říká a proč je potřeba
# # Body za posledních 10 let je dobrá aproximace pro naše potřeby (výsledkovka
body_odjakziva = { int ( res . id ) : res . body for res in resitele_s_body if res in resitele }
# # 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_set ' ) . 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_set . all ( ) :
pricti_body ( body_odjakziva , r , hodn . body )
return body_odjakziva
return body_odjakziva
# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník
# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník
@ -536,73 +452,89 @@ def body_resitelu_za_rocnik(rocnik, aktivni_resitele):
body_za_rocnik = { }
body_za_rocnik = { }
# inicializujeme na 0 pro všechny aktivní řešitele
# inicializujeme na 0 pro všechny aktivní řešitele
for ar in aktivni_resitele :
for ar in aktivni_resitele :
body_za_rocnik [ str ( ar . id ) ] = 0
body_za_rocnik [ 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
# spočítáme body řešitelům přes všechna řešení s hodnocením v daném ročníku
print ( " Před dotazem: {} " . format ( time . time ( ) ) )
reseni = Reseni . objects . prefetch_related ( ' resitele ' , ' hodnoceni_set ' ) . filter ( hodnoceni__cislo_body__rocnik = rocnik )
reseni = Reseni . objects . prefetch_related ( ' resitele ' , ' hodnoceni_set ' ) . filter ( hodnoceni__cislo_body__rocnik = rocnik )
print ( " Po dotazu: {} " . format ( time . time ( ) ) )
for res in reseni :
for res in reseni :
for resitel in res . resitele . all ( ) :
for resitel in res . resitele . all ( ) :
for hodn in res . hodnoceni_set . all ( ) :
for hodn in res . hodnoceni_set . all ( ) :
pricti_body ( body_za_rocnik , resitel , hodn . body )
pricti_body ( body_za_rocnik , resitel , hodn . body )
print ( " Po for-cyklu: {} " . format ( time . time ( ) ) )
return body_za_rocnik
return body_za_rocnik
# TODO: předělat na nový model
class RadekVysledkovkyRocniku ( object ) :
#def vysledkovka_rocniku(rocnik, jen_verejne=True):
""" Obsahuje věci, které se hodí vědět při konstruování výsledkovky.
# """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve
Umožňuje snazší práci v templatu ( lepší , než seznam ) . """
# formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html"
# """
def __init__ ( self , poradi , resitel , body_cisla_sezn , body_rocnik , body_odjakziva , rok ) :
#
self . poradi = poradi
# #vyberu vsechny vysledky z rocniku
self . resitel = resitel
# cisla_v_rocniku = VysledkyKCisluZaRocnik.objects.filter(cislo__rocnik=rocnik).order_by('cislo')
self . rocnik_resitele = resitel . rocnik ( rok )
# if jen_verejne:
self . body_rocnik = body_rocnik
# cisla_v_rocniku = cisla_v_rocniku.filter(cislo__verejna_vysledkovka=True)
self . body_celkem_odjakziva = body_odjakziva
#
self . body_cisla_sezn = body_cisla_sezn
# #pokud žádné nejsou, výsledkovka se nezobrazí
self . titul = resitel . get_titul ( body_odjakziva )
# if not cisla_v_rocniku:
# return None
def vysledkovka_rocniku ( rocnik , jen_verejne = True ) :
#
""" Přebírá ročník (např. context[ " rocnik " ]) a vrací výsledkovou listinu ve
# #vybere vsechny vysledky z posledniho (verejneho) cisla a setridi sestupne dle bodu
formě vhodné pro šablonu " seminar/vysledkovka_rocniku.html "
# vysledky = list(cisla_v_rocniku.filter(cislo = cisla_v_rocniku[0].poradi).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno').select_related('resitel'))
"""
#
# class Vysledkovka:
## TODO možná chytřeji vybírat aktivní řešitele
# def __init__(self):
# aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají
# self.rocnik = rocnik.rocnik
# u alespoň jedné hodnoty něco jiného než NULL
# self.radky = []
aktivni_resitele = list ( Resitel . objects . filter (
# self.cisla = []
rok_maturity__gte = rocnik . druhy_rok ( ) ) )
#
# TODO: zkusit hodnoceni__rocnik...
# vysledkovka = Vysledkovka()
#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik)
# vysledkovka.cisla = (rocnik.verejne_vysledkovky_cisla() if jen_verejne else rocnik.cisla.all().order_by('cislo'))
cisla = cisla_rocniku ( rocnik , jen_verejne )
#
body_cisla_slov = { }
# # doplníme některé údaje do řádků výsledkovky pro řešitele ve skupině
print ( " Jen veřejná: {} , čísla: {} " . format ( jen_verejne , cisla ) )
# for poradi, v in zip(sloupec_s_poradim(vysledky), vysledky):
for cislo in cisla :
# v.poradi = poradi
# získáme body za číslo
# v.resitel.rocnik = v.resitel.rocnik(rocnik)
_ , cislobody = secti_body_za_cislo ( cislo , aktivni_resitele )
#
body_cisla_slov [ cislo . id ] = cislobody
# verejne_vysl_odjakziva = VysledkyKCisluOdjakziva.objects.filter(cislo__rocnik=rocnik, cislo=cisla_v_rocniku[0].poradi)
# if jen_verejne:
# získáme body za ročník, seznam obsahuje dvojice (řešitel_id, body) setřízené sestupně
# verejne_vysl_odjakziva = verejne_vysl_odjakziva.filter(cislo__verejna_vysledkovka=True)
resitel_rocnikbody_sezn = secti_body_za_rocnik ( rocnik , aktivni_resitele )
#
# v.body_odjakziva = verejne_vysl_odjakziva.filter(resitel = v.resitel)[0].body
# setřídíme řešitele podle počtu bodů a získáme seznam s body od nejvyšších po nenižší
# v.titul = v.resitel.get_titul(v.body_odjakziva)
setrizeni_resitele_id = [ dvojice [ 0 ] for dvojice in resitel_rocnikbody_sezn ]
# v.body_rocnik = v.body
setrizeni_resitele = [ Resitel . objects . get ( id = i ) for i in setrizeni_resitele_id ]
# v.body_cisla = []
setrizene_body = [ dvojice [ 1 ] for dvojice in resitel_rocnikbody_sezn ]
#
poradi = sloupec_s_poradim ( setrizene_body )
# #pokud pro dany rok a cislo nema resitel vysledky, ma defaultne 0
# for cis in vysledkovka.cisla:
# získáme body odjakživa
# if not jen_verejne or cis.verejna_vysledkovka:
resitel_odjakzivabody_slov = body_resitelu_odjakziva ( rocnik , aktivni_resitele )
# #seznam vysledku se spravnym rocnikem a cislem pro resitele
# #zobrazim jen je-li vysledkovka verejna
# vytvoříme jednotlivé sloupce výsledkovky
# body_za_cislo = VysledkyZaCislo.objects.filter(cislo__rocnik=rocnik).filter(cislo = cis).filter(resitel = v.resitel)
radky_vysledkovky = [ ]
# if body_za_cislo:
i = 0
# #neprazdne vysledky by mely obsahovat prave jeden vysledek
for ar_id in setrizeni_resitele_id :
# v.body_cisla.append(body_za_cislo[0].body)
# seznam počtu bodů daného řešitele pro jednotlivá čísla
# else:
body_cisla_sezn = [ ]
# #resitel nema za cislo body
for cislo in cisla :
# v.body_cisla.append(0)
body_cisla_sezn . append ( body_cisla_slov [ cislo . id ] [ ar_id ] )
#
# vysledkovka.radky.append(v)
# vytáhneme informace pro daného řešitele
#
radek = RadekVysledkovkyRocniku (
# return vysledkovka
poradi [ i ] , # pořadí
Resitel . objects . get ( id = 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
rocnik ) # ročník semináře pro získání ročníku řešitele
print ( " {} : číslobody - {} , ročníkbody - {} , "
" odjakživabody - {} " . format ( radek . resitel , radek . body_cisla_sezn ,
radek . body_rocnik , radek . body_celkem_odjakziva ) )
radky_vysledkovky . append ( radek )
print ( " Přikládám {} -tý řádek. " . format ( i ) )
i + = 1
return radky_vysledkovky
class RocnikView ( generic . DetailView ) :
class RocnikView ( generic . DetailView ) :
@ -626,10 +558,16 @@ class RocnikView(generic.DetailView):
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
context = super ( RocnikView , self ) . get_context_data ( * * kwargs )
context = super ( RocnikView , self ) . get_context_data ( * * kwargs )
#context['vysledkovka'] = vysledkovka_rocniku(context["rocnik"])
# vysledkovka = True zajistí vykreslení,
#context['vysledkovka_s_neverejnymi'] = vysledkovka_rocniku(context["rocnik"], jen_verejne=False)
# zkontrolovat, kdy se má a nemá vykreslovat
#context['temata_v_rocniku'] = verejna_temata(context["rocnik"])
context [ ' vysledkovka ' ] = True
# FIXME: opravit vylistování témat v ročníku
context [ ' cisla_s_neverejnymi ' ] = cisla_rocniku ( context [ " rocnik " ] , jen_verejne = False )
context [ ' cisla ' ] = cisla_rocniku ( context [ " rocnik " ] )
context [ ' radky_vysledkovky ' ] = vysledkovka_rocniku ( context [ " rocnik " ] )
context [ ' radky_vysledkovky_s_neverejnymi ' ] = vysledkovka_rocniku (
context [ " rocnik " ] , jen_verejne = False )
context [ ' hlavni_problemy_v_rocniku ' ] = hlavni_problemy_rocniku ( context [ " rocnik " ] )
context [ ' hlavni_problemy_v_rocniku_s_neverejnymi ' ] = hlavni_problemy_rocniku ( context [ " rocnik " ] , jen_verejne = False )
return context
return context
@ -637,29 +575,36 @@ class RocnikView(generic.DetailView):
class ProblemView ( generic . DetailView ) :
class ProblemView ( generic . DetailView ) :
model = Problem
model = Problem
def _je_clanek ( self , problem ) :
# Používáme funkci, protože přímo template_name neumí mít v přiřazení dost logiky. Ledaže by se to udělalo polymorfně...
return problem . typ in [ Problem . TYP_ORG_CLANEK , Problem . TYP_RES_CLANEK ]
def get_template_names ( self , * * kwargs ) :
def get_template_names ( self , * * kwargs ) :
context = super ( ProblemView , self ) . get_context_data ( * * kwargs )
# FIXME: Switch podle typu není hezký, ale nechtělo se mi to přepisovat celé. Správně by se tohle mělo řešit polymorfismem.
return [ ' seminar/archiv/problem_ ' + ( ' clanek.html ' if self . _je_clanek ( context [ ' problem ' ] ) else ' uloha_tema.html ' ) ]
spravne_templaty = {
s . Uloha : " uloha " ,
s . Tema : " tema " ,
s . Konfera : " konfera " ,
s . Clanek : " clanek " ,
}
context = super ( ) . get_context_data ( * * kwargs )
return [ ' seminar/archiv/problem_ ' + spravne_templaty [ context [ ' object ' ] . __class__ ] + ' .html ' ]
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
context = super ( ProblemView , self ) . get_context_data ( * * kwargs )
context = super ( ) . get_context_data ( * * kwargs )
if not context [ ' problem ' ] . verejne ( ) and not self . request . user . is_staff :
# Musí se používat context['object'], protože nevíme, jestli dostaneme úložku, téma, článek, .... a tyhle věci vyrábějí různé klíče.
if not context [ ' object ' ] . verejne ( ) and not self . request . user . is_staff :
raise PermissionDenied ( )
raise PermissionDenied ( )
if context [ ' problem ' ] . typ == Problem . TYP_RES_CLANEK :
if isinstance ( context [ ' object ' ] , Clanek ) :
context [ ' reseni ' ] = Reseni . objects . filter ( problem = context [ ' problem ' ] ) . select_related ( ' resitel ' ) . order_by ( ' resitel__prijmeni ' )
context [ ' reseni ' ] = Reseni . objects . filter ( problem = context [ ' object ' ] ) . select_related ( ' resitel ' ) . order_by ( ' resitel__prijmeni ' )
return context
return context
class RadekVysledkovky ( object ) :
class RadekVysledkovkyCisla ( object ) :
""" Obsahuje věci, které se hodí vědět při konstruování výsledkovky.
""" 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 ) . """
Umožňuje snazší práci v templatu ( lepší , než seznam ) . """
def __init__ ( self , poradi , resitel , body_problemy_sezn ,
def __init__ ( self , poradi , resitel , body_problemy_sezn ,
body_cislo , body_rocnik , body_odjakziva ) :
body_cislo , body_rocnik , body_odjakziva , rok ) :
self . resitel = resitel
self . resitel = resitel
self . rocnik_resitele = resitel . rocnik ( rok )
self . body_cislo = body_cislo
self . body_cislo = body_cislo
self . body_rocnik = body_rocnik
self . body_rocnik = body_rocnik
self . body_celkem_odjakziva = body_odjakziva
self . body_celkem_odjakziva = body_odjakziva
@ -674,36 +619,39 @@ def pricti_body(slovnik, resitel, body):
# daného řešitele, předěláme na 0
# daného řešitele, předěláme na 0
# (v dalším kroku přičteme reálný počet bodů),
# (v dalším kroku přičteme reálný počet bodů),
# rozlišujeme tím mezi 0 a neodevzdaným řešením
# rozlišujeme tím mezi 0 a neodevzdaným řešením
if slovnik [ str ( resitel . id ) ] == " " :
if slovnik [ resitel . id ] == " " :
slovnik [ str ( resitel . id ) ] = 0
slovnik [ resitel . id ] = 0
slovnik [ str ( resitel . id ) ] + = body
slovnik [ resitel . id ] + = body
def secti_body_za_rocnik ( cislo , aktivni_resitele ) :
def secti_body_za_rocnik ( rocnik , aktivni_resitele ) :
# spočítáme všem řešitelům jejich body za ročník
# spočítáme všem řešitelům jejich body za ročník
resitel_rocnikbody_slov = body_resitelu_za_rocnik ( cislo . rocnik , aktivni_resitele )
resitel_rocnikbody_slov = body_resitelu_za_rocnik ( rocnik , aktivni_resitele )
# zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně
# zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně
resitel_rocnikbody_sezn = sorted ( resitel_rocnikbody_slov . items ( ) ,
resitel_rocnikbody_sezn = sorted ( resitel_rocnikbody_slov . items ( ) ,
key = lambda x : x [ 1 ] , reverse = True )
key = lambda x : x [ 1 ] , reverse = True )
return resitel_rocnikbody_sezn
return resitel_rocnikbody_sezn
# spočítá u řešitelů body za číslo a za jednotlivé hlavní problémy (témata)
# spočítá u řešitelů body za číslo a za jednotlivé hlavní problémy (témata)
def secti_body_za_cislo ( cislo , aktivni_resitele , hlavni_problemy ) :
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é
# 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 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ů)
# pro jednotlivé řešitele (slovník slovníků hlavních problémů)
if hlavni_problemy is None :
hlavni_problemy = hlavni_problemy_cisla ( cislo )
hlavni_problemy_slovnik = { }
hlavni_problemy_slovnik = { }
for hp in hlavni_problemy :
for hp in hlavni_problemy :
hlavni_problemy_slovnik [ str ( hp . id ) ] = { }
hlavni_problemy_slovnik [ hp . id ] = { }
# zakládání prázdných záznamů pro řešitele
# zakládání prázdných záznamů pro řešitele
cislobody = { }
cislobody = { }
for ar in aktivni_resitele :
for ar in aktivni_resitele :
# řešitele převedeme na řetězec pomocí unikátního id
# řešitele převedeme na řetězec pomocí unikátního id
cislobody [ str ( ar . id ) ] = " "
cislobody [ ar . id ] = " "
for hp in hlavni_problemy :
for hp in hlavni_problemy :
slovnik = hlavni_problemy_slovnik [ str ( hp . id ) ]
slovnik = hlavni_problemy_slovnik [ hp . id ]
slovnik [ str ( ar . id ) ] = " "
slovnik [ ar . id ] = " "
# vezmeme všechna řešení s body do daného čísla
# vezmeme všechna řešení s body do daného čísla
reseni_do_cisla = Reseni . objects . prefetch_related ( ' problem ' , ' resitele ' ,
reseni_do_cisla = Reseni . objects . prefetch_related ( ' problem ' , ' resitele ' ,
@ -716,7 +664,7 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy):
# řešení může řešit více problémů
# řešení může řešit více problémů
for prob in list ( reseni . problem . all ( ) ) :
for prob in list ( reseni . problem . all ( ) ) :
nadproblem = hlavni_problem ( prob )
nadproblem = hlavni_problem ( prob )
nadproblem_slovnik = hlavni_problemy_slovnik [ str ( nadproblem . id ) ]
nadproblem_slovnik = hlavni_problemy_slovnik [ nadproblem . id ]
# a mít více hodnocení
# a mít více hodnocení
for hodn in list ( reseni . hodnoceni_set . all ( ) ) :
for hodn in list ( reseni . hodnoceni_set . all ( ) ) :
@ -728,13 +676,11 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy):
pricti_body ( nadproblem_slovnik , resitel , body )
pricti_body ( nadproblem_slovnik , resitel , body )
return hlavni_problemy_slovnik , cislobody
return hlavni_problemy_slovnik , cislobody
def vysledkovka_cisla ( cislo , context = None ) :
def spocti_vysledkovku_cisla ( cislo , context = None ) :
if context is None :
if context is None :
context = { }
context = { }
hlavni_problemy = hlavni_problemy_cisla ( cislo )
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
## 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í
# 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
# u alespoň jedné hodnoty něco jiného než NULL
@ -747,10 +693,10 @@ def spocti_vysledkovku_cisla(cislo, context=None):
hlavni_problemy_slovnik , cislobody = secti_body_za_cislo ( cislo , aktivni_resitele , hlavni_problemy )
hlavni_problemy_slovnik , cislobody = secti_body_za_cislo ( cislo , aktivni_resitele , hlavni_problemy )
# získáme body za ročník, seznam obsahuje dvojice (řešitel_id, body) setřízené sestupně
# získáme body za ročník, seznam obsahuje dvojice (řešitel_id, body) setřízené sestupně
resitel_rocnikbody_sezn = secti_body_za_rocnik ( cislo , aktivni_resitele )
resitel_rocnikbody_sezn = secti_body_za_rocnik ( cislo . rocnik , aktivni_resitele )
# získáme body odjakživa
# získáme body odjakživa
resitel_odjakzivabody_slov = body_resitelu_odjakziva ( cislo . rocnik . druhy_rok ( ) ,
resitel_odjakzivabody_slov = body_resitelu_odjakziva ( cislo . rocnik ,
aktivni_resitele )
aktivni_resitele )
# řešitelé setřídění podle bodů za číslo sestupně
# řešitelé setřídění podle bodů za číslo sestupně
@ -768,22 +714,22 @@ def spocti_vysledkovku_cisla(cislo, context=None):
# získáme seznam bodů za problémy pro daného řešitele
# získáme seznam bodů za problémy pro daného řešitele
problemy = [ ]
problemy = [ ]
for hp in hlavni_problemy :
for hp in hlavni_problemy :
problemy . append ( hlavni_problemy_slovnik [ str ( hp . id ) ] [ ar_id ] )
problemy . append ( hlavni_problemy_slovnik [ hp . id ] [ ar_id ] )
# vytáhneme informace pro daného řešitele
# vytáhneme informace pro daného řešitele
radek = RadekVysledkovky (
radek = RadekVysledkovkyCisla (
poradi [ i ] , # pořadí
poradi [ i ] , # pořadí
Resitel . objects . get ( id = ar_id ) , # řešitel (z id)
Resitel . objects . get ( id = ar_id ) , # řešitel (z id)
problemy , # seznam bodů za hlavní problémy čísla
problemy , # seznam bodů za hlavní problémy čísla
cislobody [ ar_id ] , # body za číslo
cislobody [ ar_id ] , # body za číslo
setrizeni_resitele_body [ i ] , # body za ročník (spočítané výše s pořadím)
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
resitel_odjakzivabody_slov [ ar_id ] , # body odjakživa
cislo . rocnik ) # ročník semináře pro zjištění ročníku řešitele
print ( " {} : body za problémy - {} , číslobody - {} , ročníkbody - {} , odjakživabody - {} " . format ( radek . resitel ,
print ( " {} : body za problémy - {} , číslobody - {} , ročníkbody - {} , odjakživabody - {} " . format ( radek . resitel ,
radek . body_problemy_sezn , radek . body_cislo , radek . body_rocnik , radek . body_celkem_odjakziva ) )
radek . body_problemy_sezn , radek . body_cislo , radek . body_rocnik , radek . body_celkem_odjakziva ) )
radky_vysledkovky . append ( radek )
radky_vysledkovky . append ( radek )
print ( " Přikládám {} -tý řádek. " . format ( i ) )
print ( " Přikládám {} -tý řádek. " . format ( i ) )
i + = 1
i + = 1
print ( " Následuje předávání do kontextu. " )
# vytahané informace předáváme do kontextu
# vytahané informace předáváme do kontextu
context [ ' cislo ' ] = cislo
context [ ' cislo ' ] = cislo
context [ ' radky_vysledkovky ' ] = radky_vysledkovky
context [ ' radky_vysledkovky ' ] = radky_vysledkovky
@ -817,45 +763,8 @@ class CisloView(generic.DetailView):
cislo = context [ ' cislo ' ]
cislo = context [ ' cislo ' ]
# vrátíme context (aktuálně obsahuje jen věci ohledně výsledkovky
# vrátíme context (aktuálně obsahuje jen věci ohledně výsledkovky
return spocti_vysledkovku _cisla( cislo , context )
return vysledkovka _cisla( cislo , context )
# problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku()))
# #setridi problemy podle typu a poradi zadani
# problem_index = {}
# for i in range(len(problemy)):
# #umoznuje zjistit index podle id problemu
#
# vysledky_resitele = {}
# vysledkovka = []
#
# # doplníme některé údaje do řádků výsledkovky pro řešitele ve skupině
# for poradi, v in zip(sloupec_s_poradim(vysledky), vysledky):
# v.poradi = poradi
# v.body_celkem_rocnik = v.body
# v.body_celkem_odjakziva = VysledkyKCisluOdjakziva.objects.get(resitel=v.resitel, cislo=context['cislo']).body
# v.resitel.rocnik = v.resitel.rocnik(v.cislo.rocnik)
#
# # je tady '', aby se nezobrazovala 0, pokud se řešitel o řešení úlohy ani nepokusil
# v.body_ulohy = [''] * len(problemy)
#
# v.titul = v.resitel.get_titul(v.body_celkem_odjakziva)
#
# body_cislo_q = VysledkyZaCislo.objects.filter(resitel=v.resitel, cislo=context['cislo'])
# v.body_cislo = body_cislo_q[0].body if body_cislo_q else 0
#
# vysledkovka.append(v)
#
# # připravíme si odkaz na řádek, abychom do něj mohli doplnit body za jednotlivé úlohy
# vysledky_resitele[v.resitel.id] = v
#
# # za každé řešení doplníme k příslušnému řešiteli a úloze body
# for r in reseni:
# vysledky_resitele[r.resitel.id].body_ulohy[problem_index[r.problem.id]] = r.body
#
# context['vysledkovka'] = vysledkovka
# context['problemy'] = problemy
# context['v_cisle_zadane'] = v_cisle_zadane
# context['resene_problemy'] = resene_problemy
class ArchivTemataView ( generic . ListView ) :
class ArchivTemataView ( generic . ListView ) :
model = Problem
model = Problem
@ -864,25 +773,24 @@ class ArchivTemataView(generic.ListView):
### Generovani vysledkovky
### Generovani vysledkovky
#class CisloVysledkovkaView(CisloView):i
class CisloVysledkovkaView ( CisloView ) :
# poradi | titul. jmeno prijmeni | ulohy | za cislo | celkem | odjakziva
" View vytvořené pro stránku zobrazující výsledkovku čísla v TeXu. "
#
#
model = Cislo
#
template_name = ' seminar/archiv/cislo_vysledkovka.tex '
# model = Cislo
#content_type = 'application/x-tex; charset=UTF8'
# template_name = 'seminar/archiv/cislo_vysledkovka.tex'
#umozni rovnou stahnout TeXovsky dokument
# #content_type = 'application/x-tex; charset=UTF8'
content_type = ' text/plain; charset=UTF8 '
# #umozni rovnou stahnout TeXovsky dokument
#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
# content_type = 'text/plain; charset=UTF8'
# #vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
class RocnikVysledkovkaView ( RocnikView ) :
#
" View vytvořené pro stránku zobrazující výsledkovku ročníku v TeXu. "
#class RocnikVysledkovkaView(RocnikView):
model = Rocnik
# model = Rocnik
template_name = ' seminar/archiv/rocnik_vysledkovka.tex '
# template_name = 'seminar/archiv/rocnik_vysledkovka.tex'
#content_type = 'application/x-tex; charset=UTF8'
# #content_type = 'application/x-tex; charset=UTF8'
#umozni rovnou stahnout TeXovsky dokument
# #umozni rovnou stahnout TeXovsky dokument
content_type = ' text/plain; charset=UTF8 '
# content_type = 'text/plain; charset=UTF8'
#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
# #vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
### Generovani obalek
### Generovani obalek
class CisloObalkyStruct :
class CisloObalkyStruct :
@ -961,30 +869,31 @@ def oldObalkovaniView(request, rocnik, cislo):
### Tituly
### Tituly
# TODO udelat neco jako get_objects_or_404
def TitulyView ( request , rocnik , cislo ) :
# FIXME: prepsat, aby nepouzivalo VysledkyK...
rocnik_obj = Rocnik . objects . get ( rocnik = rocnik )
#def TitulyView(request, rocnik, cislo):
resitele = Resitel . objects . filter ( rok_maturity__gte = rocnik_obj . prvni_rok )
# rocnik_obj = Rocnik.objects.get(rocnik = rocnik)
cislo_obj = Cislo . objects . get ( rocnik = rocnik_obj , poradi = cislo )
# resitele = Resitel.objects.filter(rok_maturity__gte = rocnik_obj.prvni_rok)
# cislo_obj = Cislo.objects.get(rocnik = rocnik_obj, cislo = cislo)
asciijmena = [ ]
#
jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka), pokud ano, vrátí se jako true
# asciijmena = []
slovnik_s_body = body_resitelu_odjakziva ( rocnik_obj , resitele )
# broken = False
#
for resitel in resitele :
# for resitel in resitele:
resitel . titul = resitel . get_titul ( slovnik_s_body [ resitel . id ] )
# try:
jmeno = resitel . osoba . jmeno + resitel . osoba . prijmeni
# vys = VysledkyKCisluOdjakziva.objects.get(resitel = resitel, cislo = cislo_obj)
# převedeme jména a příjmení řešitelů do ASCII
# body = vys.body
ascii_jmeno_bytes = unicodedata . normalize ( ' NFKD ' , jmeno ) . encode ( " ascii " , " ignore " )
# except ObjectDoesNotExist:
# vrátí se byte string, převedeme na standardní string
# body = 0
ascii_jmeno_divnoznaky = str ( ascii_jmeno_bytes , " utf-8 " , " ignore " ) . replace ( " " , " " )
# resitel.titul = resitel.get_titul(body)
resitel . ascii = ' ' . join ( a for a in ascii_jmeno_divnoznaky if a . isalnum ( ) )
# resitel.ascii = unicodedata.normalize('NFKD',resitel.jmeno+resitel.prijmeni).encode("ascii","ignore").replace(" ","")
if resitel . ascii not in asciijmena :
# if resitel.ascii not in asciijmena:
asciijmena . append ( resitel . ascii )
# asciijmena.append(resitel.ascii)
else :
# else:
jmenovci = True
# broken = True
#
return render ( request , ' seminar/archiv/tituly.tex ' ,
# return render(request, 'seminar/archiv/tituly.tex',{'resitele': resitele,'broken':broken},content_type="text/plain")
{ ' resitele ' : resitele , ' jmenovci ' : jmenovci } , content_type = " text/plain " )
### Soustredeni
### Soustredeni