Browse Source

nepadající (ale nezobrazující se) verze výsledkovky v2

export_seznamu_prednasek
Anet 5 years ago
parent
commit
caa274460d
  1. 16
      seminar/templates/seminar/archiv/cislo.html
  2. 233
      seminar/views.py

16
seminar/templates/seminar/archiv/cislo.html

@ -67,21 +67,21 @@
{% endfor %} {% endfor %}
<th class='border-r'>Za číslo</sup> <th class='border-r'>Za číslo</sup>
<th class='border-r'>Za ročník <th class='border-r'>Za ročník
<th class='border-r'>Odjakživa {#<th class='border-r'>Odjakživa#}
{% for rv in vysledkovka %} {% for rv in radky_vysledkovky %}
<tr> <tr>
<td class='border-r'>{% autoescape off %}{{ rv.poradi }}{% endautoescape %} <td class='border-r'>{% autoescape off %}{{ rv.poradi }}{% endautoescape %}
<th class='border-r'> <th class='border-r'>
{% if rv.titul %} {% if rv.resitel.get_titul != "" %}
{{ rv.titul }}<sup>MM</sup> {{ rv.resitel.get_titul }}<sup>MM</sup>
{% endif %} {% endif %}
{{ rv.resitel.plne_jmeno }} {{ rv.resitel.osoba.plne_jmeno }}
{% for b in rv.body_ulohy %} {% for b in rv.hlavni_problemy_body %}
<td class='border-r'>{{ b }} <td class='border-r'>{{ b }}
{% endfor %} {% endfor %}
<td class='border-r'>{{ rv.body_cislo }} <td class='border-r'>{{ rv.body_cislo }}
<td class='border-r'><b>{{ rv.body_celkem_rocnik }}</b> <td class='border-r'><b>{{ rv.body_rocnik }}</b>
<td class='border-r'>{{ rv.body_celkem_odjakziva }} {# <td class='border-r'>{{ rv.body_celkem_odjakziva }}#}
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

233
seminar/views.py

@ -426,28 +426,34 @@ 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 ## 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): #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 # # od daného řešitele
reseni_resitele = Reseni.objects.filter(resitele__in=resitel) # 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) # cislo_body=cislo)
# XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains # # XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains
# nebo in # # nebo in
for r in hodnoceni_resitele: # for r in hodnoceni_resitele:
soucet += r.body # soucet += r.body
#
# a přičteme k tomu hodnocení všech podproblémů # # 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ů # # i přes jméno by to měla být množina jeho podproblémů
soucet += __soucet_resitele_problemu(p, resitel, soucet) # soucet += __soucet_resitele_problemu(p, resitel, soucet)
return soucet # return soucet
# spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele ## 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): #def body_resitele_problemu_v_cisle(problem, resitel, cislo):
# probably FIXED: nezohledňuje číslo, do kterého se body počítají # # probably FIXED: nezohledňuje číslo, do kterého se body počítají
return __soucet_resitele_problemu(problem, resitel, cislo, 0) # return __soucet_resitele_problemu(problem, resitel, cislo, 0)
# pro daný problém vrátí jeho nejvyšší nadproblém
def hlavni_problem(problem):
while not(problem.nadproblem == None):
problem = problem.nadproblem
return problem
# 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):
@ -463,9 +469,7 @@ def hlavni_problemy_cisla(cislo):
# (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) # (mají vlastní sloupeček ve výsledkovce, nemají nadproblém)
hlavni_problemy = [] hlavni_problemy = []
for p in problemy: for p in problemy:
while not(p.nadproblem == None): hlavni_problemy.append(hlavni_problem(p))
p = p.nadproblem
hlavni_problemy.append(p)
# zunikátnění # zunikátnění
hlavni_problemy_set = set(hlavni_problemy) hlavni_problemy_set = set(hlavni_problemy)
@ -474,38 +478,54 @@ def hlavni_problemy_cisla(cislo):
return hlavni_problemy return hlavni_problemy
def body_resitele_odjakziva(resitel): # vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník
body = 0 def body_resitelu_za_rocnik(rocnik, aktivni_resitele):
resitelova_hodnoceni = Hodnoceni.objects.select_related('body').all().filter(reseni_resitele=resitel) body_za_rocnik = {}
# TODO: v radku nahore chceme _in nebo _contains # inicializujeme na 0 pro všechny aktivní řešitele
for hodnoceni in resitelova_hodnoceni: for ar in aktivni_resitele:
body = body + hodnoceni.body body_za_rocnik[str(ar.id)] = 0
return body
# 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)
for res in reseni:
for resitel in res.resitele.all():
for hodn in res.hodnoceni.all():
body_za_rocnik[str(resitel.id)] += 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 # spočítá součet všech bodů řešitele za dané číslo
def body_resitele_v_cisle(resitel, cislo): #def body_resitele_v_cisle(resitel, cislo):
hlavni_problemy = hlavni_problemy_cisla(cislo) # hlavni_problemy = hlavni_problemy_cisla(cislo)
body_resitele = 0 # body_resitele = 0
for h in hlavni_problemy: # for h in hlavni_problemy:
body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, resitel, cislo) # 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 # # 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? # # ř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. # # Tady to ale nevadí, tady se počítá součet za číslo.
return body_resitele # return body_resitele
# spočítá součet všech bodů řešitele za daný rok (nebo jen do daného čísla včetně) # 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): #def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None):
# pokud do_cisla=None, tak do posledního čísla v ročníku # # pokud do_cisla=None, tak do posledního čísla v ročníku
# do_cisla je objekt Cislo # # do_cisla je objekt Cislo
cisla = rocnik.cisla.all() # funkce vrátí pole objektů # cisla = rocnik.cisla.all() # funkce vrátí pole objektů
# Cislo už lexikograficky setřízené, viz models # # Cislo už lexikograficky setřízené, viz models
body = 0 # body = 0
for cislo in cisla: # for cislo in cisla:
if cislo.poradi == do_cisla.poradi: break # if cislo.poradi == do_cisla.poradi: break
# druhá část zaručuje, že máme výsledky do daného čísla včetně # # druhá část zaručuje, že máme výsledky do daného čísla včetně
body = body + body_resitele_v_cisle(resitel, cislo) # body = body + body_resitele_v_cisle(resitel, cislo)
return body # return body
# TODO: předělat na nový model
#def vysledkovka_rocniku(rocnik, jen_verejne=True): #def vysledkovka_rocniku(rocnik, jen_verejne=True):
# """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve # """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve
# formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" # formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html"
@ -612,19 +632,17 @@ class ProblemView(generic.DetailView):
return context return context
class VysledkyResitele(object): class RadekVysledkovky(object):
"""Pro daného řešitele ukládá počet bodů za jednotlivé úlohy a celkový """Obsahuje věci, které se hodí vědět při konstruování výsledkovky.
počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" Umožňuje snazší práci v templatu (lepší, než seznam)."""
def __init__(self, resitel, cislo, rocnik): def __init__(self, poradi, resitel, body_problemy_sezn, body_cislo, body_rocnik):
self.resitel = resitel self.resitel = resitel
self.cislo = cislo self.body_cislo = body_cislo
self.body_cislo = body_resitele_v_cisle(resitel, cislo) self.body_rocnik = body_rocnik
self.body = [] # TODO self.body_celkem_odjakziva = odjakziva
self.rocnik = rocnik self.poradi = poradi
self.body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) self.body_problemy_sezn = body_problemy_sezn
self.body_celkem_odjakziva = resitel.vsechny_body()
self.poradi = 0
class CisloView(generic.DetailView): class CisloView(generic.DetailView):
model = Cislo model = Cislo
@ -648,38 +666,84 @@ class CisloView(generic.DetailView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(CisloView, self).get_context_data(**kwargs) context = super(CisloView, self).get_context_data(**kwargs)
## TODO upravit dle nového modelu
cislo = context['cislo'] cislo = context['cislo']
hlavni_problemy = hlavni_problemy_cisla(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 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
## chceme letos něco poslal # 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( aktivni_resitele = Resitel.objects.filter(
rok_maturity__gte=cislo.rocnik.druhy_rok()) rok_maturity__gte=cislo.rocnik.druhy_rok())
# TODO: zkusit hodnoceni__rocnik... # TODO: zkusit hodnoceni__rocnik...
#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik)
radky_vysledkovky = [] # zakládání prázdných záznamů pro řešitele
cislobody = {}
for ar in aktivni_resitele: for ar in aktivni_resitele:
# získáme výsledky řešitele - součty přes číslo a ročník # řešitele převedeme na řetězec pomocí unikátního id
vr = VysledkyResitele(ar, cislo, cislo.rocnik) cislobody[str(ar.id)] = ""
for hp in hlavni_problemy: for hp in hlavni_problemy:
vr.body.append( slovnik = hlavni_problemy_slovnik[str(hp.id)]
body_resitele_problemu_v_cisle(hp, ar, cislo)) slovnik[str(ar.id)] = ""
radky_vysledkovky.append(vr)
# vezmeme všechna řešení s body do daného čísla
# setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů reseni_do_cisla = Reseni.objects.filter(hodnoceni__cislo_body=cislo)
radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True)
# projdeme všechna řešení do čísla a přičteme body každému řešiteli do celkových
# generujeme sloupec s pořadím pomocí stejně zvané funkce # bodů i do bodů za problém
pocty_bodu = [rv.body_rocnik for rv in radky_vysledkovky] for reseni in reseni_do_cisla:
sloupec_poradi = sloupec_s_poradim(pocty_bodu) 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
# 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)
# ř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 = []
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
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)
# pořadí určíme pomocí funkce, které dáme celkové body za ročník vzestupně
poradi = sloupec_s_poradim(rocnik_body)
# každému řádku výsledkovky přidáme jeho pořadí radky_vysledkovky = []
i = 0 for i in range(0, len(setrizeni_resitele_id)):
for rv in radky_vysledkovky: radek = RadekVysledkovky(poradi[i], setrizeni_resitele[i],
rv.poradi = sloupec_poradi[i] hlavni_problemy_body[i], cislo_body[i], rocnik_body[i])
i = i + 1 radky_vysledkovky.append(radek)
# vytahané informace předáváme do kontextu # vytahané informace předáváme do kontextu
context['cislo'] = cislo context['cislo'] = cislo
@ -689,7 +753,6 @@ class CisloView(generic.DetailView):
# context['resene_problemy'] = resene_problemy # context['resene_problemy'] = resene_problemy
#XXX testovat #XXX testovat
#XXX opravit to, že se nezobrazují body za jednotlivé úlohy #XXX opravit to, že se nezobrazují body za jednotlivé úlohy
return context return context
# problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku())) # problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku()))

Loading…
Cancel
Save