89 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from django.core.exceptions import ObjectDoesNotExist
 | |
| 
 | |
| import personalni.models
 | |
| 
 | |
| import tvorba.models as m
 | |
| 
 | |
| 
 | |
| def resi_v_rocniku(rocnik, cislo=None):
 | |
| 	""" Vrátí seznam řešitelů, co vyřešili nějaký problém v daném ročníku, do daného čísla.
 | |
| 	Parametry:
 | |
| 		rocnik (typu Rocnik)	ročník, ze kterého chci řešitele, co něco odevzdali
 | |
| 		cislo (typu Cislo)	číslo, do kterého včetně se počítá, že v daném
 | |
| 					ročníku řešitel něco poslal.
 | |
| 					Pokud není zadané, počítají se všechna řešení z daného ročníku.
 | |
| 	Výstup:
 | |
| 		QuerySet objektů typu Resitel """
 | |
| 
 | |
| 	if cislo is None:
 | |
| 		# filtrujeme pouze podle ročníku
 | |
| 		return personalni.models.Resitel.objects.filter(
 | |
| 			rok_maturity__gte=rocnik.druhy_rok(),
 | |
| 			reseni__hodnoceni__deadline_body__cislo__rocnik=rocnik
 | |
| 		).distinct()
 | |
| 	else:  # filtrujeme podle ročníku i čísla
 | |
| 		return personalni.models.Resitel.objects.filter(
 | |
| 			rok_maturity__gte=rocnik.druhy_rok(),
 | |
| 			reseni__hodnoceni__deadline_body__cislo__rocnik=rocnik,
 | |
| 			reseni__hodnoceni__deadline_body__cislo__poradi__lte=cislo.poradi
 | |
| 		).distinct()
 | |
| 
 | |
| 
 | |
| def aktivniResitele(cislo, pouze_letosni=False):
 | |
| 	""" Vrací QuerySet aktivních řešitelů, což jsou ti, co ještě neodmaturovali
 | |
| 	a letos něco poslali (anebo loni něco poslali, pokud jde o první tři čísla).
 | |
| 	Parametry:
 | |
| 		cislo (typu Cislo)	číslo, o které se jedná
 | |
| 		pouze_letosni		jen řešitelé, kteří tento rok něco poslali
 | |
| 
 | |
| 	"""
 | |
| 	letos = cislo.rocnik
 | |
| 
 | |
| 	# detekujeme, zda jde o první tři čísla či nikoli (tj. zda spamovat řešitele z minulého roku)
 | |
| 	zacatek_rocniku = True
 | |
| 	try:
 | |
| 		if int(cislo.poradi) > 3:
 | |
| 			zacatek_rocniku = False
 | |
| 	except ValueError:
 | |
| 		# if cislo.poradi != '7-8':
 | |
| 		# 	raise ValueError(f'{cislo} je neplatné číslo čísla (není int a není 7-8)')
 | |
| 		zacatek_rocniku = False
 | |
| 
 | |
| 	# nehledě na číslo chceme jen řešitele, kteří letos něco odevzdali
 | |
| 	if pouze_letosni:
 | |
| 		zacatek_rocniku = False
 | |
| 
 | |
| 	try:
 | |
| 		loni = m.Rocnik.objects.get(rocnik=letos.rocnik - 1)
 | |
| 	except ObjectDoesNotExist:
 | |
| 		# Pro první ročník neexistuje ročník předchozí
 | |
| 		zacatek_rocniku = False
 | |
| 
 | |
| 	if not zacatek_rocniku:
 | |
| 		return resi_v_rocniku(letos, cislo).filter(rok_maturity__gte=letos.druhy_rok())
 | |
| 	else:
 | |
| 		# spojíme querysety s řešiteli loni a letos do daného čísla
 | |
| 		return (resi_v_rocniku(loni) | resi_v_rocniku(letos, cislo))\
 | |
| 			.distinct().filter(rok_maturity__gte=letos.druhy_rok())
 | |
| 
 | |
| 
 | |
| # Pozor: zarovnáno velmi netradičně pro přehlednost
 | |
| roman_numerals = zip((1000, 900, 500, 400,  100, 90,   50,  40,   10,  9,    5,   4,    1),  # noqa
 | |
| 					 ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'))  # noqa
 | |
| 
 | |
| 
 | |
| def roman(num):
 | |
| 	res = ""
 | |
| 	for i, n in roman_numerals:
 | |
| 		res += n * (num // i)
 | |
| 		num %= i
 | |
| 	return res
 | |
| 
 | |
| 
 | |
| def from_roman(rom):
 | |
| 	if not rom:
 | |
| 		return 0
 | |
| 	for i, n in roman_numerals:
 | |
| 		if rom.upper().startswith(n):
 | |
| 			return i + from_roman(rom[len(n):])
 | |
| 	raise Exception('Invalid roman numeral: "%s"', rom)
 |