@ -61,7 +61,7 @@ class VlozBodyView(generic.ListView):
print ( self . tema )
self . problemy = Problem . objects . filter ( nadproblem = self . tema )
print ( self . problemy )
self . reseni = Reseni . objects . filter ( problem__in = self . problemy )
self . reseni = Reseni . objects . filter ( problem__in = self . problemy )
print ( self . reseni )
return self . reseni
@ -80,7 +80,7 @@ class ObalkovaniView(generic.ListView):
def get_context_data ( self , * * kwargs ) :
context = super ( ObalkovaniView , self ) . get_context_data ( * * kwargs )
print ( self . cislo )
context [ ' cislo ' ] = self . cislo
context [ ' cislo ' ] = self . cislo
return context
class TNLData ( object ) :
@ -106,18 +106,22 @@ class TreeNodeView(generic.DetailView):
return context
class AktualniZadaniView ( TreeNodeView ) :
def get_object ( self ) :
nastaveni = get_object_or_404 ( Nastaveni )
return nastaveni . aktualni_cislo . cislonode
def get_context_data ( self , * * kwargs ) :
nastaveni = get_object_or_404 ( Nastaveni )
context = super ( ) . get_context_data ( * * kwargs )
verejne = nastaveni . aktualni_cislo . verejne ( )
context [ ' verejne ' ] = verejne
return context
#def AktualniZadaniView(request):
# nastaveni = get_object_or_404(Nastaveni)
# verejne = nastaveni.aktualni_cislo.verejne()
# problemy = Problem.objects.filter(cislo_zadani=nastaveni.aktualni_cislo).filter(stav = 'zadany')
# ulohy = problemy.filter(typ = 'uloha').order_by('kod')
# serialy = problemy.filter(typ = 'serial').order_by('kod')
# jednorazove_problemy = [ulohy, serialy]
# return render(request, 'seminar/zadani/AktualniZadani.html',
# {'nastaveni': nastaveni,
# 'jednorazove_problemy': jednorazove_problemy,
# 'temata': verejna_temata(nastaveni.aktualni_rocnik),
# 'verejne': verejne,
# },
# )
#
#def ZadaniTemataView(request):
# nastaveni = get_object_or_404(Nastaveni)
# temata = verejna_temata(nastaveni.aktualni_rocnik)
@ -285,6 +289,7 @@ class CojemamOrganizatoriStariView(generic.ListView):
### Archiv
class ArchivView ( generic . ListView ) :
model = Rocnik
template_name = ' seminar/archiv/cisla.html '
@ -295,16 +300,13 @@ class ArchivView(generic.ListView):
vyska = 297 # px
sirka = 210 # px
# nejnovějších 10 zveřejněných čísel
cisla = Cislo . objects . filter ( verejne_db = True ) [ : 10 ]
# op = os.path, udělá z argumentů cestu
png_dir = op . join ( settings . MEDIA_ROOT , " cislo " , " png " )
# seznam [(url obrázku, číslo)]
urls = [ ]
# c je číslo, i je pořadí čísla
for i , c in enumerate ( cisla ) :
if not c . pdf :
continue
@ -396,7 +398,7 @@ def sloupec_s_poradim(seznam_s_body):
sloupec_s_poradim . append ( " {} . " . format ( aktualni_poradi ) )
# pokud je skupina větší, vypíšu rozsah
else :
sloupec_s_poradim . append ( " {} .– {} . " . format ( aktualni_poradi ,
sloupec_s_poradim . append ( " {} .– {} . " . format ( aktualni_poradi ,
aktualni_poradi + velikost_skupiny - 1 ) )
# zvětšíme aktuální pořadí o tolik, kolik pozic bylo přeskočeno
aktualni_poradi = aktualni_poradi + velikost_skupiny
@ -404,10 +406,10 @@ def sloupec_s_poradim(seznam_s_body):
## 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, cislo, soucet):
# # sečteme body za daný problém přes všechna řešení daného problému
# # sečteme body za daný problém přes všechna řešení daného problému
# # od daného řešitele
# reseni_resitele = s.Reseni_Resitele.objects.filter(resitele=resitel)
# hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele,
# hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele,
# cislo_body=cislo)
# # XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains
# # nebo in
@ -415,7 +417,7 @@ def sloupec_s_poradim(seznam_s_body):
# soucet += r.body
#
# # a přičteme k tomu hodnocení všech podproblémů
# for p in problem.podproblem.all():
# 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
@ -433,14 +435,15 @@ def hlavni_problem(problem):
# 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 . select_related ( ' problem ' , ' reseni ' ) . all ( ) # hodnocení, která se vážou k danému číslu
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čí
# hlavní problémy čísla
# hlavní problémy čísla
# (mají vlastní sloupeček ve výsledkovce, nemají nadproblém)
hlavni_problemy = [ ]
for p in problemy :
@ -450,16 +453,16 @@ def hlavni_problemy_cisla(cislo):
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 t1, t2, c3, ...
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
# POZOR! Aktuálně počítá jen za posledních 10 let od zadaného ročníku
# # Body za posledních 10 let je dobrá aproximace pro naše potřeby (výsledkovka
# # s aktivními řešiteli)
#
@ -497,38 +500,6 @@ def body_resitelu_za_rocnik(rocnik, aktivni_resitele):
pricti_body ( body_za_rocnik , resitel , hodn . body )
return body_za_rocnik
#def body_resitele_odjakziva(resitel):
# body = 0
# resitelova_hodnoceni = Hodnoceni.objects.select_related('body').all().filter(reseni_resitele=resitel)
# # TODO: v radku nahore chceme _in nebo _contains
# for hodnoceni in resitelova_hodnoceni:
# body = body + hodnoceni.body
# return body
# 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)
# body_resitele = 0
# for h in hlavni_problemy:
# body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, 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, do_cisla=None):
# # pokud do_cisla=None, tak do posledního čísla v ročníku
# # do_cisla je objekt Cislo
# cisla = rocnik.cisla.all() # funkce vrátí pole objektů
# # Cislo už lexikograficky setřízené, viz models
# body = 0
# for cislo in cisla:
# if cislo.poradi == do_cisla.poradi: break
# # druhá část zaručuje, že máme výsledky do daného čísla včetně
# body = body + body_resitele_v_cisle(resitel, cislo)
# return body
# TODO: předělat na nový model
#def vysledkovka_rocniku(rocnik, jen_verejne=True):
# """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve
@ -662,6 +633,120 @@ def pricti_body(slovnik, resitel, body):
slovnik [ str ( resitel . id ) ] + = body
def secti_body_za_rocnik ( cislo , aktivni_resitele ) :
# 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 )
# 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 ( ) ,
key = lambda x : x [ 1 ] , reverse = True )
return resitel_rocnikbody_sezn
# 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 ) :
# 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ů)
hlavni_problemy_slovnik = { }
for hp in hlavni_problemy :
hlavni_problemy_slovnik [ str ( hp . id ) ] = { }
# zakládání prázdných záznamů pro řešitele
cislobody = { }
for ar in aktivni_resitele :
# řešitele převedeme na řetězec pomocí unikátního id
cislobody [ str ( ar . id ) ] = " "
for hp in hlavni_problemy :
slovnik = hlavni_problemy_slovnik [ str ( hp . id ) ]
slovnik [ str ( ar . id ) ] = " "
# 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 )
nadproblem_slovnik = hlavni_problemy_slovnik [ str ( nadproblem . 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 ( ) ) :
pricti_body ( cislobody , resitel , body )
pricti_body ( nadproblem_slovnik , resitel , body )
return hlavni_problemy_slovnik , cislobody
def spocti_vysledkovku_cisla ( cislo , context = None ) :
if context is None :
context = { }
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
# 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 = list ( Resitel . objects . filter (
rok_maturity__gte = cislo . rocnik . druhy_rok ( ) ) )
# TODO: zkusit hodnoceni__rocnik...
#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik)
# získáme body za číslo
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ě
resitel_rocnikbody_sezn = secti_body_za_rocnik ( cislo , aktivni_resitele )
# 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 ]
# spočítáme pořadí řešitelů
setrizeni_resitele_body = [ dvojice [ 1 ] for dvojice in resitel_rocnikbody_sezn ]
poradi = sloupec_s_poradim ( setrizeni_resitele_body )
# vytvoříme jednotlivé sloupce výsledkovky
radky_vysledkovky = [ ]
i = 0
for ar_id in setrizeni_resitele_id :
# získáme seznam bodů za problémy pro daného řešitele
problemy = [ ]
for hp in hlavni_problemy :
problemy . append ( hlavni_problemy_slovnik [ str ( hp . id ) ] [ ar_id ] )
# vytáhneme informace pro daného řešitele
radek = RadekVysledkovky (
poradi [ i ] , # pořadí
Resitel . objects . get ( id = ar_id ) , # řešitel (z id)
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
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 ) )
radky_vysledkovky . append ( radek )
print ( " Přikládám {} -tý řádek. " . format ( i ) )
i + = 1
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
print ( " Předávám kontext. " )
return context
class CisloView ( generic . DetailView ) :
model = Cislo
template_name = ' seminar/archiv/cislo.html '
@ -685,101 +770,8 @@ class CisloView(generic.DetailView):
context = super ( CisloView , self ) . get_context_data ( * * kwargs )
cislo = context [ ' cislo ' ]
hlavni_problemy = hlavni_problemy_cisla ( cislo )
# 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ů)
hlavni_problemy_slovnik = { }
for hp in hlavni_problemy :
hlavni_problemy_slovnik [ str ( hp . id ) ] = { }
## 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
# 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 = 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
cislobody = { }
for ar in aktivni_resitele :
# řešitele převedeme na řetězec pomocí unikátního id
cislobody [ str ( ar . id ) ] = " "
for hp in hlavni_problemy :
slovnik = hlavni_problemy_slovnik [ str ( hp . id ) ]
slovnik [ str ( ar . id ) ] = " "
# 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 )
nadproblem_slovnik = hlavni_problemy_slovnik [ str ( nadproblem . id ) ]
# a více hodnocení
for hodn in list ( reseni . hodnoceni_set . 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 ] ,
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
print ( " Předávám kontext. " )
return context
# vrátíme context (aktuálně obsahuje jen věci ohledně výsledkovky
return spocti_vysledkovku_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
@ -1006,7 +998,7 @@ def soustredeniUcastniciExportView(request,soustredeni):
class ClankyResitelView ( generic . ListView ) :
model = Problem
template_name = ' seminar/clanky/resitelske_clanky.html '
queryset = Clanek . objects . filter ( stav = Problem . STAV_ZADANY , resitelsky = True ) . select_related ( ' cislo__rocnik ' ) . order_by ( ' -cislo__rocnik__rocnik ' , ' kod ' )
queryset = Clanek . objects . filter ( stav = Problem . STAV_ZADANY ) . select_related ( ' cislo_zadani __rocnik ' ) . order_by ( ' -cislo_zadani __rocnik__rocnik ' , ' kod ' )
# FIXME: pokud chceme orgoclanky, tak nejak zavest do modelu a podle toho odkomentovat a upravit
#class ClankyOrganizatorView(generic.ListView)<F12>:
@ -1292,7 +1284,7 @@ def loginView(request):
if request . method == ' POST ' :
form = LoginForm ( request . POST )
if form . is_valid ( ) :
user = authenticate ( request ,
user = authenticate ( request ,
username = form . cleaned_data [ ' username ' ] ,
password = form . cleaned_data [ ' password ' ] )
print ( form . cleaned_data )
@ -1300,8 +1292,8 @@ def loginView(request):
login ( request , user )
return HttpResponseRedirect ( ' / ' )
else :
return render ( request ,
' seminar/login.html ' ,
return render ( request ,
' seminar/login.html ' ,
{ ' form ' : form , ' login_error ' : ' Neplatné jméno nebo heslo ' } )
else :
@ -1319,7 +1311,7 @@ def logoutView(request):
def prihlaska_log_gdpr_safe ( logger , gdpr_logger , msg , form_data ) :
msg = " {} , form_hash: {} " . format ( msg , hash ( form_data ) )
logger . warn ( msg )
gdpr_logger . warn ( msg + " , form: {} " . format ( form_data ) )
gdpr_logger . warn ( msg + " , form: {} " . format ( form_data ) )
from django . forms . models import model_to_dict
def resitelEditView ( request ) :
@ -1329,7 +1321,7 @@ def resitelEditView(request):
osoba_edit = Osoba . objects . get ( user = u )
resitel_edit = osoba_edit . resitel
user_edit = osoba_edit . user
## Vytvoření slovníku, kterým předvyplním formulář
## Vytvoření slovníku, kterým předvyplním formulář
prefill_1 = model_to_dict ( user_edit )
prefill_2 = model_to_dict ( resitel_edit )
prefill_3 = model_to_dict ( osoba_edit )
@ -1387,7 +1379,7 @@ def prihlaskaView(request):
fcd = form . cleaned_data
form_hash = hash ( fcd )
form_logger . info ( fcd , form_hash = form_hash )
with transaction . atomic ( ) :
u = User . objects . create_user (
username = fcd [ ' username ' ] ,
@ -1426,7 +1418,7 @@ def prihlaskaView(request):
rok_maturity = fcd [ ' rok_maturity ' ] ,
zasilat = fcd [ ' zasilat ' ]
)
r . save ( )
r . osoba = o
if fcd . get ( ' skola ' ) :