Merge branch 'data_migrations' into treelib_tests
|
@ -39,8 +39,8 @@ def obrazek_filename(self, filename):
|
||||||
# soustředění je v cestě jen pokud galerie pod nějaké patří
|
# soustředění je v cestě jen pokud galerie pod nějaké patří
|
||||||
cesta = (
|
cesta = (
|
||||||
['Galerie'] +
|
['Galerie'] +
|
||||||
(["soustredeni_" + gal.soustredeni.pk] if gal.soustredeni else []) +
|
(["soustredeni_{}".format(gal.soustredeni.pk)] if gal.soustredeni else []) +
|
||||||
["galerie_" + cislo_gal, self.nazev]
|
["galerie_{}".format(cislo_gal), self.nazev]
|
||||||
)
|
)
|
||||||
|
|
||||||
return os.path.join(*cesta)
|
return os.path.join(*cesta)
|
||||||
|
|
Before Width: | Height: | Size: 15 KiB |
35
galerie/static/galerie/prvky/dalsi.svg
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="25.135418mm"
|
||||||
|
height="42.333332mm"
|
||||||
|
viewBox="0 0 25.135418 42.333331"
|
||||||
|
version="1.1"
|
||||||
|
id="svg851">
|
||||||
|
<defs
|
||||||
|
id="defs845" />
|
||||||
|
<metadata
|
||||||
|
id="metadata848">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
transform="matrix(-1.0282842,0,0,1,111.4545,-88.415317)">
|
||||||
|
<path
|
||||||
|
d="m 108.38881,88.415317 -6.43264,21.166663 6.43264,21.16667 -18.011397,-21.16667 z"
|
||||||
|
style="fill:#e84e10;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.23177969"
|
||||||
|
id="path44-3" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 15 KiB |
35
galerie/static/galerie/prvky/predchozi.svg
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="25.135418mm"
|
||||||
|
height="42.333332mm"
|
||||||
|
viewBox="0 0 25.135418 42.333331"
|
||||||
|
version="1.1"
|
||||||
|
id="svg851">
|
||||||
|
<defs
|
||||||
|
id="defs845" />
|
||||||
|
<metadata
|
||||||
|
id="metadata848">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
transform="matrix(-1.0282842,0,0,1,111.4545,-88.415317)">
|
||||||
|
<path
|
||||||
|
d="m 83.944774,88.415319 6.43264,21.166661 -6.43264,21.16667 18.011396,-21.16667 z"
|
||||||
|
style="fill:#e84e10;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.23177969"
|
||||||
|
id="path44-3" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1 KiB |
|
@ -242,6 +242,10 @@ nav.nav-button {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.dropdown-backdrop { /* tohle způsobuje, že funguje mobilní menu */
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
h1 a:hover {
|
h1 a:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
@ -387,11 +391,16 @@ p.license-mobile {
|
||||||
}
|
}
|
||||||
|
|
||||||
div.graf{
|
div.graf{
|
||||||
|
width: 70%;
|
||||||
float: none;
|
float: none;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
width: 70%;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
#svg-graf{
|
||||||
|
width: 100%;
|
||||||
|
height: auto;;
|
||||||
|
}
|
||||||
|
|
||||||
ul.menu {
|
ul.menu {
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
|
@ -575,12 +584,9 @@ ul.submenu {
|
||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.graf{
|
div.graf {
|
||||||
float: none;
|
width: 100%;
|
||||||
width: 70%;
|
}
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,19 +712,6 @@ div.cislo_odkazy ul {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* archiv ročník
|
|
||||||
div.cisla-v-rocniku {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #6f2509;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.cislo-v-rocniku-blok {
|
|
||||||
display: inline-block;
|
|
||||||
width: 150px;
|
|
||||||
height: 220px;
|
|
||||||
text-align: center;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
/* galerie */
|
/* galerie */
|
||||||
|
|
||||||
|
@ -739,7 +732,8 @@ div.cislo-v-rocniku-blok {
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
.predchozi_obrazek:hover{
|
.predchozi_obrazek:hover{
|
||||||
background-image: url("/static/galerie/prvky/predchozi.png");
|
background-image: url("/static/galerie/prvky/predchozi.svg");
|
||||||
|
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4));
|
||||||
background-position: left center;
|
background-position: left center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
@ -752,7 +746,8 @@ div.cislo-v-rocniku-blok {
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
.dalsi_obrazek:hover{
|
.dalsi_obrazek:hover{
|
||||||
background-image: url("/static/galerie/prvky/dalsi.png");
|
background-image: url("/static/galerie/prvky/dalsi.svg");
|
||||||
|
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4));
|
||||||
background-position: right center;
|
background-position: right center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
@ -782,31 +777,25 @@ div.cislo-v-rocniku-blok {
|
||||||
|
|
||||||
/* titulní obrázek hlavní galerie soustředění */
|
/* titulní obrázek hlavní galerie soustředění */
|
||||||
.titulni_obrazek {
|
.titulni_obrazek {
|
||||||
border: 1px solid black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.galerie_nahledy{
|
.galerie_nahledy{
|
||||||
/*margin: 1em 0;*/
|
/*margin: 1em 0;*/
|
||||||
margin: 0 auto 30px auto;
|
margin: auto;
|
||||||
|
padding: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.galerie_nahledy div.navigace {
|
.galerie_nahledy img {
|
||||||
display: inline-block;
|
margin: 10px;
|
||||||
width: 150px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*.galerie_nahledy img{*/
|
.galerie_nahledy div.navigace {
|
||||||
/*margin: 0 10px 0 10px;*/
|
display: inline-block;
|
||||||
/*}*/
|
}
|
||||||
|
|
||||||
/*.galerie_nahledy a{*/
|
.galerie_nahled, .podgalerie_nahled { /* frame */
|
||||||
/*height: 100%;*/
|
|
||||||
/*width: 100%;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
.galerie_nahled { /* frame */
|
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
float: left;
|
float: left;
|
||||||
|
@ -814,19 +803,19 @@ div.cislo-v-rocniku-blok {
|
||||||
height: 200px;
|
height: 200px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: solid;
|
border: solid;
|
||||||
border-width: 2px;
|
border-width: 1px;
|
||||||
border-radius: 5px;
|
border-radius: 4px;
|
||||||
/*border-color: #ffa500;*/
|
border-color: #f9d59e;
|
||||||
border-color: #ffd546;
|
background-color: #fffbf6;
|
||||||
/*background-color: #ffb52d;*/
|
|
||||||
background-color: white;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
margin: 10px 20px 10px 0px;
|
margin: 10px;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.galerie_nahled:hover {
|
.galerie_nahled:hover, .podgalerie_nahled:hover {
|
||||||
background-color: #ffd546;
|
background-color: #f9d59e;
|
||||||
border-color: #ffa500;
|
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4));
|
||||||
|
color: #6f2509;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vystredeno{ /* helper */
|
.vystredeno{ /* helper */
|
||||||
|
@ -839,12 +828,6 @@ div.cislo-v-rocniku-blok {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
max-height: 180px;
|
max-height: 180px;
|
||||||
max-width: 180px;
|
max-width: 180px;
|
||||||
/*border: 1px solid white;*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_nahled img, .podgalerie_nahled img {
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.galerie_nahled div {
|
.galerie_nahled div {
|
||||||
|
@ -854,30 +837,6 @@ div.cislo-v-rocniku-blok {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.podgalerie_nahled {
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
float: left;
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
text-align: center;
|
|
||||||
border: solid;
|
|
||||||
border-width: 2px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border-color: #ffa500;
|
|
||||||
/*border-color: #ffd546;*/
|
|
||||||
background-color: #ffd546;
|
|
||||||
/*background-color: white;*/
|
|
||||||
white-space: nowrap;
|
|
||||||
margin: 10px 20px 10px 0px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.podgalerie_nahled:hover {
|
|
||||||
background-color: #ffa500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.podgalerie_nahled img {
|
.podgalerie_nahled img {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
@ -893,10 +852,10 @@ div.cislo-v-rocniku-blok {
|
||||||
|
|
||||||
/* plus a minus tlacitka */
|
/* plus a minus tlacitka */
|
||||||
.mam-org-only-galerie {
|
.mam-org-only-galerie {
|
||||||
background: #fff0d7;
|
background: #eee4ec;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 10px 10px 10px -20px;
|
margin: 10px 10px 10px -20px;
|
||||||
border: orange 2px dashed;
|
border: #333 2px dashed;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,8 +863,8 @@ div.cislo-v-rocniku-blok {
|
||||||
padding: 3px 5px;
|
padding: 3px 5px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
background-color: lightblue;
|
background-color: #6f2509;;
|
||||||
color: black;
|
color: #fffbf6;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg2"
|
id="svg-graf"
|
||||||
width="482.57019"
|
width="482.57019"
|
||||||
height="599.45636"
|
height="599.45636"
|
||||||
viewBox="0 0 482.57019 599.45636"
|
viewBox="0 0 482.57019 599.45636"
|
||||||
|
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
@ -173,13 +173,12 @@ def gen_organizatori(rnd, osoby, last_rocnik, users):
|
||||||
if do.year > datetime.datetime.now().year:
|
if do.year > datetime.datetime.now().year:
|
||||||
do = None
|
do = None
|
||||||
organizatori.append(Organizator.objects.create(osoba=os,
|
organizatori.append(Organizator.objects.create(osoba=os,
|
||||||
organizuje_od=od, organizuje_do=do, strucny_popis_organizatora = popis_orga))
|
organizuje_od=od, organizuje_do=do, strucny_popis_organizatora = popis_orga))
|
||||||
return organizatori
|
return organizatori
|
||||||
|
|
||||||
def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size):
|
def gen_zadani_ulohy(rnd, cisla, organizatori, pocet_oboru, poradi_cisla, poradi_problemu):
|
||||||
logger.info('Generuji úlohy do čísla (size={})...'.format(size))
|
|
||||||
|
# Proměnné pro náhodné generování názvů a zadání.
|
||||||
# ulohy resene v cisle
|
|
||||||
jaka = ["Šachová", "Černá", "Větrná", "Dlouhá", "Křehká", "Rychlá",
|
jaka = ["Šachová", "Černá", "Větrná", "Dlouhá", "Křehká", "Rychlá",
|
||||||
"Zákeřná", "Fyzikální"]
|
"Zákeřná", "Fyzikální"]
|
||||||
co = ["kostka", "smršť", "díra", "zrada", "toulka", "tyč",
|
co = ["kostka", "smršť", "díra", "zrada", "toulka", "tyč",
|
||||||
|
@ -189,7 +188,47 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size)
|
||||||
ceho = ["všech", "správných", "konstatních", "zelených"]
|
ceho = ["všech", "správných", "konstatních", "zelených"]
|
||||||
jmeno = ["řešení", "tahů", "čísel", "kalhot", "koulí", "hadů"]
|
jmeno = ["řešení", "tahů", "čísel", "kalhot", "koulí", "hadů"]
|
||||||
kde = ["na zemi", "ve vesmíru", "ve vzduchu", "na šňůře", "v letadle"]
|
kde = ["na zemi", "ve vesmíru", "ve vzduchu", "na šňůře", "v letadle"]
|
||||||
obor = ["M", "F", "I", "O", "B"]
|
obory = ["M", "F", "I", "O", "B"]
|
||||||
|
|
||||||
|
p = Uloha.objects.create(
|
||||||
|
# atributy třídy Problem
|
||||||
|
nazev=" ".join([rnd.choice(jaka), rnd.choice(co)]),
|
||||||
|
stav=Problem.STAV_ZADANY,
|
||||||
|
zamereni=rnd.sample(obory, pocet_oboru),
|
||||||
|
autor=rnd.choice(organizatori),
|
||||||
|
garant=rnd.choice(organizatori),
|
||||||
|
kod=str(poradi_problemu),
|
||||||
|
# atributy třídy Uloha
|
||||||
|
cislo_zadani=cisla[poradi_cisla-2-1],
|
||||||
|
cislo_reseni=cisla[poradi_cisla-1],
|
||||||
|
cislo_deadline=cisla[poradi_cisla-1],
|
||||||
|
max_body = rnd.randint(1, 8)
|
||||||
|
)
|
||||||
|
|
||||||
|
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(
|
||||||
|
[rnd.choice(sloveso),
|
||||||
|
rnd.choice(koho),
|
||||||
|
rnd.choice(ceho),
|
||||||
|
rnd.choice(jmeno),
|
||||||
|
rnd.choice(kde)]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
zad = TextNode.objects.create(text = text_zadani)
|
||||||
|
uloha_zadani = UlohaZadaniNode.objects.create(uloha = p, first_child = zad)
|
||||||
|
p.ulohazadaninode = uloha_zadani
|
||||||
|
otec_syn(cisla[poradi_cisla-2-1].cislonode, uloha_zadani)
|
||||||
|
|
||||||
|
return p
|
||||||
|
|
||||||
|
def gen_vzoroveho_reseni_ulohy(rnd, cisla, organizatori, uloha, pocet_opravovatelu, poradi_cisla):
|
||||||
reseni = ["to je přece jasné", "triviální", "omlouváme se,"
|
reseni = ["to je přece jasné", "triviální", "omlouváme se,"
|
||||||
"otevřený problém", "neřešitelné", "triviálně triviální",
|
"otevřený problém", "neřešitelné", "triviálně triviální",
|
||||||
"použitím věty z prvního semestru na matfyzu",
|
"použitím věty z prvního semestru na matfyzu",
|
||||||
|
@ -197,96 +236,81 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size)
|
||||||
"netriviální aplikace diferenciálních rovnic", "zadání je vnitřně"
|
"netriviální aplikace diferenciálních rovnic", "zadání je vnitřně"
|
||||||
"sporné", "nepopsatelně jednoduché", "pokud jste na to nepřišli,"
|
"sporné", "nepopsatelně jednoduché", "pokud jste na to nepřišli,"
|
||||||
"tak jste fakt hloupí"]
|
"tak jste fakt hloupí"]
|
||||||
|
|
||||||
|
# Generování vzorového řešení.
|
||||||
|
text_vzoraku = Text.objects.create(
|
||||||
|
na_web = rnd.choice(reseni),
|
||||||
|
do_cisla = rnd.choice(reseni)
|
||||||
|
)
|
||||||
|
vzorak = TextNode.objects.create(text = text_vzoraku)
|
||||||
|
uloha_vzorak = UlohaVzorakNode.objects.create(uloha = uloha, first_child = vzorak)
|
||||||
|
uloha.ulohavzoraknode = uloha_vzorak
|
||||||
|
otec_syn(cisla[poradi_cisla-1].cislonode, uloha_vzorak)
|
||||||
|
|
||||||
|
uloha.opravovatele.set(rnd.sample(organizatori, pocet_opravovatelu))
|
||||||
|
uloha.save()
|
||||||
|
return
|
||||||
|
|
||||||
|
def gen_reseni_ulohy(rnd, cisla, uloha, pocet_resitelu, poradi_cisla, resitele_cisla, resitele):
|
||||||
|
|
||||||
|
pocet_reseni = rnd.randint(pocet_resitelu//4, pocet_resitelu * 4)
|
||||||
|
# generujeme náhodný počet řešení vzhledem k počtu řešitelů čísla
|
||||||
|
for _ in range(pocet_reseni):
|
||||||
|
#print("Generuji {}-té řešení".format(reseni))
|
||||||
|
if rnd.randint(1, 10) == 1:
|
||||||
|
# cca desetina řešení od více řešitelů
|
||||||
|
res_vyber = rnd.sample(resitele_cisla,
|
||||||
|
rnd.randint(2, 5))
|
||||||
|
else:
|
||||||
|
res_vyber = rnd.sample(resitele_cisla, 1)
|
||||||
|
if resitele[0] in res_vyber: # speciální řešitel, který nemá žádné body
|
||||||
|
res_vyber.remove(resitele[0])
|
||||||
|
|
||||||
|
# Vytvoření řešení.
|
||||||
|
res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0])
|
||||||
|
# Problím a řešitele přiřadíme později, ManyToManyField
|
||||||
|
# se nedá vyplnit v create().
|
||||||
|
res.resitele.set(res_vyber)
|
||||||
|
res.save()
|
||||||
|
|
||||||
|
# Vytvoření hodnocení.
|
||||||
|
hod = Hodnoceni.objects.create(
|
||||||
|
body=rnd.randint(0, uloha.max_body),
|
||||||
|
cislo_body=cisla[poradi_cisla - 1],
|
||||||
|
reseni=res,
|
||||||
|
problem=uloha
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size):
|
||||||
|
logger.info('Generuji úlohy do čísla (size={})...'.format(size))
|
||||||
|
|
||||||
k = 0
|
k = 0
|
||||||
for rocnik in rocniky:
|
for rocnik in rocniky:
|
||||||
k+=1
|
k += 1
|
||||||
print("Generuji {}. číslo.".format(k))
|
print("Generuji {}. číslo.".format(k))
|
||||||
cisla = rocnik_cisla[k-1]
|
cisla = rocnik_cisla[k - 1]
|
||||||
for ci in range(3, len(cisla)+1): # pro všechna čísla
|
for ci in range(3, len(cisla) + 1): # pro všechna čísla
|
||||||
resitele_size = round(7/8 * 30 * size) # očekáváný celkový počet řešitelů
|
resitele_size = round(7/8 * 30 * size) # očekáváný celkový počet řešitelů
|
||||||
poc_res = rnd.randint(round(resitele_size/8), round(resitele_size/4))
|
poc_res = rnd.randint(resitele_size//8, resitele_size//4)
|
||||||
# dané číslo řeší něco mezi osminou a čtvrtinou všech řešitelů
|
# dané číslo řeší něco mezi osminou a čtvrtinou všech řešitelů
|
||||||
# (náhodná hausnumera, možno změnit)
|
# (náhodná hausnumera, možno změnit)
|
||||||
# účelem je, aby se řešení generovala z menší množiny řešitelů a tedy
|
# účelem je, aby se řešení generovala z menší množiny řešitelů a tedy
|
||||||
# bylo více řešení od jednoho řešitele daného čísla
|
# bylo více řešení od jednoho řešitele daného čísla
|
||||||
resitele_cisla = rnd.sample(resitele, poc_res)
|
resitele_cisla = rnd.sample(resitele, poc_res)
|
||||||
for pi in range(1, ((size + 1) // 2) + 1):
|
for pi in range(1, ((size + 1) // 2) + 1): # počet problémů
|
||||||
|
|
||||||
poc_op = rnd.randint(1, 4) # počet opravovatelů
|
poc_op = rnd.randint(1, 4) # počet opravovatelů
|
||||||
poc_oboru = rnd.randint(1, 2)
|
poc_oboru = rnd.randint(1, 2)
|
||||||
p = Uloha.objects.create(
|
|
||||||
# atributy třídy Problem
|
# Generování zadání úlohy a UlohaZadaniNode,
|
||||||
nazev=" ".join([rnd.choice(jaka), rnd.choice(co)]),
|
# přivěšení pod dané číslo
|
||||||
stav=Problem.STAV_ZADANY,
|
p = gen_zadani_ulohy(rnd, cisla, organizatori, poc_oboru, ci, pi)
|
||||||
zamereni=rnd.sample(["M", "F", "I", "O", "B"], poc_oboru),
|
# Generování vzorového řešení
|
||||||
autor=rnd.choice(organizatori),
|
gen_vzoroveho_reseni_ulohy(rnd, cisla, organizatori, p, poc_op, ci)
|
||||||
garant=rnd.choice(organizatori),
|
# Generování řešení a hodnocení k úloze
|
||||||
kod=str(pi),
|
gen_reseni_ulohy(rnd, cisla, p, poc_res, ci,
|
||||||
# atributy třídy Uloha
|
resitele_cisla, resitele)
|
||||||
cislo_zadani=cisla[ci-2-1],
|
|
||||||
cislo_reseni=cisla[ci-1],
|
|
||||||
cislo_deadline=cisla[ci-1],
|
|
||||||
max_body = rnd.randint(1, 8)
|
|
||||||
)
|
|
||||||
|
|
||||||
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(
|
|
||||||
[rnd.choice(sloveso),
|
|
||||||
rnd.choice(koho),
|
|
||||||
rnd.choice(ceho),
|
|
||||||
rnd.choice(jmeno),
|
|
||||||
rnd.choice(kde)]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
zad = TextNode.objects.create(text = text_zadani)
|
|
||||||
uloha_zadani = UlohaZadaniNode.objects.create(uloha=p, first_child = zad)
|
|
||||||
p.ulohazadaninode = uloha_zadani
|
|
||||||
otec_syn(cisla[ci-2-1].cislonode, uloha_zadani)
|
|
||||||
|
|
||||||
# generování vzorového textu
|
|
||||||
text_vzoraku = Text.objects.create(
|
|
||||||
na_web = rnd.choice(reseni),
|
|
||||||
do_cisla = rnd.choice(reseni)
|
|
||||||
)
|
|
||||||
vzorak = TextNode.objects.create(text = text_vzoraku)
|
|
||||||
uloha_vzorak = UlohaVzorakNode.objects.create(uloha=p, first_child = vzorak)
|
|
||||||
p.ulohavzoraknode = uloha_vzorak
|
|
||||||
otec_syn(cisla[ci-1].cislonode, uloha_vzorak)
|
|
||||||
|
|
||||||
p.opravovatele.set(rnd.sample(organizatori,poc_op))
|
|
||||||
p.save()
|
|
||||||
|
|
||||||
# generování řešení
|
|
||||||
poc_reseni = rnd.randint(poc_res, poc_res * 4)
|
|
||||||
# generujeme náhodný počet řešení vzhledem k počtu řešitelů čísla
|
|
||||||
for ri in range(poc_reseni):
|
|
||||||
#print("Generuji {}-té řešení".format(ri))
|
|
||||||
if rnd.randint(1, 10) == 6:
|
|
||||||
# cca desetina řešení od více řešitelů
|
|
||||||
res_vyber = rnd.sample(resitele_cisla,
|
|
||||||
rnd.randint(2, 5))
|
|
||||||
else:
|
|
||||||
res_vyber = rnd.sample(resitele_cisla, 1)
|
|
||||||
if resitele[0] in res_vyber:
|
|
||||||
res_vyber.remove(resitele[0])
|
|
||||||
res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0])
|
|
||||||
# problem a resitele přiřadíme později, ManyToManyField
|
|
||||||
# se nedá vyplnit v create()
|
|
||||||
res.resitele.set(res_vyber)
|
|
||||||
res.save()
|
|
||||||
hod = Hodnoceni.objects.create(
|
|
||||||
body=rnd.randint(0, p.max_body),
|
|
||||||
cislo_body=cisla[ci-1],
|
|
||||||
reseni=res,
|
|
||||||
problem=p
|
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -482,8 +506,10 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori)
|
||||||
rocnik=rocnik,
|
rocnik=rocnik,
|
||||||
poradi=str(int(cislo.poradi) + 2),
|
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í...)
|
# Pokud není číslo pro vzorák, tak se dá do posledního čísla
|
||||||
# Tohle sice umožňuje vygenerovat vzorák do čísla dávno po konci témátka, ale to nám pro jednoduchost nevadí.
|
# (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:
|
if len(cislo_se_vzorakem) == 0:
|
||||||
cislo_se_vzorakem = cisla[-1]
|
cislo_se_vzorakem = cisla[-1]
|
||||||
else:
|
else:
|
||||||
|
@ -505,7 +531,8 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori)
|
||||||
tema = tema_node.tema
|
tema = tema_node.tema
|
||||||
|
|
||||||
# Pokud už témátko skončilo, žádné úložky negenerujeme
|
# 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)
|
# 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):
|
if not temata[int(tema.kod)-1][1] >= int(cislo_se_vzorakem.poradi):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -581,8 +608,10 @@ def gen_novinky(rnd, organizatori):
|
||||||
kdy = ["Zítra bude", "10. 10. 2020 bude", "V prosinci bude", "V létě bude"]
|
kdy = ["Zítra bude", "10. 10. 2020 bude", "V prosinci bude", "V létě bude"]
|
||||||
|
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
text_novinky = " ".join([rnd.choice(kdy),rnd.choice(kde),rnd.choice(jake),rnd.choice(co)])
|
text_novinky = " ".join([rnd.choice(kdy), rnd.choice(kde), rnd.choice(jake),
|
||||||
novinka = Novinky.objects.create(id=i,autor=rnd.choice(organizatori),text=(text_novinky+", těšíme se na vás!"),zverejneno=rnd.choice([True,False]))
|
rnd.choice(co)])
|
||||||
|
novinka = Novinky.objects.create(id=i,autor=rnd.choice(organizatori),
|
||||||
|
text=(text_novinky+", těšíme se na vás!"),zverejneno=rnd.choice([True,False]))
|
||||||
novinka.save()
|
novinka.save()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -324,10 +324,16 @@ class ArchivView(generic.ListView):
|
||||||
|
|
||||||
### Výsledky
|
### Výsledky
|
||||||
|
|
||||||
# ze seznamu obsahujícího sestupně setřízené body řešitelů za daný ročník
|
|
||||||
# vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.),
|
|
||||||
# podle toho, jak jdou za sebou ve výsledkovce
|
|
||||||
def sloupec_s_poradim(setrizene_body):
|
def sloupec_s_poradim(setrizene_body):
|
||||||
|
""" Ze seznamu obsahujícího sestupně setřízené body řešitelů za daný ročník
|
||||||
|
vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.),
|
||||||
|
podle toho, jak jdou za sebou ve výsledkovce.
|
||||||
|
Parametr:
|
||||||
|
setrizene_body (seznam integerů): sestupně setřízená čísla
|
||||||
|
|
||||||
|
Výstup:
|
||||||
|
sloupec_s_poradim (seznam stringů)
|
||||||
|
"""
|
||||||
|
|
||||||
# ze seznamu obsahujícího setřízené body spočítáme sloupec s pořadím
|
# ze seznamu obsahujícího setřízené body spočítáme sloupec s pořadím
|
||||||
aktualni_poradi = 1
|
aktualni_poradi = 1
|
||||||
|
@ -358,20 +364,28 @@ def sloupec_s_poradim(setrizene_body):
|
||||||
aktualni_poradi = aktualni_poradi + velikost_skupiny
|
aktualni_poradi = aktualni_poradi + velikost_skupiny
|
||||||
return sloupec_s_poradim
|
return sloupec_s_poradim
|
||||||
|
|
||||||
# vrátí všechna čísla daného ročníku
|
|
||||||
def cisla_rocniku(rocnik, jen_verejne=True):
|
def cisla_rocniku(rocnik, jen_verejne=True):
|
||||||
|
""" Vrátí všechna čísla daného ročníku.
|
||||||
|
Parametry:
|
||||||
|
rocnik (Rocnik): ročník semináře
|
||||||
|
jen_verejne (bool): zda se mají vrátit jen veřejná, nebo všechna čísla
|
||||||
|
Vrátí:
|
||||||
|
seznam objektů typu Cislo
|
||||||
|
"""
|
||||||
if jen_verejne:
|
if jen_verejne:
|
||||||
return rocnik.verejna_cisla()
|
return rocnik.verejna_cisla()
|
||||||
else:
|
else:
|
||||||
return rocnik.cisla.all()
|
return rocnik.cisla.all()
|
||||||
|
|
||||||
# pro daný problém vrátí jeho nejvyšší nadproblém
|
|
||||||
def hlavni_problem(problem):
|
def hlavni_problem(problem):
|
||||||
|
""" Pro daný problém vrátí jeho nejvyšší nadproblém."""
|
||||||
while not(problem.nadproblem == None):
|
while not(problem.nadproblem == None):
|
||||||
problem = problem.nadproblem
|
problem = problem.nadproblem
|
||||||
return problem
|
return problem
|
||||||
|
|
||||||
def hlavni_problemy_rocniku(rocnik, jen_verejne=True):
|
def hlavni_problemy_rocniku(rocnik, jen_verejne=True):
|
||||||
|
""" Pro zadaný ročník vrátí hlavní problémy ročníku,
|
||||||
|
tj. ty, které už nemají nadproblém."""
|
||||||
hlavni_problemy = []
|
hlavni_problemy = []
|
||||||
for cislo in cisla_rocniku(rocnik, jen_verejne):
|
for cislo in cisla_rocniku(rocnik, jen_verejne):
|
||||||
for problem in hlavni_problemy_cisla(cislo):
|
for problem in hlavni_problemy_cisla(cislo):
|
||||||
|
@ -382,8 +396,8 @@ def hlavni_problemy_rocniku(rocnik, jen_verejne=True):
|
||||||
|
|
||||||
return hlavni_problemy
|
return hlavni_problemy
|
||||||
|
|
||||||
# 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):
|
||||||
|
""" Vrátí seznam všech problémů s body v daném čísle, které již nemají nadproblém. """
|
||||||
hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all()
|
hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all()
|
||||||
# hodnocení, která se vážou k danému číslu
|
# hodnocení, která se vážou k danému číslu
|
||||||
|
|
||||||
|
@ -405,36 +419,71 @@ 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
|
def body_resitelu(resitele, za, odjakziva=True):
|
||||||
def body_resitelu_odjakziva(rocnik, resitele):
|
""" Funkce počítající počty bodů pro zadané řešitele,
|
||||||
# Následující řádek přidá ke každému řešiteli údaj ".body" se součtem jejich bodů
|
buď odjakživa do daného ročníku/čísla anebo za daný ročník/číslo.
|
||||||
resitele_s_body = Resitel.objects.annotate(body=Sum('reseni__hodnoceni__body'))
|
Parametry:
|
||||||
# Teď jen z QuerySetu řešitelů anotovaných body vygenerujeme slovník indexovaný řešitelským id obsahující body
|
resitele (seznam obsahující položky typu Resitel): aktivní řešitelé
|
||||||
# ... ale jen ro řešitele, které dostaneme jako parametr.
|
za (Rocnik/Cislo): za co se mají počítat body
|
||||||
# TODO: Zjistit, co ten parametr říká a proč je potřeba
|
(generování starších výsledkovek)
|
||||||
body_odjakziva = {int(res.id) : res.body for res in resitele_s_body if res in resitele}
|
odjakziva (bool): zda se mají počítat body odjakživa, nebo jen za číslo/ročník
|
||||||
return body_odjakziva
|
zadané v "za"
|
||||||
|
Výstup:
|
||||||
|
slovník (Resitel.id):body
|
||||||
|
"""
|
||||||
|
resitele_id = [r.id for r in resitele]
|
||||||
|
# Zjistíme, typ objektu v parametru "za"
|
||||||
|
if isinstance(za, Rocnik):
|
||||||
|
cislo = None
|
||||||
|
rocnik = za
|
||||||
|
rok = rocnik.prvni_rok
|
||||||
|
elif isinstance(za, Cislo):
|
||||||
|
cislo = za
|
||||||
|
rocnik = None
|
||||||
|
rok = cislo.rocnik.prvni_rok
|
||||||
|
else:
|
||||||
|
assert True, "body_resitelu: za není ani číslo ani ročník."
|
||||||
|
|
||||||
# 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):
|
# Kvůli rychlosti používáme sčítáme body už v databázi, viz
|
||||||
body_za_rocnik = {}
|
# https://docs.djangoproject.com/en/3.0/topics/db/aggregation/,
|
||||||
# inicializujeme na 0 pro všechny aktivní řešitele
|
# sekce Filtering on annotations (protože potřebujeme filtrovat výsledky
|
||||||
for ar in aktivni_resitele:
|
# jen do nějakého data, abychom uměli správně nagenerovat výsledkovky i
|
||||||
body_za_rocnik[ar.id] = 0
|
# za historická čísla.
|
||||||
|
|
||||||
# spočítáme body řešitelům přes všechna řešení s hodnocením v daném ročníku
|
# Níže se vytváří dotaz na součet bodů za správně vyfiltrovaná hodnocení,
|
||||||
print("Před dotazem:{}".format(time.time()))
|
# který se použije ve výsledném dotazu.
|
||||||
reseni = Reseni.objects.prefetch_related('resitele', 'hodnoceni_set').filter(hodnoceni__cislo_body__rocnik=rocnik)
|
if cislo and odjakziva: # Body se sčítají odjakživa do zadaného čísla.
|
||||||
print("Po dotazu:{}".format(time.time()))
|
# Vyfiltrujeme všechna hodnocení, která jsou buď ze starších ročníků,
|
||||||
for res in reseni:
|
# anebo ze stejného ročníku, jak je zadané číslo, tam ale sčítáme jen
|
||||||
for resitel in res.resitele.all():
|
# pro čísla s pořadím nejvýše stejným, jako má zadané číslo.
|
||||||
for hodn in res.hodnoceni_set.all():
|
body_k_zapocteni = Sum('reseni__hodnoceni__body',
|
||||||
pricti_body(body_za_rocnik, resitel, hodn.body)
|
filter=( Q(reseni__hodnoceni__cislo_body__rocnik__prvni_rok__lt=rok) |
|
||||||
print("Po for-cyklu:{}".format(time.time()))
|
Q(reseni__hodnoceni__cislo_body__rocnik__prvni_rok=rok,
|
||||||
return body_za_rocnik
|
reseni__hodnoceni__cislo_body__poradi__lte=cislo.poradi) ))
|
||||||
|
elif cislo and not odjakziva: # Body se sčítají za dané číslo.
|
||||||
|
body_k_zapocteni = Sum('reseni__hodnoceni__body',
|
||||||
|
filter=( Q(reseni__hodnoceni__cislo_body=cislo) ))
|
||||||
|
elif rocnik and odjakziva: # Spočítáme body za starší ročníky až do zadaného včetně.
|
||||||
|
body_k_zapocteni = Sum('reseni__hodnoceni__body',
|
||||||
|
filter= Q(reseni__hodnoceni__cislo_body__rocnik__prvni_rok__lte=rok))
|
||||||
|
elif rocnik and not odjakziva: # Spočítáme body za daný ročník.
|
||||||
|
body_k_zapocteni = Sum('reseni__hodnoceni__body',
|
||||||
|
filter= Q(reseni__hodnoceni__cislo_body__rocnik=rocnik))
|
||||||
|
else:
|
||||||
|
assert True, "body_resitelu: Neplatná kombinace za a odjakživa."
|
||||||
|
|
||||||
|
# Následující řádek přidá ke každému řešiteli údaj ".body" se součtem jejich bodů
|
||||||
|
resitele_s_body = Resitel.objects.filter(id__in=resitele_id).annotate(
|
||||||
|
body=body_k_zapocteni)
|
||||||
|
# Teď jen z QuerySetu řešitelů anotovaných body vygenerujeme slovník
|
||||||
|
# indexovaný řešitelským id obsahující body.
|
||||||
|
# Pokud jsou body None, nahradíme za 0.
|
||||||
|
slovnik = {int(res.id) : (res.body if res.body else 0) for res in resitele_s_body}
|
||||||
|
return slovnik
|
||||||
|
|
||||||
class RadekVysledkovkyRocniku(object):
|
class RadekVysledkovkyRocniku(object):
|
||||||
"""Obsahuje věci, které se hodí vědět při konstruování výsledkovky.
|
""" 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)."""
|
Umožňuje snazší práci v templatu (lepší, než seznam)."""
|
||||||
|
|
||||||
def __init__(self, poradi, resitel, body_cisla_sezn, body_rocnik, body_odjakziva, rok):
|
def __init__(self, poradi, resitel, body_cisla_sezn, body_rocnik, body_odjakziva, rok):
|
||||||
|
@ -447,7 +496,7 @@ class RadekVysledkovkyRocniku(object):
|
||||||
self.titul = resitel.get_titul(body_odjakziva)
|
self.titul = resitel.get_titul(body_odjakziva)
|
||||||
|
|
||||||
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"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -460,7 +509,6 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True):
|
||||||
#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik)
|
#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik)
|
||||||
cisla = cisla_rocniku(rocnik, jen_verejne)
|
cisla = cisla_rocniku(rocnik, jen_verejne)
|
||||||
body_cisla_slov = {}
|
body_cisla_slov = {}
|
||||||
print("Jen veřejná: {}, čísla: {}".format(jen_verejne, cisla))
|
|
||||||
for cislo in cisla:
|
for cislo in cisla:
|
||||||
# získáme body za číslo
|
# získáme body za číslo
|
||||||
_, cislobody = secti_body_za_cislo(cislo, aktivni_resitele)
|
_, cislobody = secti_body_za_cislo(cislo, aktivni_resitele)
|
||||||
|
@ -476,7 +524,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True):
|
||||||
poradi = sloupec_s_poradim(setrizene_body)
|
poradi = sloupec_s_poradim(setrizene_body)
|
||||||
|
|
||||||
# získáme body odjakživa
|
# získáme body odjakživa
|
||||||
resitel_odjakzivabody_slov = body_resitelu_odjakziva(rocnik, aktivni_resitele)
|
resitel_odjakzivabody_slov = body_resitelu(aktivni_resitele, rocnik)
|
||||||
|
|
||||||
# vytvoříme jednotlivé sloupce výsledkovky
|
# vytvoříme jednotlivé sloupce výsledkovky
|
||||||
radky_vysledkovky = []
|
radky_vysledkovky = []
|
||||||
|
@ -495,11 +543,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True):
|
||||||
setrizene_body[i], # body za ročník (spočítané výše s pořadím)
|
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
|
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))
|
|
||||||
radky_vysledkovky.append(radek)
|
radky_vysledkovky.append(radek)
|
||||||
print("Přikládám {}-tý řádek.".format(i))
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
return radky_vysledkovky
|
return radky_vysledkovky
|
||||||
|
@ -581,8 +625,8 @@ class RadekVysledkovkyCisla(object):
|
||||||
self.titul = resitel.get_titul(body_odjakziva)
|
self.titul = resitel.get_titul(body_odjakziva)
|
||||||
|
|
||||||
|
|
||||||
# přiřazuje danému řešiteli body do slovníku
|
|
||||||
def pricti_body(slovnik, resitel, body):
|
def pricti_body(slovnik, resitel, body):
|
||||||
|
""" Přiřazuje danému řešiteli body do slovníku. """
|
||||||
# testujeme na None (""), pokud je to první řešení
|
# testujeme na None (""), pokud je to první řešení
|
||||||
# daného řešitele, předěláme na 0
|
# daného řešitele, předěláme na 0
|
||||||
# (v dalším kroku přičteme reálný počet bodů),
|
# (v dalším kroku přičteme reálný počet bodů),
|
||||||
|
@ -593,15 +637,16 @@ def pricti_body(slovnik, resitel, body):
|
||||||
slovnik[resitel.id] += body
|
slovnik[resitel.id] += body
|
||||||
|
|
||||||
def secti_body_za_rocnik(rocnik, aktivni_resitele):
|
def secti_body_za_rocnik(rocnik, aktivni_resitele):
|
||||||
# spočítáme všem řešitelům jejich body za ročník
|
""" Spočítá body za ročník, setřídí je sestupně a vrátí jako seznam."""
|
||||||
resitel_rocnikbody_slov = body_resitelu_za_rocnik(rocnik, aktivni_resitele)
|
# spočítáme všem řešitelům jejich body za ročník (False => ne odjakživa)
|
||||||
|
resitel_rocnikbody_slov = body_resitelu(aktivni_resitele, rocnik, False)
|
||||||
# zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně
|
# zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně
|
||||||
resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(),
|
resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(),
|
||||||
key = lambda x: x[1], reverse = True)
|
key = lambda x: x[1], reverse = True)
|
||||||
return resitel_rocnikbody_sezn
|
return resitel_rocnikbody_sezn
|
||||||
|
|
||||||
# spočítá u řešitelů body za číslo a za jednotlivé hlavní problémy (témata)
|
|
||||||
def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None):
|
def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None):
|
||||||
|
""" Spočítá u řešitelů body za číslo a za jednotlivé hlavní problémy (témata)."""
|
||||||
# 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ů)
|
||||||
|
@ -664,8 +709,7 @@ def vysledkovka_cisla(cislo, context=None):
|
||||||
resitel_rocnikbody_sezn = secti_body_za_rocnik(cislo.rocnik, aktivni_resitele)
|
resitel_rocnikbody_sezn = secti_body_za_rocnik(cislo.rocnik, aktivni_resitele)
|
||||||
|
|
||||||
# získáme body odjakživa
|
# získáme body odjakživa
|
||||||
resitel_odjakzivabody_slov = body_resitelu_odjakziva(cislo.rocnik,
|
resitel_odjakzivabody_slov = body_resitelu(aktivni_resitele, cislo)
|
||||||
aktivni_resitele)
|
|
||||||
|
|
||||||
# řešitelé setřídění podle bodů za číslo sestupně
|
# řešitelé setřídění podle bodů za číslo sestupně
|
||||||
setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn]
|
setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn]
|
||||||
|
@ -692,10 +736,7 @@ def vysledkovka_cisla(cislo, context=None):
|
||||||
setrizeni_resitele_body[i], # body za ročník (spočítané výše s pořadím)
|
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
|
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)
|
radky_vysledkovky.append(radek)
|
||||||
print("Přikládám {}-tý řádek.".format(i))
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# vytahané informace předáváme do kontextu
|
# vytahané informace předáváme do kontextu
|
||||||
|
@ -704,7 +745,6 @@ def vysledkovka_cisla(cislo, context=None):
|
||||||
context['problemy'] = hlavni_problemy
|
context['problemy'] = hlavni_problemy
|
||||||
#context['v_cisle_zadane'] = TODO
|
#context['v_cisle_zadane'] = TODO
|
||||||
#context['resene_problemy'] = resene_problemy
|
#context['resene_problemy'] = resene_problemy
|
||||||
print("Předávám kontext.")
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
class CisloView(generic.DetailView):
|
class CisloView(generic.DetailView):
|
||||||
|
@ -742,7 +782,7 @@ class ArchivTemataView(generic.ListView):
|
||||||
### Generovani vysledkovky
|
### Generovani vysledkovky
|
||||||
|
|
||||||
class CisloVysledkovkaView(CisloView):
|
class CisloVysledkovkaView(CisloView):
|
||||||
"View vytvořené pro stránku zobrazující výsledkovku čísla v TeXu."
|
"""View vytvořené pro stránku zobrazující výsledkovku čísla v TeXu."""
|
||||||
|
|
||||||
model = Cislo
|
model = Cislo
|
||||||
template_name = 'seminar/archiv/cislo_vysledkovka.tex'
|
template_name = 'seminar/archiv/cislo_vysledkovka.tex'
|
||||||
|
@ -752,7 +792,7 @@ class CisloVysledkovkaView(CisloView):
|
||||||
#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
|
#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
|
||||||
|
|
||||||
class RocnikVysledkovkaView(RocnikView):
|
class RocnikVysledkovkaView(RocnikView):
|
||||||
"View vytvořené pro stránku zobrazující výsledkovku ročníku v TeXu."
|
""" View vytvořené pro stránku zobrazující výsledkovku ročníku v TeXu."""
|
||||||
model = Rocnik
|
model = Rocnik
|
||||||
template_name = 'seminar/archiv/rocnik_vysledkovka.tex'
|
template_name = 'seminar/archiv/rocnik_vysledkovka.tex'
|
||||||
#content_type = 'application/x-tex; charset=UTF8'
|
#content_type = 'application/x-tex; charset=UTF8'
|
||||||
|
@ -761,6 +801,7 @@ class RocnikVysledkovkaView(RocnikView):
|
||||||
#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
|
#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
|
||||||
|
|
||||||
### Generovani obalek
|
### Generovani obalek
|
||||||
|
|
||||||
class CisloObalkyStruct:
|
class CisloObalkyStruct:
|
||||||
rocnik = None
|
rocnik = None
|
||||||
cisla = None
|
cisla = None
|
||||||
|
@ -785,13 +826,15 @@ def aktivniResitele(rocnik,cislo):
|
||||||
|
|
||||||
letos.rocnik = Rocnik.objects.get(rocnik = rocnik)
|
letos.rocnik = Rocnik.objects.get(rocnik = rocnik)
|
||||||
loni.rocnik = Rocnik.objects.get(rocnik = int(rocnik)-1)
|
loni.rocnik = Rocnik.objects.get(rocnik = int(rocnik)-1)
|
||||||
letos.cisla = Cislo.objects.filter(rocnik=letos.rocnik,cislo__lte = cislo)
|
letos.cisla = Cislo.objects.filter(rocnik=letos.rocnik, cislo__lte = cislo)
|
||||||
loni.cisla = Cislo.objects.filter(rocnik=loni.rocnik)
|
loni.cisla = Cislo.objects.filter(rocnik=loni.rocnik)
|
||||||
if int(cislo) > 3:
|
if int(cislo) > 3:
|
||||||
problemy = Problem.objects.filter(cislo_zadani__in = letos.cisla)
|
problemy = Problem.objects.filter(cislo_zadani__in = letos.cisla)
|
||||||
else:
|
else:
|
||||||
problemy = Problem.objects.filter(Q(cislo_zadani__in = letos.cisla)|Q(cislo_zadani__in = loni.cisla))
|
problemy = Problem.objects.filter(
|
||||||
resitele = aktualni_resitele.filter(reseni__in = Reseni.objects.filter(problem__in=problemy)).distinct()
|
Q(cislo_zadani__in = letos.cisla) | Q(cislo_zadani__in = loni.cisla) )
|
||||||
|
resitele = aktualni_resitele.filter(reseni__in = Reseni.objects.filter(
|
||||||
|
problem__in=problemy)).distinct()
|
||||||
return resitele
|
return resitele
|
||||||
|
|
||||||
|
|
||||||
|
@ -838,13 +881,15 @@ def oldObalkovaniView(request, rocnik, cislo):
|
||||||
### Tituly
|
### Tituly
|
||||||
|
|
||||||
def TitulyView(request, rocnik, cislo):
|
def TitulyView(request, rocnik, cislo):
|
||||||
|
""" View pro stažení makra titulů v TeXu."""
|
||||||
rocnik_obj = Rocnik.objects.get(rocnik = rocnik)
|
rocnik_obj = Rocnik.objects.get(rocnik = rocnik)
|
||||||
resitele = Resitel.objects.filter(rok_maturity__gte = rocnik_obj.prvni_rok)
|
resitele = Resitel.objects.filter(rok_maturity__gte = rocnik_obj.prvni_rok)
|
||||||
cislo_obj = Cislo.objects.get(rocnik = rocnik_obj, poradi = cislo)
|
cislo_obj = Cislo.objects.get(rocnik = rocnik_obj, poradi = cislo)
|
||||||
|
|
||||||
asciijmena = []
|
asciijmena = []
|
||||||
jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka), pokud ano, vrátí se jako true
|
jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka),
|
||||||
slovnik_s_body = body_resitelu_odjakziva(rocnik_obj, resitele)
|
# pokud ano, vrátí se jako true
|
||||||
|
slovnik_s_body = body_resitelu(resitele, rocnik_obj)
|
||||||
|
|
||||||
for resitel in resitele:
|
for resitel in resitele:
|
||||||
resitel.titul = resitel.get_titul(slovnik_s_body[resitel.id])
|
resitel.titul = resitel.get_titul(slovnik_s_body[resitel.id])
|
||||||
|
@ -862,8 +907,6 @@ def TitulyView(request, rocnik, cislo):
|
||||||
return render(request, 'seminar/archiv/tituly.tex',
|
return render(request, 'seminar/archiv/tituly.tex',
|
||||||
{'resitele': resitele,'jmenovci':jmenovci},content_type="text/plain")
|
{'resitele': resitele,'jmenovci':jmenovci},content_type="text/plain")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Soustredeni
|
### Soustredeni
|
||||||
|
|
||||||
class SoustredeniListView(generic.ListView):
|
class SoustredeniListView(generic.ListView):
|
||||||
|
@ -892,13 +935,13 @@ class SoustredeniUcastniciBaseView(generic.ListView):
|
||||||
|
|
||||||
|
|
||||||
class SoustredeniMailyUcastnikuView(SoustredeniUcastniciBaseView):
|
class SoustredeniMailyUcastnikuView(SoustredeniUcastniciBaseView):
|
||||||
"""Seznam e-mailů řešitelů oddělených čárkami"""
|
""" Seznam e-mailů řešitelů oddělených čárkami. """
|
||||||
model = Soustredeni_Ucastnici
|
model = Soustredeni_Ucastnici
|
||||||
template_name = 'seminar/soustredeni/maily_ucastniku.txt'
|
template_name = 'seminar/soustredeni/maily_ucastniku.txt'
|
||||||
|
|
||||||
|
|
||||||
class SoustredeniUcastniciView(SoustredeniUcastniciBaseView):
|
class SoustredeniUcastniciView(SoustredeniUcastniciBaseView):
|
||||||
"""HTML tabulka účastníků pro tisk"""
|
""" HTML tabulka účastníků pro tisk. """
|
||||||
model = Soustredeni_Ucastnici
|
model = Soustredeni_Ucastnici
|
||||||
template_name = 'seminar/soustredeni/seznam_ucastniku.html'
|
template_name = 'seminar/soustredeni/seznam_ucastniku.html'
|
||||||
|
|
||||||
|
@ -1020,11 +1063,11 @@ def texUploadView(request):
|
||||||
}
|
}
|
||||||
problem_typ = typy[meta["typ"]]
|
problem_typ = typy[meta["typ"]]
|
||||||
|
|
||||||
# Pokud už problém existuje, vytáhneme jej z db a upravíme
|
# Pokud už problém existuje, vytáhneme jej z db a upravíme.
|
||||||
# Pokud neexistuje, vytvoříme jej jedině pokud je to vynucené
|
# Pokud neexistuje, vytvoříme jej jedině pokud je to vynucené.
|
||||||
|
|
||||||
# Pokud ročník/číslo ještě neexistuje, vyhodí to výjimku ->
|
# Pokud ročník/číslo ještě neexistuje, vyhodí to výjimku ->
|
||||||
# číslo/ročník se musí založit ručně v adminu
|
# číslo/ročník se musí založit ručně v adminu.
|
||||||
rocnik = Rocnik.objects.get(rocnik=meta["rocnik"])
|
rocnik = Rocnik.objects.get(rocnik=meta["rocnik"])
|
||||||
cislo = Cislo.objects.get(rocnik=rocnik, cislo=meta["cislo"])
|
cislo = Cislo.objects.get(rocnik=rocnik, cislo=meta["cislo"])
|
||||||
|
|
||||||
|
@ -1158,7 +1201,8 @@ class ResitelView(LoginRequiredMixin,generic.DetailView):
|
||||||
print(self.request.user)
|
print(self.request.user)
|
||||||
return Resitel.objects.get(osoba__user=self.request.user)
|
return Resitel.objects.get(osoba__user=self.request.user)
|
||||||
|
|
||||||
## Formulare
|
### Formulare
|
||||||
|
|
||||||
class AddSolutionView(LoginRequiredMixin, FormView):
|
class AddSolutionView(LoginRequiredMixin, FormView):
|
||||||
template_name = 'seminar/org/vloz_reseni.html'
|
template_name = 'seminar/org/vloz_reseni.html'
|
||||||
form_class = f.VlozReseniForm
|
form_class = f.VlozReseniForm
|
||||||
|
@ -1197,9 +1241,6 @@ class SubmitSolutionView(LoginRequiredMixin, CreateView):
|
||||||
|
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
return HttpResponseRedirect(self.get_success_url())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def resetPasswordView(request):
|
def resetPasswordView(request):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -1361,10 +1402,6 @@ def prihlaskaView(request):
|
||||||
|
|
||||||
return render(request, 'seminar/prihlaska.html', {'form': form})
|
return render(request, 'seminar/prihlaska.html', {'form': form})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# FIXME: Tohle asi vlastně vůbec nepatří do aplikace 'seminar'
|
# FIXME: Tohle asi vlastně vůbec nepatří do aplikace 'seminar'
|
||||||
class LoginView(auth_views.LoginView):
|
class LoginView(auth_views.LoginView):
|
||||||
# Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL
|
# Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL
|
||||||
|
@ -1382,25 +1419,25 @@ class LogoutView(auth_views.LogoutView):
|
||||||
# Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité.
|
# Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité.
|
||||||
next_page = reverse_lazy('titulni_strana')
|
next_page = reverse_lazy('titulni_strana')
|
||||||
|
|
||||||
# "Chci resetovat heslo"
|
|
||||||
class PasswordResetView(auth_views.PasswordResetView):
|
class PasswordResetView(auth_views.PasswordResetView):
|
||||||
|
""" Chci resetovat heslo. """
|
||||||
#template_name = 'seminar/password_reset.html'
|
#template_name = 'seminar/password_reset.html'
|
||||||
# TODO: vlastní email_template_name a subject_template_name a html_email_template_name
|
# TODO: vlastní email_template_name a subject_template_name a html_email_template_name
|
||||||
success_url = reverse_lazy('reset_password_done')
|
success_url = reverse_lazy('reset_password_done')
|
||||||
from_email = 'login@mam.mff.cuni.cz'
|
from_email = 'login@mam.mff.cuni.cz'
|
||||||
|
|
||||||
# "Poslali jsme e-mail (pokud bylo kam))"
|
|
||||||
class PasswordResetDoneView(auth_views.PasswordResetDoneView):
|
class PasswordResetDoneView(auth_views.PasswordResetDoneView):
|
||||||
|
""" Poslali jsme e-mail (pokud bylo kam)). """
|
||||||
#template_name = 'seminar/password_reset_done.html'
|
#template_name = 'seminar/password_reset_done.html'
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# "Vymysli si heslo"
|
|
||||||
class PasswordResetConfirmView(auth_views.PasswordResetConfirmView):
|
class PasswordResetConfirmView(auth_views.PasswordResetConfirmView):
|
||||||
|
""" Vymysli si heslo. """
|
||||||
#template_name = 'seminar/password_confirm_done.html'
|
#template_name = 'seminar/password_confirm_done.html'
|
||||||
success_url = reverse_lazy('reset_password_complete')
|
success_url = reverse_lazy('reset_password_complete')
|
||||||
|
|
||||||
# "Heslo se asi změnilo."
|
|
||||||
class PasswordResetCompleteView(auth_views.PasswordResetCompleteView):
|
class PasswordResetCompleteView(auth_views.PasswordResetCompleteView):
|
||||||
|
""" Heslo se asi změnilo."""
|
||||||
#template_name = 'seminar/password_complete_done.html'
|
#template_name = 'seminar/password_complete_done.html'
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|