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 %} |         {% endfor %} | ||||||
|         <th class='border-r'>Za číslo</sup> |         <th class='border-r'>Za číslo</sup> | ||||||
|         <th class='border-r'>Za ročník |         <th class='border-r'>Za ročník | ||||||
|         <th class='border-r'>Odjakživa |         {#<th class='border-r'>Odjakživa#} | ||||||
|     {% for rv in vysledkovka %} |     {% for rv in radky_vysledkovky %} | ||||||
|       <tr> |       <tr> | ||||||
|         <td class='border-r'>{% autoescape off %}{{ rv.poradi }}{% endautoescape %} |         <td class='border-r'>{% autoescape off %}{{ rv.poradi }}{% endautoescape %} | ||||||
|             <th class='border-r'> |             <th class='border-r'> | ||||||
|             {% if rv.titul %} |             {% if rv.resitel.get_titul != "" %} | ||||||
|               {{ rv.titul }}<sup>MM</sup> |               {{ rv.resitel.get_titul }}<sup>MM</sup> | ||||||
|             {% endif %} |             {% endif %} | ||||||
|             {{ rv.resitel.plne_jmeno }} |             {{ rv.resitel.osoba.plne_jmeno }} | ||||||
|         {% for b in rv.body_ulohy %} |         {% for b in rv.hlavni_problemy_body %} | ||||||
|         <td class='border-r'>{{ b }} |         <td class='border-r'>{{ b }} | ||||||
|         {% endfor %} |         {% endfor %} | ||||||
|         <td class='border-r'>{{ rv.body_cislo }} |         <td class='border-r'>{{ rv.body_cislo }} | ||||||
|         <td class='border-r'><b>{{ rv.body_celkem_rocnik }}</b> |         <td class='border-r'><b>{{ rv.body_rocnik }}</b> | ||||||
|         <td class='border-r'>{{ rv.body_celkem_odjakziva }} |         {# <td class='border-r'>{{ rv.body_celkem_odjakziva }}#} | ||||||
|       </tr> |       </tr> | ||||||
|     {% endfor %} |     {% endfor %} | ||||||
|     </table> |     </table> | ||||||
|  |  | ||||||
							
								
								
									
										223
									
								
								seminar/views.py
									
									
									
									
									
								
							
							
						
						
									
										223
									
								
								seminar/views.py
									
									
									
									
									
								
							|  | @ -426,28 +426,34 @@ def sloupec_s_poradim(seznam_s_body): | ||||||
| 		aktualni_poradi = aktualni_poradi + velikost_skupiny | 		aktualni_poradi = aktualni_poradi + velikost_skupiny | ||||||
| 	return sloupec_s_poradim | 	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 | ## 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): | #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  | #	# sečteme body za daný problém přes všechna řešení daného problému  | ||||||
| 	# od daného řešitele | #	# od daného řešitele | ||||||
| 	reseni_resitele = Reseni.objects.filter(resitele__in=resitel) | #	reseni_resitele = s.Reseni_Resitele.objects.filter(resitele=resitel) | ||||||
| 	hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele,  | #	hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele,  | ||||||
| 				cislo_body=cislo) | #				cislo_body=cislo) | ||||||
| 	# XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains | #	# XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains | ||||||
| 	# nebo in | #	# nebo in | ||||||
| 	for r in hodnoceni_resitele: | #	for r in hodnoceni_resitele: | ||||||
| 		soucet += r.body | #		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ů | ## spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele | ||||||
| 	for p in problem.podproblem.all():  | #def body_resitele_problemu_v_cisle(problem, resitel, cislo): | ||||||
| 	# i přes jméno by to měla být množina jeho podproblémů | #	# probably FIXED: nezohledňuje číslo, do kterého se body počítají | ||||||
| 		soucet += __soucet_resitele_problemu(p, resitel, soucet) | #	return __soucet_resitele_problemu(problem, resitel, cislo, 0) | ||||||
| 	return soucet |  | ||||||
| 
 | 
 | ||||||
| # spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele | # pro daný problém vrátí jeho nejvyšší nadproblém | ||||||
| def body_resitele_problemu_v_cisle(problem, resitel, cislo): | def hlavni_problem(problem): | ||||||
| 	# probably FIXED: nezohledňuje číslo, do kterého se body počítají | 	while not(problem.nadproblem == None): | ||||||
| 	return __soucet_resitele_problemu(problem, resitel, cislo, 0) | 		problem = problem.nadproblem | ||||||
|  | 	return 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): | ||||||
|  | @ -463,9 +469,7 @@ def hlavni_problemy_cisla(cislo): | ||||||
| 	# (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) | 	# (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) | ||||||
| 	hlavni_problemy = [] | 	hlavni_problemy = [] | ||||||
| 	for p in problemy: | 	for p in problemy: | ||||||
| 		while not(p.nadproblem == None): | 		hlavni_problemy.append(hlavni_problem(p)) | ||||||
| 			p = p.nadproblem |  | ||||||
| 		hlavni_problemy.append(p) |  | ||||||
| 		 | 		 | ||||||
| 	# zunikátnění | 	# zunikátnění | ||||||
| 	hlavni_problemy_set = set(hlavni_problemy) | 	hlavni_problemy_set = set(hlavni_problemy) | ||||||
|  | @ -474,38 +478,54 @@ def hlavni_problemy_cisla(cislo): | ||||||
| 	 | 	 | ||||||
| 	return hlavni_problemy | 	return hlavni_problemy | ||||||
| 
 | 
 | ||||||
| def body_resitele_odjakziva(resitel): | # vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník | ||||||
| 	body = 0 | def body_resitelu_za_rocnik(rocnik, aktivni_resitele): | ||||||
| 	resitelova_hodnoceni = Hodnoceni.objects.select_related('body').all().filter(reseni_resitele=resitel) | 	body_za_rocnik = {} | ||||||
| 	# TODO: v radku nahore chceme _in nebo _contains | 	# inicializujeme na 0 pro všechny aktivní řešitele | ||||||
| 	for hodnoceni in resitelova_hodnoceni: | 	for ar in aktivni_resitele: | ||||||
| 		body = body + hodnoceni.body | 		body_za_rocnik[str(ar.id)] = 0 | ||||||
| 	return body | 	 | ||||||
|  | 	# 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 | # spočítá součet všech bodů řešitele za dané číslo | ||||||
| def body_resitele_v_cisle(resitel, cislo): | #def body_resitele_v_cisle(resitel, cislo): | ||||||
| 	hlavni_problemy = hlavni_problemy_cisla(cislo) | #	hlavni_problemy = hlavni_problemy_cisla(cislo) | ||||||
| 	body_resitele = 0 | #	body_resitele = 0 | ||||||
| 	for h in hlavni_problemy: | #	for h in hlavni_problemy: | ||||||
| 		body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, resitel, cislo) | #		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 | #	# 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? | #	# ř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. | #	# Tady to ale nevadí, tady se počítá součet za číslo. | ||||||
| 	return body_resitele | #	return body_resitele | ||||||
| 
 | 
 | ||||||
| # spočítá součet všech bodů řešitele za daný rok (nebo jen do daného čísla včetně) | # 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): | #def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): | ||||||
| 	# pokud do_cisla=None, tak do posledního čísla v ročníku | #	# pokud do_cisla=None, tak do posledního čísla v ročníku | ||||||
| 	# do_cisla je objekt Cislo | #	# do_cisla je objekt Cislo | ||||||
| 	cisla = rocnik.cisla.all() # funkce vrátí pole objektů  | #	cisla = rocnik.cisla.all() # funkce vrátí pole objektů  | ||||||
| 	# Cislo už lexikograficky setřízené, viz models | #	# Cislo už lexikograficky setřízené, viz models | ||||||
| 	body = 0 | #	body = 0 | ||||||
| 	for cislo in cisla: | #	for cislo in cisla: | ||||||
| 		if cislo.poradi == do_cisla.poradi: break | #		if cislo.poradi == do_cisla.poradi: break | ||||||
| 		# druhá část zaručuje, že máme výsledky do daného čísla včetně | #		# druhá část zaručuje, že máme výsledky do daného čísla včetně | ||||||
| 		body = body + body_resitele_v_cisle(resitel, cislo) | #		body = body + body_resitele_v_cisle(resitel, cislo) | ||||||
| 	return body | #	return body | ||||||
| 
 | 
 | ||||||
|  | # 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 | ||||||
| #	formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" | #	formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" | ||||||
|  | @ -612,19 +632,17 @@ class ProblemView(generic.DetailView): | ||||||
| 		return context | 		return context | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class VysledkyResitele(object): | class RadekVysledkovky(object): | ||||||
| 	"""Pro daného řešitele ukládá počet bodů za jednotlivé úlohy a celkový | 	"""Obsahuje věci, které se hodí vědět při konstruování výsledkovky. | ||||||
| 	počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" | 	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.resitel = resitel | ||||||
| 		self.cislo = cislo | 		self.body_cislo = body_cislo | ||||||
| 		self.body_cislo = body_resitele_v_cisle(resitel, cislo) | 		self.body_rocnik = body_rocnik | ||||||
| 		self.body = [] | #		TODO self.body_celkem_odjakziva = odjakziva | ||||||
| 		self.rocnik = rocnik | 		self.poradi = poradi | ||||||
| 		self.body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) | 		self.body_problemy_sezn = body_problemy_sezn | ||||||
| 		self.body_celkem_odjakziva = resitel.vsechny_body() |  | ||||||
| 		self.poradi = 0 |  | ||||||
| 
 | 
 | ||||||
| class CisloView(generic.DetailView): | class CisloView(generic.DetailView): | ||||||
| 	model = Cislo | 	model = Cislo | ||||||
|  | @ -648,38 +666,84 @@ class CisloView(generic.DetailView): | ||||||
| 	def get_context_data(self, **kwargs): | 	def get_context_data(self, **kwargs): | ||||||
| 		context = super(CisloView, self).get_context_data(**kwargs) | 		context = super(CisloView, self).get_context_data(**kwargs) | ||||||
| 
 | 
 | ||||||
| 		## TODO upravit dle nového modelu |  | ||||||
| 		cislo = context['cislo'] | 		cislo = context['cislo'] | ||||||
| 		hlavni_problemy = hlavni_problemy_cisla(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 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 | 		## 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( | 		aktivni_resitele = Resitel.objects.filter( | ||||||
| 				rok_maturity__gte=cislo.rocnik.druhy_rok()) | 				rok_maturity__gte=cislo.rocnik.druhy_rok()) | ||||||
| 				# TODO: zkusit hodnoceni__rocnik... | 				# TODO: zkusit hodnoceni__rocnik... | ||||||
| 				#.filter(hodnoceni_set__rocnik__eq=cislo_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: | 		for ar in aktivni_resitele: | ||||||
| 			# získáme výsledky řešitele - součty přes číslo a ročník | 			# řešitele převedeme na řetězec pomocí unikátního id | ||||||
| 			vr = VysledkyResitele(ar, cislo, cislo.rocnik) | 			cislobody[str(ar.id)] = "" | ||||||
| 			for hp in hlavni_problemy: | 			for hp in hlavni_problemy: | ||||||
| 				vr.body.append( | 				slovnik = hlavni_problemy_slovnik[str(hp.id)] | ||||||
| 				body_resitele_problemu_v_cisle(hp, ar, cislo)) | 				slovnik[str(ar.id)] = "" | ||||||
| 			radky_vysledkovky.append(vr) |  | ||||||
| 		 | 		 | ||||||
| 		# setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů | 		# vezmeme všechna řešení s body do daného čísla | ||||||
| 		radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) | 		reseni_do_cisla = Reseni.objects.filter(hodnoceni__cislo_body=cislo) | ||||||
| 		 | 		 | ||||||
| 		# generujeme sloupec s pořadím pomocí stejně zvané funkce | 		# projdeme všechna řešení do čísla a přičteme body každému řešiteli do celkových | ||||||
| 		pocty_bodu = [rv.body_rocnik for rv in radky_vysledkovky] | 		# bodů i do bodů za problém | ||||||
| 		sloupec_poradi = sloupec_s_poradim(pocty_bodu) | 		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 | ||||||
| 
 | 
 | ||||||
| 		# každému řádku výsledkovky přidáme jeho pořadí | 				if nadproblem_slovnik[str(resitel.id)] == "": | ||||||
| 		i = 0 | 					nadproblem_slovnik[str(resitel.id)] = 0   | ||||||
| 		for rv in radky_vysledkovky: | 				nadproblem_slovnik[str(resitel.id)] += body  | ||||||
| 			rv.poradi = sloupec_poradi[i] | 
 | ||||||
| 			i = i + 1 | 		# 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 | 		# vytahané informace předáváme do kontextu | ||||||
| 		context['cislo'] = cislo | 		context['cislo'] = cislo | ||||||
|  | @ -689,7 +753,6 @@ class CisloView(generic.DetailView): | ||||||
| #		context['resene_problemy'] = resene_problemy | #		context['resene_problemy'] = resene_problemy | ||||||
| 		#XXX testovat | 		#XXX testovat | ||||||
| 		#XXX opravit to, že se nezobrazují body za jednotlivé úlohy | 		#XXX opravit to, že se nezobrazují body za jednotlivé úlohy | ||||||
| 
 |  | ||||||
| 		return context | 		return 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())) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Anet
						Anet