Browse Source

Výsledkovka čísla přesunuta do funkce a rozsekána na menší kusy, optimalizace kódu.

export_seznamu_prednasek
Anet 5 years ago
parent
commit
3b328e4b00
  1. 202
      seminar/views/views_all.py

202
seminar/views/views_all.py

@ -106,18 +106,22 @@ class TreeNodeView(generic.DetailView):
return context 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): #def ZadaniTemataView(request):
# nastaveni = get_object_or_404(Nastaveni) # nastaveni = get_object_or_404(Nastaveni)
# temata = verejna_temata(nastaveni.aktualni_rocnik) # temata = verejna_temata(nastaveni.aktualni_rocnik)
@ -285,6 +289,7 @@ class CojemamOrganizatoriStariView(generic.ListView):
### Archiv ### Archiv
class ArchivView(generic.ListView): class ArchivView(generic.ListView):
model = Rocnik model = Rocnik
template_name='seminar/archiv/cisla.html' template_name='seminar/archiv/cisla.html'
@ -295,16 +300,13 @@ class ArchivView(generic.ListView):
vyska = 297 # px vyska = 297 # px
sirka = 210 # px sirka = 210 # px
# nejnovějších 10 zveřejněných čísel
cisla = Cislo.objects.filter(verejne_db=True)[:10] 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") png_dir = op.join(settings.MEDIA_ROOT, "cislo", "png")
# seznam [(url obrázku, číslo)] # seznam [(url obrázku, číslo)]
urls = [] urls = []
# c je číslo, i je pořadí čísla
for i, c in enumerate(cisla): for i, c in enumerate(cisla):
if not c.pdf: if not c.pdf:
continue continue
@ -433,7 +435,8 @@ def hlavni_problem(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):
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] reseni = [h.reseni for h in hodnoceni]
problemy = [h.problem for h in hodnoceni] problemy = [h.problem for h in hodnoceni]
@ -454,12 +457,12 @@ def hlavni_problemy_cisla(cislo):
return hlavni_problemy return hlavni_problemy
# 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
# POZOR! Aktuálně počítá jen za posledních 10 let od zadaného ročníku
def body_resitelu_odjakziva(rocnik, resitele): def body_resitelu_odjakziva(rocnik, resitele):
body_odjakziva = {} body_odjakziva = {}
for r in resitele: for r in resitele:
body_odjakziva[str(r.id)] = 0 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 # # Body za posledních 10 let je dobrá aproximace pro naše potřeby (výsledkovka
# # s aktivními řešiteli) # # 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) pricti_body(body_za_rocnik, resitel, hodn.body)
return body_za_rocnik 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 # 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
@ -662,30 +633,16 @@ def pricti_body(slovnik, resitel, body):
slovnik[str(resitel.id)] += body slovnik[str(resitel.id)] += body
class CisloView(generic.DetailView): def secti_body_za_rocnik(cislo, aktivni_resitele):
model = Cislo # spočítáme všem řešitelům jejich body za ročník
template_name = 'seminar/archiv/cislo.html' 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ě
# Vlastni ziskavani objektu z databaze podle (Rocnik.rocnik) resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(),
def get_object(self, queryset=None): key = lambda x: x[1], reverse = True)
if queryset is None: return resitel_rocnikbody_sezn
queryset = self.get_queryset()
rocnik_arg = self.kwargs.get('rocnik')
poradi_arg = self.kwargs.get('cislo')
queryset = queryset.filter(rocnik__rocnik=rocnik_arg, poradi=poradi_arg)
try:
obj = queryset.get()
except queryset.model.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
return obj
def get_context_data(self, **kwargs):
context = super(CisloView, self).get_context_data(**kwargs)
cislo = context['cislo'] # spočítá u řešitelů body za číslo a za jednotlivé hlavní problémy (témata)
hlavni_problemy = hlavni_problemy_cisla(cislo) 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é # 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ů)
@ -693,14 +650,6 @@ class CisloView(generic.DetailView):
for hp in hlavni_problemy: for hp in hlavni_problemy:
hlavni_problemy_slovnik[str(hp.id)] = {} 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 # zakládání prázdných záznamů pro řešitele
cislobody = {} cislobody = {}
for ar in aktivni_resitele: for ar in aktivni_resitele:
@ -711,7 +660,8 @@ class CisloView(generic.DetailView):
slovnik[str(ar.id)] = "" slovnik[str(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', 'hodnoceni_set').filter(hodnoceni__cislo_body=cislo) 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 # 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 # bodů i do bodů za problém
@ -722,19 +672,36 @@ class CisloView(generic.DetailView):
nadproblem = hlavni_problem(prob) nadproblem = hlavni_problem(prob)
nadproblem_slovnik = hlavni_problemy_slovnik[str(nadproblem.id)] nadproblem_slovnik = hlavni_problemy_slovnik[str(nadproblem.id)]
# a 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()):
body = hodn.body body = hodn.body
# a více řešitelů # a mít více řešitelů
for resitel in list(reseni.resitele.all()): for resitel in list(reseni.resitele.all()):
pricti_body(cislobody, resitel, body) pricti_body(cislobody, resitel, body)
pricti_body(nadproblem_slovnik, resitel, body) pricti_body(nadproblem_slovnik, resitel, body)
return hlavni_problemy_slovnik, cislobody
# 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) def spocti_vysledkovku_cisla(cislo, context=None):
resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(), if context is None:
key = lambda x: x[1], reverse = True) 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 # získáme body odjakživa
resitel_odjakzivabody_slov = body_resitelu_odjakziva(cislo.rocnik.druhy_rok(), resitel_odjakzivabody_slov = body_resitelu_odjakziva(cislo.rocnik.druhy_rok(),
@ -744,32 +711,31 @@ class CisloView(generic.DetailView):
setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn] setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn]
setrizeni_resitele = [Resitel.objects.get(id=i) for i in setrizeni_resitele_id] 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 # vytvoříme jednotlivé sloupce výsledkovky
radky_vysledkovky = [] radky_vysledkovky = []
odjakziva_body = [] i = 0
rocnik_body = []
cislo_body = []
hlavni_problemy_body = []
for ar_id in setrizeni_resitele_id: for ar_id in setrizeni_resitele_id:
# vytáhneme ze slovníků body pro daného řešitele # získáme seznam bodů za problémy 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 = [] 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[str(hp.id)][ar_id])
hlavni_problemy_body.append(problemy) # vytáhneme informace pro daného řešitele
print("{}: body za problémy - {}, číslobody - {}, ročníkbody - {}, odjakživabody - ".format(ar_id, problemy, cislobody[ar_id], resitel_rocnikbody_slov[ar_id])) radek = RadekVysledkovky(
# pořadí určíme pomocí funkce, které dáme celkové body za ročník vzestupně poradi[i], # pořadí
poradi = sloupec_s_poradim(rocnik_body) Resitel.objects.get(id=ar_id), # řešitel (z id)
problemy, # seznam bodů za hlavní problémy čísla
radky_vysledkovky = [] cislobody[ar_id], # body za číslo
for i in range(0, len(setrizeni_resitele_id)): setrizeni_resitele_body[i], # body za ročník (spočítané výše s pořadím)
radek = RadekVysledkovky(poradi[i], setrizeni_resitele[i], resitel_odjakzivabody_slov[ar_id]) # body odjakživa
hlavni_problemy_body[i], cislo_body[i], rocnik_body[i], print("{}: body za problémy - {}, číslobody - {}, ročníkbody - {}, odjakživabody - {}".format(radek.resitel,
odjakziva_body[i]) 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
print("Následuje předávání do kontextu.") 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
@ -781,6 +747,32 @@ class CisloView(generic.DetailView):
print("Předávám kontext.") print("Předávám kontext.")
return context return context
class CisloView(generic.DetailView):
model = Cislo
template_name = 'seminar/archiv/cislo.html'
# Vlastni ziskavani objektu z databaze podle (Rocnik.rocnik)
def get_object(self, queryset=None):
if queryset is None:
queryset = self.get_queryset()
rocnik_arg = self.kwargs.get('rocnik')
poradi_arg = self.kwargs.get('cislo')
queryset = queryset.filter(rocnik__rocnik=rocnik_arg, poradi=poradi_arg)
try:
obj = queryset.get()
except queryset.model.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
return obj
def get_context_data(self, **kwargs):
context = super(CisloView, self).get_context_data(**kwargs)
cislo = context['cislo']
# 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())) # 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 # #setridi problemy podle typu a poradi zadani
# problem_index = {} # problem_index = {}
@ -1006,7 +998,7 @@ def soustredeniUcastniciExportView(request,soustredeni):
class ClankyResitelView(generic.ListView): class ClankyResitelView(generic.ListView):
model = Problem model = Problem
template_name = 'seminar/clanky/resitelske_clanky.html' 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 # FIXME: pokud chceme orgoclanky, tak nejak zavest do modelu a podle toho odkomentovat a upravit
#class ClankyOrganizatorView(generic.ListView)<F12>: #class ClankyOrganizatorView(generic.ListView)<F12>:

Loading…
Cancel
Save