diff --git a/seminar/testutils.py b/seminar/testutils.py index e1b3d6d8..a1646861 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -9,7 +9,7 @@ from django.db import transaction import unidecode import logging -from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Osoba, Organizator, Prijemce, Tema, Uloha, Konfera, KonferaNode, TextNode, UlohaVzorakNode, RocnikNode, CisloNode, TemaVCisleNode, Text, Hodnoceni, UlohaZadaniNode, Novinky +from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Osoba, Organizator, Prijemce, Tema, Uloha, Konfera, KonferaNode, TextNode, UlohaVzorakNode, RocnikNode, CisloNode, TemaVCisleNode, Text, Hodnoceni, UlohaZadaniNode, Novinky, TreeNode from django.contrib.flatpages.models import FlatPage from django.contrib.sites.models import Site @@ -395,7 +395,7 @@ def gen_temata(rnd, rocniky, rocnik_cisla, organizatori): # Věříme, že rocnik_cisla je pole polí čísel podle ročníků, tak si necháme dát vždycky jeden ročník a k němu příslušná čísla. for rocnik, cisla in zip(rocniky, rocnik_cisla): kod = 1 - temata = [] + letosni_temata = [] # Do každého ročníku vymyslíme tři (zatím) témata, v každém z prvních čísel jedno for zacatek_tematu in range(1, 3): # Vygenerujeme téma @@ -420,6 +420,7 @@ def gen_temata(rnd, rocniky, rocnik_cisla, organizatori): # Vyrobíme TemaVCisleNody pro obsah for i in range(zacatek_tematu, konec_tematu+1): node = TemaVCisleNode.objects.create(tema = t) + # FIXME: Není to off-by-one? otec = cisla[i-1].cislonode otec_syn(otec, node) @@ -429,8 +430,8 @@ def gen_temata(rnd, rocniky, rocnik_cisla, organizatori): # Uložíme všechno t.save() - temata.append((zacatek_tematu, konec_tematu, t)) - rocnik_temata.append(temata) + letosni_temata.append((zacatek_tematu, konec_tematu, t)) + rocnik_temata.append(letosni_temata) return rocnik_temata @@ -455,84 +456,103 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori) "netriviální aplikace diferenciálních rovnic", "zadání je vnitřně" "sporné", "nepopsatelně jednoduché", "pokud jste na to nepřišli," "tak jste fakt hloupí"] - k = 0 - for rocnik in rocniky: - k+=1 - cisla = rocnik_cisla[k-1] - temata = rocnik_temata[k-1] - for ci in range(len(cisla)): - print("Generuji {}-té číslo".format(ci)) - cislo = cisla[ci-1] - mozna_tema_vcn = cislo.cislonode.first_child - # kdybyste nad tím někdo taky přemýšleli, tak vcn == VCisleNode :) - while mozna_tema_vcn != None: - if type(mozna_tema_vcn) != TemaVCisleNode: - mozna_tema_vcn = mozna_tema_vcn.succ + # Ke každému ročníku si vezmeme příslušná čísla a témata + for rocnik, cisla, temata in zip(rocniky, rocnik_cisla, rocnik_temata): + # Do každého čísla nagenerujeme ke každému témátku pár úložek + for cislo in cisla: + print("Generuji úložky do {}-tého čísla".format(cislo.poradi)) + # Vzorák bude o dvě čísla dál + cislo_se_vzorakem = Cislo.objects.filter( + rocnik=rocnik, + poradi=str(int(cislo.poradi) + 2), + ) + # Pokud není číslo pro vzorák, tak se dá do posledního čísla (i kdyby tam mělo být zadání i řešení...) + # Tohle sice umožňuje vygenerovat vzorák do čísla dávno po konci témátka, ale to nám pro jednoduchost nevadí. + if len(cislo_se_vzorakem) == 0: + cislo_se_vzorakem = cisla[-1] + else: + cislo_se_vzorakem = cislo_se_vzorakem.first() + + # FIXME: Tenhle generátor dát asi někam jinam + def potomci(node): + if not isinstance(node, TreeNode): + raise ValueError("Typ {} nemá potomky", type(node)) + current_child = node.first_child + while current_child is not None: + yield current_child + current_child = current_child.succ + + for mozna_tema_node in potomci(cislo.cislonode): + if not isinstance(mozna_tema_node, TemaVCisleNode): continue - else: - tema = mozna_tema_vcn.tema + tema_node = mozna_tema_node + tema = tema_node.tema - if not temata[int(tema.kod)-1][1] >= ci+2: - mozna_tema_vcn = mozna_tema_vcn.succ + # Pokud už témátko skončilo, žádné úložky negenerujeme + # FIXME: Bylo by hezčí, kdyby se čísla předávala jako Cislo a ne jako int v té trojici (start, konec, tema) + if not temata[int(tema.kod)-1][1] >= int(cislo_se_vzorakem.poradi): continue - for i in range(1, rnd.randint(1, 4)): - poc_op = rnd.randint(1, 4) - poc_oboru = rnd.randint(1, 2) - p = Uloha.objects.create( + # Generujeme 1 až 4 úložky k tomuto témátku do tohoto čísla + for kod in range(1, rnd.randint(1, 4)): + u = Uloha.objects.create( nazev=": ".join([tema.nazev, - "úloha {}.".format(i)]), + "úloha {}.".format(kod)]), nadproblem=tema, stav=Problem.STAV_ZADANY, zamereni=tema.zamereni, autor=tema.autor, garant=tema.garant, - kod=str(i), + kod=str(kod), cislo_zadani=cislo, - cislo_reseni=cisla[ci+2-1], - cislo_deadline=cisla[ci+2-1], + cislo_reseni=cislo_se_vzorakem, + cislo_deadline=cislo_se_vzorakem, max_body = rnd.randint(1, 8) ) - p.opravovatele.set(rnd.sample(organizatori, poc_op)) + poc_opravovatelu = rnd.randint(1, 4) + u.opravovatele.set(rnd.sample(organizatori, poc_opravovatelu)) - text_zadani = Text.objects.create( - na_web = " ".join( - [rnd.choice(sloveso), - rnd.choice(koho), - rnd.choice(ceho), - rnd.choice(jmeno), - rnd.choice(kde)] - ), - do_cisla = " ".join( + # Samotný obsah následně vzniklého Textu zadání + obsah = " ".join( [rnd.choice(sloveso), rnd.choice(koho), rnd.choice(ceho), rnd.choice(jmeno), rnd.choice(kde)] ) - ) + text_zadani = Text.objects.create( + na_web = obsah, + do_cisla = obsah, + ) zad = TextNode.objects.create(text = text_zadani) - uloha_zadani = UlohaZadaniNode.objects.create(uloha=p, first_child = zad) - p.ulohazadaninode = uloha_zadani - otec_syn(mozna_tema_vcn, uloha_zadani) - # TODO dělá se podproblém takto??? TODO + uloha_zadani = UlohaZadaniNode.objects.create(uloha=u, first_child = zad) + u.ulohazadaninode = uloha_zadani + + # FIXME: Tohle dává zadání vždy jako prvního potomka témátka, spec. se naskládají v opačném pořadí a nemůže mezi nimi vzniknout žádný (orgo-)text + otec_syn(tema_node, uloha_zadani) + # Text vzoráku stejně + obsah = rnd.choice(reseni) text_vzoraku = Text.objects.create( - na_web = rnd.choice(reseni), - do_cisla = rnd.choice(reseni) + na_web = obsah, + do_cisla = obsah, ) vzorak = TextNode.objects.create(text = text_vzoraku) - uloha_vzorak = UlohaVzorakNode.objects.create(uloha=p, first_child = vzorak) - p.UlohaVzorakNode = uloha_vzorak - res_tema_vcn = cisla[ci+2-1].cislonode.first_child - while res_tema_vcn.tema != tema: - res_tema_vcn = res_tema_vcn.succ - otec_syn(res_tema_vcn, uloha_vzorak) + uloha_vzorak = UlohaVzorakNode.objects.create(uloha=u, first_child = vzorak) + u.UlohaVzorakNode = uloha_vzorak + + # Najdeme správný TemaVCisleNode pro vložení vzoráku + res_tema_node = None; + for node in potomci(cislo_se_vzorakem.cislonode): + if isinstance(node, TemaVCisleNode) and node.tema == tema: + res_tema_node = node + if res_tema_node is None: + raise LookupError("Nenalezen Node pro vložení vzoráku") + # FIXME: Stejný problém jako výše: vzoráky se dají na začátek v opačném pořadí. + otec_syn(res_tema_node, uloha_vzorak) - p.save() - - mozna_tema_vcn = mozna_tema_vcn.succ + u.save() return def gen_novinky(rnd, organizatori): @@ -552,7 +572,7 @@ def gen_novinky(rnd, organizatori): def otec_syn(otec, syn): bratr = otec.first_child - syn.ucc = bratr + syn.succ = bratr otec.first_child = syn syn.save() otec.save()