From c499d823f9d2d2e28a3b4d8f443030e2800d0178 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 15 Apr 2020 22:30:58 +0200 Subject: [PATCH] =?UTF-8?q?Dokon=C4=8Dena=20oprava=20v=C3=BDsledkovek=20?= =?UTF-8?q?=C4=8D=C3=ADsla=20a=20ro=C4=8Dn=C3=ADku=20=20-=20generov=C3=A1n?= =?UTF-8?q?=C3=AD=20TeXu.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seminar/archiv/cislo_vysledkovka.tex | 4 +- .../seminar/archiv/rocnik_vysledkovka.tex | 7 +- .../templates/seminar/vysledkovka_rocnik.html | 2 +- seminar/urls.py | 16 +- seminar/views/views_all.py | 168 +++++------------- 5 files changed, 57 insertions(+), 140 deletions(-) diff --git a/seminar/templates/seminar/archiv/cislo_vysledkovka.tex b/seminar/templates/seminar/archiv/cislo_vysledkovka.tex index 68baec9b..b374864c 100644 --- a/seminar/templates/seminar/archiv/cislo_vysledkovka.tex +++ b/seminar/templates/seminar/archiv/cislo_vysledkovka.tex @@ -1,9 +1,9 @@ \setlength{\tabcolsep}{3pt} \begin{longtable}{|r|l|c|r|{% for p in problemy %}c@{\hskip.5em}{% endfor %}|r|r|}\hline -& & & & \multicolumn{ {{ problemy|length}} }{c|}{\textbf{Úlohy}} & & \\\textbf{Poř.}& \textbf{Jméno}& \textbf{R.}& \raisebox{0.7mm}{$\sum_{-1}$}& {% for p in problemy %}{% if p.typ == "uloha" %}\textbf{r{{p.kod}}}&{% elif p.typ == "tema" %}\textbf{t{{p.kod}}}&{% else %}\textbf{ {{p.kod}} }&{% endif %}{% endfor %}\raisebox{0.7mm}{$\sum_0$}&\raisebox{0.7mm}{$\sum_1$}\\\hline +& & & & \multicolumn{ {{ problemy|length}} }{c|}{\textbf{Úlohy}} & & \\\textbf{Poř.}& \textbf{Jméno}& \textbf{R.}& \raisebox{0.7mm}{$\sum_{-1}$}& {% for p in problemy %}\textbf{ {{ p.kod_v_rocniku }} }&{% endfor %}\raisebox{0.7mm}{$\sum_0$}&\raisebox{0.7mm}{$\sum_1$}\\\hline \endhead \hline \endfoot -{% for rv in vysledkovka %}{{rv.poradi}}&{% if rv.titul %}\titul{ {{ rv.titul}}}{% endif %}{{rv.resitel.inicial_krestni}} {{rv.resitel.prijmeni}}&{{rv.resitel.rocnik|default:""}}&{{rv.body_celkem_odjakziva}}&{% for b in rv.body_ulohy %}{{b}}&{% endfor %}{{rv.body_cislo}}&{{rv.body_celkem_rocnik|default:0}}\\ +{% for rv in radky_vysledkovky %}{{rv.poradi}}&{% if rv.titul %}\titul{ {{ rv.titul}}}{% endif %}{{rv.resitel.osoba.jmeno|slice:":1"}}. {{rv.resitel.osoba.prijmeni}}&{{rv.rocnik_resitele|default:""}}&{{rv.body_celkem_odjakziva}}&{% for b in rv.body_problemy_sezn %}{{b}}&{% endfor %}{{rv.body_cislo}}&{{rv.body_rocnik|default:0}}\\ {% endfor %} \end{longtable} diff --git a/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex b/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex index 4218de57..61c9abbb 100644 --- a/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex +++ b/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex @@ -1,13 +1,12 @@ {% with lb="{" %} {% with rb="}" %} \setlength{\tabcolsep}{3pt} -\begin{longtable}{|r|l|c|r|{% for cislo in vysledkovka.cisla %}c{% if not forloop.last %}@{\hskip.5em}{% endif %}{% endfor %}|r|} -\hline -& & & & \multicolumn{{ lb }}{{ vysledkovka.cisla|length }}}{c|}{\textbf{Číslo}} & \\\textbf{Poř.} & \textbf{Jméno} & \textbf{R.} & \raisebox{0.7mm}{$\sum_{-1}$} & {% for cislo in vysledkovka.cisla %}\textbf{{ lb }}{{ cislo.cislo }}{{ rb }} & {% endfor %}\raisebox{0.7mm}{$\sum_1$} \\\hline +\begin{longtable}{|r|l|c|r|{% for cislo in cisla %}c{% if not forloop.last %}@{\hskip.5em}{% endif %}{% endfor %}|r|}\hline +& & & & \multicolumn{{ lb }}{{ cisla|length }}}{c|}{\textbf{Číslo}} & \\\textbf{Poř.} & \textbf{Jméno} & \textbf{R.} & \raisebox{0.7mm}{$\sum_{-1}$} & {% for cislo in cisla %}\textbf{{ lb }}{{ cislo.poradi }}{{ rb }} & {% endfor %}\raisebox{0.7mm}{$\sum_1$} \\\hline \endhead \hline \endfoot -{% for rv in radky_vysledkovky %}{{ rv.poradi }} & {% if rv.titul %}\titul{{ lb }}{{ rv.titul }}}~{% endif %}{{ rv.resitel.osoba.jmeno|slice:":1" }}.~{{ rv.resitel.osoba.prijmeni }} & {% if rv.resitel.rocnik %}{{ rv.resitel.rocnik }}.{% endif %} & {{ rv.body_odjakziva }} {% for b in rv.body_cisla_sezn %} & {{ b }}{% endfor %} & {{ rv.body_rocnik }} \\ +{% for rv in radky_vysledkovky %}{{ rv.poradi }} & {% if rv.titul %}\titul{{ lb }}{{ rv.titul }}}~{% endif %}{{ rv.resitel.osoba.jmeno|slice:":1" }}.~{{ rv.resitel.osoba.prijmeni }} & {% if rv.rocnik_resitele %}{{ rv.rocnik_resitele }}{% endif %} & {{ rv.body_celkem_odjakziva }} {% for b in rv.body_cisla_sezn %} & {{ b }}{% endfor %} & {{ rv.body_rocnik }} \\ {% endfor %}\end{longtable} {% endwith %} {% endwith %} diff --git a/seminar/templates/seminar/vysledkovka_rocnik.html b/seminar/templates/seminar/vysledkovka_rocnik.html index 424f805b..db9e848a 100644 --- a/seminar/templates/seminar/vysledkovka_rocnik.html +++ b/seminar/templates/seminar/vysledkovka_rocnik.html @@ -18,7 +18,7 @@ {{ rv.titul }}MM {% endif %} {{ rv.resitel.osoba.plne_jmeno }} - {{ rv.resitel.rocnik }} + {{ rv.rocnik_resitele }} {{ rv.body_celkem_odjakziva }} {% for b in rv.body_cisla_sezn %} {{ b }} diff --git a/seminar/urls.py b/seminar/urls.py index adf2cea5..2db6d367 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -75,13 +75,15 @@ urlpatterns = [ path('aesop-export/index.csv', export.ExportIndexView.as_view(), name='seminar_export_index'), # Stranky viditelne pouze pro orgy: - #path( - # 'rocnik/(?P\d+)/vysledkovka.tex', - # staff_member_required(views.RocnikVysledkovkaView.as_view()), - # name='seminar_cislo_vysledkovka' - #), - #path('cislo/(?P\d+).(?P[0-9-]+)/vysledkovka.tex', - # staff_member_required(views.CisloVysledkovkaView.as_view()), name='seminar_cislo_vysledkovka'), + path( + 'rocnik//vysledkovka.tex', + staff_member_required(views.RocnikVysledkovkaView.as_view()), + name='seminar_rocnik_vysledkovka' + ), + path('cislo/./vysledkovka.tex', + staff_member_required(views.CisloVysledkovkaView.as_view()), + name='seminar_cislo_vysledkovka' + ), path('cislo/./obalky.pdf', staff_member_required(views.cisloObalkyView), name='seminar_cislo_obalky'), diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index e72f23aa..bb078614 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -39,6 +39,7 @@ import traceback import sys import csv import logging +import time def verejna_temata(rocnik): @@ -536,26 +537,26 @@ def body_resitelu_odjakziva(rocnik, resitele): # Body za posledních 10 let je dobrá aproximace pro naše potřeby (výsledkovka # s aktivními řešiteli) - body_pred_roky = [] - rok = rocnik.prvni_rok - rocniky = Rocnik.objects.filter(prvni_rok__gt=rok-11) - for roc in rocniky: - body_pred_roky.append(body_resitelu_za_rocnik(roc, resitele)) - - for r in resitele: - for i in range(0,10): - body_odjakziva[str(r.id)] += body_pred_roky[i][str(r.id)] + #body_pred_roky = [] + #rok = rocnik.prvni_rok + #rocniky = Rocnik.objects.filter(prvni_rok__gt=rok-11) + #for roc in rocniky: + # body_pred_roky.append(body_resitelu_za_rocnik(roc, 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é: # (důsledek toho, že dotazy na joinování databázových tabulek jsou kvadratické) -# 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) + 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 # vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník @@ -566,24 +567,28 @@ 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 + print("Před dotazem:{}".format(time.time())) 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 resitel in res.resitele.all(): for hodn in res.hodnoceni_set.all(): pricti_body(body_za_rocnik, resitel, hodn.body) + print("Po for-cyklu:{}".format(time.time())) return body_za_rocnik class RadekVysledkovkyRocniku(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_cisla_sezn, body_rocnik, body_odjakziva): + def __init__(self, poradi, resitel, body_cisla_sezn, body_rocnik, body_odjakziva, rok): self.poradi = poradi self.resitel = resitel + self.rocnik_resitele = resitel.rocnik(rok) self.body_rocnik = body_rocnik self.body_celkem_odjakziva = body_odjakziva self.body_cisla_sezn = body_cisla_sezn - self.titul = resitel.get_titul(body_odjakziva) + elf.titul = resitel.get_titul(body_odjakziva) def vysledkovka_rocniku(rocnik, jen_verejne=True): """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve @@ -632,7 +637,8 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): 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 + 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)) @@ -643,59 +649,6 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): return radky_vysledkovky - #vyberu vsechny vysledky z rocniku -# cisla_v_rocniku = VysledkyKCisluZaRocnik.objects.filter(cislo__rocnik=rocnik).order_by('cislo') -# if jen_verejne: -# cisla_v_rocniku = cisla_v_rocniku.filter(cislo__verejna_vysledkovka=True) -# -# #pokud žádné nejsou, výsledkovka se nezobrazí -# if not cisla_v_rocniku: -# return None -# -# #vybere vsechny vysledky z posledniho (verejneho) cisla a setridi sestupne dle bodu -# vysledky = list(cisla_v_rocniku.filter(cislo = cisla_v_rocniku[0].poradi).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno').select_related('resitel')) -# -# class Vysledkovka: -# def __init__(self): -# self.rocnik = rocnik.rocnik -# self.radky = [] -# self.cisla = [] -# -# vysledkovka = Vysledkovka() -# vysledkovka.cisla = (rocnik.verejne_vysledkovky_cisla() if jen_verejne else rocnik.cisla.all().order_by('cislo')) -# -# # 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.resitel.rocnik = v.resitel.rocnik(rocnik) -# -# verejne_vysl_odjakziva = VysledkyKCisluOdjakziva.objects.filter(cislo__rocnik=rocnik, cislo=cisla_v_rocniku[0].poradi) -# if jen_verejne: -# verejne_vysl_odjakziva = verejne_vysl_odjakziva.filter(cislo__verejna_vysledkovka=True) -# -# v.body_odjakziva = verejne_vysl_odjakziva.filter(resitel = v.resitel)[0].body -# v.titul = v.resitel.get_titul(v.body_odjakziva) -# v.body_rocnik = v.body -# v.body_cisla = [] -# -# #pokud pro dany rok a cislo nema resitel vysledky, ma defaultne 0 -# for cis in vysledkovka.cisla: -# if not jen_verejne or cis.verejna_vysledkovka: -# #seznam vysledku se spravnym rocnikem a cislem pro resitele -# #zobrazim jen je-li vysledkovka verejna -# body_za_cislo = VysledkyZaCislo.objects.filter(cislo__rocnik=rocnik).filter(cislo = cis).filter(resitel = v.resitel) -# if body_za_cislo: -# #neprazdne vysledky by mely obsahovat prave jeden vysledek -# v.body_cisla.append(body_za_cislo[0].body) -# else: -# #resitel nema za cislo body -# v.body_cisla.append(0) -# -# vysledkovka.radky.append(v) -# -# return vysledkovka - - class RocnikView(generic.DetailView): model = Rocnik template_name = 'seminar/archiv/rocnik.html' @@ -723,7 +676,8 @@ class RocnikView(generic.DetailView): 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['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) @@ -754,8 +708,9 @@ class RadekVysledkovkyCisla(object): Umožňuje snazší práci v templatu (lepší, než seznam).""" 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.rocnik_resitele = resitel.rocnik(rok) self.body_cislo = body_cislo self.body_rocnik = body_rocnik self.body_celkem_odjakziva = body_odjakziva @@ -826,7 +781,6 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): pricti_body(cislobody, resitel, body) pricti_body(nadproblem_slovnik, resitel, body) return hlavni_problemy_slovnik, cislobody - def vysledkovka_cisla(cislo, context=None): if context is None: @@ -874,14 +828,14 @@ def vysledkovka_cisla(cislo, context=None): 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 + 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, 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 @@ -917,43 +871,6 @@ class CisloView(generic.DetailView): # vrátíme context (aktuálně obsahuje jen věci ohledně výsledkovky 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): model = Problem @@ -962,19 +879,18 @@ class ArchivTemataView(generic.ListView): ### Generovani vysledkovky -#class CisloVysledkovkaView(CisloView):i -# poradi | titul. jmeno prijmeni | ulohy | za cislo | celkem | odjakziva -# -# -# -# model = Cislo -# template_name = 'seminar/archiv/cislo_vysledkovka.tex' -# #content_type = 'application/x-tex; charset=UTF8' -# #umozni rovnou stahnout TeXovsky dokument -# content_type = 'text/plain; charset=UTF8' -# #vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani -# +class CisloVysledkovkaView(CisloView): + "View vytvořené pro stránku zobrazující výsledkovku čísla v TeXu." + + model = Cislo + template_name = 'seminar/archiv/cislo_vysledkovka.tex' + #content_type = 'application/x-tex; charset=UTF8' + #umozni rovnou stahnout TeXovsky dokument + 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." model = Rocnik template_name = 'seminar/archiv/rocnik_vysledkovka.tex' #content_type = 'application/x-tex; charset=UTF8'