views: skoro funkční výsledkovka, problémy s body odjakživa, dotazy do databáze už jinak rozumně rychlé
This commit is contained in:
		
							parent
							
								
									d9558a750a
								
							
						
					
					
						commit
						64074d5dc6
					
				
					 1 changed files with 78 additions and 26 deletions
				
			
		|  | @ -477,6 +477,35 @@ def hlavni_problemy_cisla(cislo): | |||
| 	 | ||||
| 	return hlavni_problemy | ||||
| 
 | ||||
| # vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník | ||||
| # POZOR! Aktuálně počítá jen za posledních 10 let od zadaného ročníku | ||||
| def body_resitelu_odjakziva(rocnik, resitele): | ||||
| 	body_odjakziva = {} | ||||
| 
 | ||||
| 	for r in resitele: | ||||
| 		body_odjakziva[str(r.id)] = 0 | ||||
| #	# Body za posledních 10 let je dobrá aproximace pro naše potřeby (výsledkovka | ||||
| #	# s aktivními řešiteli) | ||||
| # | ||||
| #	body_pred_roky = [] | ||||
| #	for i in range(0, 10): | ||||
| #		body_pred_roky.append(body_resitelu_za_rocnik(rocnik-i, resitele)) | ||||
| # | ||||
| #	for r in resitele: | ||||
| #		for i in range(0,10): | ||||
| #			body_odjakziva[str(r.id)] += body_pred_roky[i][str(r.id)] | ||||
| 
 | ||||
| 
 | ||||
| # Nasledující řešení je sice správné, ale moc pomalé:	 | ||||
| 	for res in Reseni.objects.prefetch_related('resitele', 'hodnoceni').all(): | ||||
| 		for r in res.resitele.all(): | ||||
| 			# daný řešitel nemusí být v naší podmnožině | ||||
| 			if r not in resitele: continue | ||||
| 			 | ||||
| 			for hodn in res.hodnoceni.all(): | ||||
| 				pricti_body(body_odjakziva, r, hodn.body) | ||||
| 	return body_odjakziva | ||||
| 
 | ||||
| # 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 = {} | ||||
|  | @ -485,11 +514,11 @@ def body_resitelu_za_rocnik(rocnik, 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) | ||||
| 	reseni = Reseni.objects.prefetch_related('resitele', 'hodnoceni').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 | ||||
| 				pricti_body(body_za_rocnik, resitel, hodn.body) | ||||
| 	return body_za_rocnik | ||||
| 
 | ||||
| #def body_resitele_odjakziva(resitel): | ||||
|  | @ -635,13 +664,26 @@ 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, poradi, resitel, body_problemy_sezn, body_cislo, body_rocnik): | ||||
| 	def __init__(self, poradi, resitel, body_problemy_sezn,  | ||||
| 				body_cislo, body_rocnik, body_odjakziva): | ||||
| 		self.resitel = resitel | ||||
| 		self.body_cislo = body_cislo | ||||
| 		self.body_rocnik = body_rocnik | ||||
| #		TODO self.body_celkem_odjakziva = odjakziva | ||||
| 		self.body_celkem_odjakziva = body_odjakziva | ||||
| 		self.poradi = poradi | ||||
| 		self.body_problemy_sezn = body_problemy_sezn | ||||
| 	 | ||||
| 
 | ||||
| # přiřazuje danému řešiteli body do slovníku | ||||
| def pricti_body(slovnik, resitel, body): | ||||
| 	# testujeme na None (""), pokud je to 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 slovnik[str(resitel.id)] == "": | ||||
| 		slovnik[str(resitel.id)] = 0 | ||||
| 	 | ||||
| 	slovnik[str(resitel.id)] += body | ||||
| 
 | ||||
| class CisloView(generic.DetailView): | ||||
| 	model = Cislo | ||||
|  | @ -678,8 +720,8 @@ class CisloView(generic.DetailView): | |||
| 		## TODO možná chytřeji vybírat aktivní řešitele | ||||
| 		# aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají  | ||||
| 		# u alespoň jedné hodnoty něco jiného než NULL | ||||
| 		aktivni_resitele = Resitel.objects.filter( | ||||
| 				rok_maturity__gte=cislo.rocnik.druhy_rok()) | ||||
| 		aktivni_resitele = list(Resitel.objects.filter( | ||||
| 				rok_maturity__gte=cislo.rocnik.druhy_rok())) | ||||
| 				# TODO: zkusit hodnoceni__rocnik... | ||||
| 				#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) | ||||
| 		# zakládání prázdných záznamů pro řešitele | ||||
|  | @ -692,66 +734,76 @@ class CisloView(generic.DetailView): | |||
| 				slovnik[str(ar.id)] = "" | ||||
| 		 | ||||
| 		# vezmeme všechna řešení s body do daného čísla | ||||
| 		reseni_do_cisla = Reseni.objects.filter(hodnoceni__cislo_body=cislo) | ||||
| 		reseni_do_cisla = Reseni.objects.prefetch_related('problem', 'hodnoceni', 'resitele').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  | ||||
| 			 | ||||
| 			# řešení může řešit více problémů | ||||
| 			for prob in list(reseni.problem.all()): | ||||
| 				nadproblem = hlavni_problem(prob) | ||||
| 				nadproblem_slovnik = hlavni_problemy_slovnik[str(nadproblem.id)] | ||||
| 				 | ||||
| 				# a více hodnocení | ||||
| 				for hodn in list(reseni.hodnoceni.all()): | ||||
| 					body = hodn.body	 | ||||
| 					 | ||||
| 					# a více řešitelů | ||||
| 					for resitel in list(reseni.resitele.all()): | ||||
| 						pricti_body(cislobody, resitel, body) | ||||
| 						pricti_body(nadproblem_slovnik, resitel, 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) | ||||
| 		 | ||||
| 	 | ||||
| 		# získáme body odjakživa | ||||
| 		resitel_odjakzivabody_slov = body_resitelu_odjakziva(cislo.rocnik.druhy_rok(),  | ||||
| 									aktivni_resitele) | ||||
| 	 | ||||
| 		# ř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 = [] | ||||
| 		odjakziva_body = [] | ||||
| 		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 | ||||
| 			odjakziva_body.append(resitel_odjakzivabody_slov[ar_id]) | ||||
| 			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) | ||||
| 			print("{}: body za problémy - {}, číslobody - {}, ročníkbody - {}, odjakživabody - ".format(ar_id, problemy, cislobody[ar_id], resitel_rocnikbody_slov[ar_id])) | ||||
| 		# 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]) | ||||
| 				hlavni_problemy_body[i], cislo_body[i], rocnik_body[i], | ||||
| 				odjakziva_body[i]) | ||||
| 			radky_vysledkovky.append(radek) | ||||
| 			print("Přikládám {}-tý řádek.".format(i)) | ||||
| 
 | ||||
| 		print("Následuje předávání do kontextu.") | ||||
| 		# vytahané informace předáváme do kontextu | ||||
| 		context['cislo'] = cislo | ||||
| 		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 | ||||
| 		#XXX nefungují body odjakživa - asi typový problém | ||||
| 		#XXX nefungují tituly - možná korelace s výše uvedeným problémem | ||||
| 		print("Předávám kontext.") | ||||
| 		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