nepadající (ale nezobrazující se) verze výsledkovky v2
This commit is contained in:
		
							parent
							
								
									d99e4064e8
								
							
						
					
					
						commit
						caa274460d
					
				
					 2 changed files with 154 additions and 91 deletions
				
			
		|  | @ -67,21 +67,21 @@ | |||
|         {% endfor %} | ||||
|         <th class='border-r'>Za číslo</sup> | ||||
|         <th class='border-r'>Za ročník | ||||
|         <th class='border-r'>Odjakživa | ||||
|     {% for rv in vysledkovka %} | ||||
|         {#<th class='border-r'>Odjakživa#} | ||||
|     {% for rv in radky_vysledkovky %} | ||||
|       <tr> | ||||
|         <td class='border-r'>{% autoescape off %}{{ rv.poradi }}{% endautoescape %} | ||||
|             <th class='border-r'> | ||||
|             {% if rv.titul %} | ||||
|               {{ rv.titul }}<sup>MM</sup> | ||||
|             {% if rv.resitel.get_titul != "" %} | ||||
|               {{ rv.resitel.get_titul }}<sup>MM</sup> | ||||
|             {% endif %} | ||||
|             {{ rv.resitel.plne_jmeno }} | ||||
|         {% for b in rv.body_ulohy %} | ||||
|             {{ rv.resitel.osoba.plne_jmeno }} | ||||
|         {% for b in rv.hlavni_problemy_body %} | ||||
|         <td class='border-r'>{{ b }} | ||||
|         {% endfor %} | ||||
|         <td class='border-r'>{{ rv.body_cislo }} | ||||
|         <td class='border-r'><b>{{ rv.body_celkem_rocnik }}</b> | ||||
|         <td class='border-r'>{{ rv.body_celkem_odjakziva }} | ||||
|         <td class='border-r'><b>{{ rv.body_rocnik }}</b> | ||||
|         {# <td class='border-r'>{{ rv.body_celkem_odjakziva }}#} | ||||
|       </tr> | ||||
|     {% endfor %} | ||||
|     </table> | ||||
|  |  | |||
							
								
								
									
										229
									
								
								seminar/views.py
									
									
									
									
									
								
							
							
						
						
									
										229
									
								
								seminar/views.py
									
									
									
									
									
								
							|  | @ -426,28 +426,34 @@ def sloupec_s_poradim(seznam_s_body): | |||
| 		aktualni_poradi = aktualni_poradi + velikost_skupiny | ||||
| 	return sloupec_s_poradim | ||||
| 
 | ||||
| # spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy | ||||
| def __soucet_resitele_problemu(problem, resitel, cislo, soucet): | ||||
| 	# sečteme body za daný problém přes všechna řešení daného problému  | ||||
| 	# od daného řešitele | ||||
| 	reseni_resitele = Reseni.objects.filter(resitele__in=resitel) | ||||
| 	hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele,  | ||||
| 				cislo_body=cislo) | ||||
| 	# XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains | ||||
| 	# nebo in | ||||
| 	for r in hodnoceni_resitele: | ||||
| 		soucet += r.body | ||||
| ## spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy | ||||
| #def __soucet_resitele_problemu(problem, resitel, cislo, soucet): | ||||
| #	# sečteme body za daný problém přes všechna řešení daného problému  | ||||
| #	# od daného řešitele | ||||
| #	reseni_resitele = s.Reseni_Resitele.objects.filter(resitele=resitel) | ||||
| #	hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele,  | ||||
| #				cislo_body=cislo) | ||||
| #	# XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains | ||||
| #	# nebo in | ||||
| #	for r in hodnoceni_resitele: | ||||
| #		soucet += r.body | ||||
| # | ||||
| #	# a přičteme k tomu hodnocení všech podproblémů | ||||
| #	for p in problem.podproblem.all():  | ||||
| #	# i přes jméno by to měla být množina jeho podproblémů | ||||
| #		soucet += __soucet_resitele_problemu(p, resitel, soucet) | ||||
| #	return soucet | ||||
| 
 | ||||
| 	# a přičteme k tomu hodnocení všech podproblémů | ||||
| 	for p in problem.podproblem.all():  | ||||
| 	# i přes jméno by to měla být množina jeho podproblémů | ||||
| 		soucet += __soucet_resitele_problemu(p, resitel, soucet) | ||||
| 	return soucet | ||||
| ## spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele | ||||
| #def body_resitele_problemu_v_cisle(problem, resitel, cislo): | ||||
| #	# probably FIXED: nezohledňuje číslo, do kterého se body počítají | ||||
| #	return __soucet_resitele_problemu(problem, resitel, cislo, 0) | ||||
| 
 | ||||
| # spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele | ||||
| def body_resitele_problemu_v_cisle(problem, resitel, cislo): | ||||
| 	# probably FIXED: nezohledňuje číslo, do kterého se body počítají | ||||
| 	return __soucet_resitele_problemu(problem, resitel, cislo, 0) | ||||
| # pro daný problém vrátí jeho nejvyšší nadproblém | ||||
| def hlavni_problem(problem): | ||||
| 	while not(problem.nadproblem == None): | ||||
| 		problem = problem.nadproblem | ||||
| 	return problem | ||||
| 
 | ||||
| # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém | ||||
| def hlavni_problemy_cisla(cislo): | ||||
|  | @ -463,9 +469,7 @@ def hlavni_problemy_cisla(cislo): | |||
| 	# (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) | ||||
| 	hlavni_problemy = [] | ||||
| 	for p in problemy: | ||||
| 		while not(p.nadproblem == None): | ||||
| 			p = p.nadproblem | ||||
| 		hlavni_problemy.append(p) | ||||
| 		hlavni_problemy.append(hlavni_problem(p)) | ||||
| 		 | ||||
| 	# zunikátnění | ||||
| 	hlavni_problemy_set = set(hlavni_problemy) | ||||
|  | @ -474,38 +478,54 @@ def hlavni_problemy_cisla(cislo): | |||
| 	 | ||||
| 	return hlavni_problemy | ||||
| 
 | ||||
| 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 | ||||
| # 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): | ||||
| 	body_za_rocnik = {} | ||||
| 	# inicializujeme na 0 pro všechny aktivní řešitele | ||||
| 	for ar in 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 | ||||
| 	reseni = Reseni.objects.filter(hodnoceni__cislo_body__rocnik=rocnik) | ||||
| 	for res in reseni: | ||||
| 		for resitel in res.resitele.all(): | ||||
| 			for hodn in res.hodnoceni.all(): | ||||
| 				body_za_rocnik[str(resitel.id)] += hodn.body | ||||
| 	return body_za_rocnik | ||||
| 
 | ||||
| #def body_resitele_odjakziva(resitel): | ||||
| #	body = 0 | ||||
| #	resitelova_hodnoceni = Hodnoceni.objects.select_related('body').all().filter(reseni_resitele=resitel) | ||||
| #	# TODO: v radku nahore chceme _in nebo _contains | ||||
| #	for hodnoceni in resitelova_hodnoceni: | ||||
| #		body = body + hodnoceni.body | ||||
| #	return body | ||||
| 
 | ||||
| # spočítá součet všech bodů řešitele za dané číslo | ||||
| 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 | ||||
| #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 | ||||
| #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 | ||||
| #def vysledkovka_rocniku(rocnik, jen_verejne=True): | ||||
| #	"""Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve | ||||
| #	formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" | ||||
|  | @ -612,19 +632,17 @@ class ProblemView(generic.DetailView): | |||
| 		return context | ||||
| 
 | ||||
| 
 | ||||
| class VysledkyResitele(object): | ||||
| 	"""Pro daného řešitele ukládá počet bodů za jednotlivé úlohy a celkový | ||||
| 	počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" | ||||
| class RadekVysledkovky(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, resitel, cislo, rocnik): | ||||
| 	def __init__(self, poradi, resitel, body_problemy_sezn, body_cislo, body_rocnik): | ||||
| 		self.resitel = resitel | ||||
| 		self.cislo = cislo | ||||
| 		self.body_cislo = body_resitele_v_cisle(resitel, cislo) | ||||
| 		self.body = [] | ||||
| 		self.rocnik = rocnik | ||||
| 		self.body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) | ||||
| 		self.body_celkem_odjakziva = resitel.vsechny_body() | ||||
| 		self.poradi = 0 | ||||
| 		self.body_cislo = body_cislo | ||||
| 		self.body_rocnik = body_rocnik | ||||
| #		TODO self.body_celkem_odjakziva = odjakziva | ||||
| 		self.poradi = poradi | ||||
| 		self.body_problemy_sezn = body_problemy_sezn | ||||
| 
 | ||||
| class CisloView(generic.DetailView): | ||||
| 	model = Cislo | ||||
|  | @ -648,48 +666,93 @@ class CisloView(generic.DetailView): | |||
| 	def get_context_data(self, **kwargs): | ||||
| 		context = super(CisloView, self).get_context_data(**kwargs) | ||||
| 
 | ||||
| 		## TODO upravit dle nového modelu | ||||
| 		cislo = context['cislo'] | ||||
| 		hlavni_problemy = hlavni_problemy_cisla(cislo) | ||||
| 		# TODO setřídit hlavní problémy čísla podle id, ať jsou ve stejném pořadí pokaždé | ||||
| 		# pro každý hlavní problém zavedeme slovník s body za daný hlavní problém  | ||||
| 		# pro jednotlivé řešitele (slovník slovníků hlavních problémů) | ||||
| 		hlavni_problemy_slovnik = {} | ||||
| 		for hp in hlavni_problemy: | ||||
| 			hlavni_problemy_slovnik[str(hp.id)] = {} | ||||
| 
 | ||||
| 		## TODO dostat pro tyto problémy součet v daném čísle pro daného řešitele | ||||
| 		## TODO možná chytřeji vybírat aktivní řešitele | ||||
| 		## chceme letos něco poslal | ||||
| 		# aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají  | ||||
| 		# u alespoň jedné hodnoty něco jiného než NULL | ||||
| 		aktivni_resitele = Resitel.objects.filter( | ||||
| 				rok_maturity__gte=cislo.rocnik.druhy_rok()) | ||||
| 				# TODO: zkusit hodnoceni__rocnik... | ||||
| 				#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) | ||||
| 		radky_vysledkovky = [] | ||||
| 		# zakládání prázdných záznamů pro řešitele | ||||
| 		cislobody = {} | ||||
| 		for ar in aktivni_resitele: | ||||
| 			# získáme výsledky řešitele - součty přes číslo a ročník | ||||
| 			vr = VysledkyResitele(ar, cislo, cislo.rocnik) | ||||
| 			# řešitele převedeme na řetězec pomocí unikátního id | ||||
| 			cislobody[str(ar.id)] = "" | ||||
| 			for hp in hlavni_problemy: | ||||
| 				vr.body.append( | ||||
| 				body_resitele_problemu_v_cisle(hp, ar, cislo)) | ||||
| 			radky_vysledkovky.append(vr) | ||||
| 
 | ||||
| 		# setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů | ||||
| 		radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) | ||||
| 
 | ||||
| 		# generujeme sloupec s pořadím pomocí stejně zvané funkce | ||||
| 		pocty_bodu = [rv.body_rocnik for rv in radky_vysledkovky] | ||||
| 		sloupec_poradi = sloupec_s_poradim(pocty_bodu) | ||||
| 				slovnik = hlavni_problemy_slovnik[str(hp.id)] | ||||
| 				slovnik[str(ar.id)] = "" | ||||
| 		 | ||||
| 		# každému řádku výsledkovky přidáme jeho pořadí | ||||
| 		i = 0 | ||||
| 		for rv in radky_vysledkovky: | ||||
| 			rv.poradi = sloupec_poradi[i] | ||||
| 			i = i + 1 | ||||
| 		# vezmeme všechna řešení s body do daného čísla | ||||
| 		reseni_do_cisla = Reseni.objects.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 | ||||
| 		# bodů i do bodů za problém | ||||
| 		for reseni in reseni_do_cisla: | ||||
| 			body = reseni.hodnoceni.body	 | ||||
| 			problem = reseni.problem | ||||
| 			nadproblem = hlavni_problem(problem) | ||||
| 			nadproblem_slovnik = hlavni_problemy_slovnik[str(nadproblem.id)] | ||||
| 			for resitel in reseni.resitele: | ||||
| 				# testujeme na None, pokud první řešení daného řešitele, předěláme na 0 | ||||
| 				# (v dalším kroku přičteme reálný počet bodů), rozlišujeme tím mezi 0 a  | ||||
| 				# neodevzdaným řešením | ||||
| 				if cislobody[str(resitel.id)] == "": | ||||
| 					cislobody[str(resitel.id)] = 0  | ||||
| 				cislobody[str(resitel.id)] += body | ||||
| 
 | ||||
| 				if nadproblem_slovnik[str(resitel.id)] == "": | ||||
| 					nadproblem_slovnik[str(resitel.id)] = 0   | ||||
| 				nadproblem_slovnik[str(resitel.id)] += body  | ||||
| 
 | ||||
| 		# zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně | ||||
| 		resitel_rocnikbody_slov = body_resitelu_za_rocnik(cislo.rocnik, aktivni_resitele) | ||||
| 		resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(), | ||||
| 						key = lambda x: x[1], reverse = True) | ||||
| 		 | ||||
| 		# řešitelé setřídění podle bodů za číslo sestupně | ||||
| 		setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn] | ||||
| 		setrizeni_resitele = [Resitel.objects.get(id=i) for i in setrizeni_resitele_id] | ||||
| 				 | ||||
| 		# vytvoříme jednotlivé sloupce výsledkovky | ||||
| 		radky_vysledkovky = [] | ||||
| 		rocnik_body = [] | ||||
| 		cislo_body = [] | ||||
| 		hlavni_problemy_body = [] | ||||
| 		for ar_id in setrizeni_resitele_id: | ||||
| 			# vytáhneme ze slovníků body pro daného řešitele | ||||
| 			rocnik_body.append(resitel_rocnikbody_slov[ar_id]) | ||||
| 			cislo_body.append(cislobody[ar_id]) | ||||
| 			problemy = [] | ||||
| 			for hp in hlavni_problemy: | ||||
| 				problemy.append(hlavni_problemy_slovnik[str(hp.id)][ar_id]) | ||||
| 			hlavni_problemy_body.append(problemy) | ||||
| 		# pořadí určíme pomocí funkce, které dáme celkové body za ročník vzestupně | ||||
| 		poradi = sloupec_s_poradim(rocnik_body) | ||||
| 
 | ||||
| 		radky_vysledkovky = [] | ||||
| 		for i in range(0, len(setrizeni_resitele_id)): | ||||
| 			radek = RadekVysledkovky(poradi[i], setrizeni_resitele[i], | ||||
| 				hlavni_problemy_body[i], cislo_body[i], rocnik_body[i]) | ||||
| 			radky_vysledkovky.append(radek) | ||||
| 
 | ||||
| 		# vytahané informace předáváme do kontextu | ||||
| 		context['cislo'] = cislo | ||||
| 		context['radky_vysledkovky'] = radky_vysledkovky	 | ||||
| 		context['radky_vysledkovky'] = radky_vysledkovky | ||||
| 		context['problemy'] = hlavni_problemy | ||||
| #		context['v_cisle_zadane'] = TODO | ||||
| #		context['resene_problemy'] = resene_problemy | ||||
| 		#XXX testovat | ||||
| 		#XXX opravit to, že se nezobrazují body za jednotlivé úlohy | ||||
| 
 | ||||
| 		return context | ||||
| 
 | ||||
| #		problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku())) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Anet
						Anet