Browse Source

views: skoro funkční výsledkovka, problémy s body odjakživa, dotazy do databáze už jinak rozumně rychlé

export_seznamu_prednasek
Anet 5 years ago
parent
commit
64074d5dc6
  1. 100
      seminar/views/views_all.py

100
seminar/views/views_all.py

@ -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,14 +664,27 @@ 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
template_name = 'seminar/archiv/cislo.html'
@ -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)
# ř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)]
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
# 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()))

Loading…
Cancel
Save