|
|
@ -9,9 +9,11 @@ from dataclasses import dataclass
|
|
|
|
from glob import glob
|
|
|
|
from glob import glob
|
|
|
|
from typing import Sequence
|
|
|
|
from typing import Sequence
|
|
|
|
from functools import reduce
|
|
|
|
from functools import reduce
|
|
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
|
|
VOLICU_CELKEM = 8_245_962
|
|
|
|
VOLICU_CELKEM = 8_245_962
|
|
|
|
OKRSKU_CELKEM = 14_857
|
|
|
|
OKRSKU_CELKEM = 14_857
|
|
|
|
|
|
|
|
START = datetime.fromisoformat('2023-01-14T14:00:00')
|
|
|
|
kandidati_jmena = {
|
|
|
|
kandidati_jmena = {
|
|
|
|
1: 'Pavel Fischer',
|
|
|
|
1: 'Pavel Fischer',
|
|
|
|
2: 'Jaroslav Bašta',
|
|
|
|
2: 'Jaroslav Bašta',
|
|
|
@ -66,6 +68,12 @@ def nacti_davku(fn) -> dict[tuple[int, int], VysledekOkrsku]:
|
|
|
|
|
|
|
|
|
|
|
|
return okrsky
|
|
|
|
return okrsky
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
|
|
|
|
class KolacovaData:
|
|
|
|
|
|
|
|
kandidati: dict[str, int]
|
|
|
|
|
|
|
|
timestamp: datetime
|
|
|
|
|
|
|
|
secteno_okrsku: int
|
|
|
|
|
|
|
|
|
|
|
|
def zpracuj_davky(fns: Sequence[str]):
|
|
|
|
def zpracuj_davky(fns: Sequence[str]):
|
|
|
|
# Zpracovávací fáze: načteme dávku, nahradíme předchozí instance pro okrsky
|
|
|
|
# Zpracovávací fáze: načteme dávku, nahradíme předchozí instance pro okrsky
|
|
|
|
# Počítací fáze: sečteme hlasy za všechny okrsky, vyrobíme dump nebo koláč ke každému času
|
|
|
|
# Počítací fáze: sečteme hlasy za všechny okrsky, vyrobíme dump nebo koláč ke každému času
|
|
|
@ -75,6 +83,7 @@ def zpracuj_davky(fns: Sequence[str]):
|
|
|
|
|
|
|
|
|
|
|
|
okrsky: dict[tuple[int, int], VysledekOkrsku] = {}
|
|
|
|
okrsky: dict[tuple[int, int], VysledekOkrsku] = {}
|
|
|
|
celkovy_vysledek: dict[str, int] = {}
|
|
|
|
celkovy_vysledek: dict[str, int] = {}
|
|
|
|
|
|
|
|
data: list[KolacovaData] = []
|
|
|
|
for fn in fns:
|
|
|
|
for fn in fns:
|
|
|
|
print(f'Zpracovávám dávku {fn}')
|
|
|
|
print(f'Zpracovávám dávku {fn}')
|
|
|
|
nove = nacti_davku(fn)
|
|
|
|
nove = nacti_davku(fn)
|
|
|
@ -95,15 +104,35 @@ def zpracuj_davky(fns: Sequence[str]):
|
|
|
|
celkovy_vysledek['NEZAPOČÍTANÉ'] = 0 # del který funguje i v první iteraci :-)
|
|
|
|
celkovy_vysledek['NEZAPOČÍTANÉ'] = 0 # del který funguje i v první iteraci :-)
|
|
|
|
celkovy_vysledek['NEZAPOČÍTANÉ'] = VOLICU_CELKEM - sum(celkovy_vysledek.values())
|
|
|
|
celkovy_vysledek['NEZAPOČÍTANÉ'] = VOLICU_CELKEM - sum(celkovy_vysledek.values())
|
|
|
|
# Vizualizace / export
|
|
|
|
# Vizualizace / export
|
|
|
|
|
|
|
|
data.append(KolacovaData(
|
|
|
|
|
|
|
|
kandidati = dict(celkovy_vysledek),
|
|
|
|
|
|
|
|
timestamp = ts,
|
|
|
|
|
|
|
|
secteno_okrsku = len(okrsky.keys())
|
|
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# FIXME: ne globálním datům!
|
|
|
|
|
|
|
|
data = [KolacovaData(
|
|
|
|
|
|
|
|
kandidati={'NEZAPOČÍTANÉ': VOLICU_CELKEM},
|
|
|
|
|
|
|
|
timestamp=START,
|
|
|
|
|
|
|
|
secteno_okrsku=0,
|
|
|
|
|
|
|
|
)]
|
|
|
|
|
|
|
|
data.extend(zpracuj_davky(sorted(glob('davky/*.xml'))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Reálně ale kašleme na jednotlivé sekundy, takže z každé vezmeme jen poslední výsledek
|
|
|
|
|
|
|
|
po_sekundach = {}
|
|
|
|
|
|
|
|
for x in data:
|
|
|
|
|
|
|
|
po_sekundach[x.timestamp] = x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def visualize_data(data: KolacovaData):
|
|
|
|
# FIXME: Zkopírováno, negenerické, fuj. Má používat nějaký dedikovaný spoolečný kód.
|
|
|
|
# FIXME: Zkopírováno, negenerické, fuj. Má používat nějaký dedikovaný spoolečný kód.
|
|
|
|
plt.clf()
|
|
|
|
plt.clf()
|
|
|
|
# Pro srovnání: zpracování okrsků
|
|
|
|
# Pro srovnání: zpracování okrsků
|
|
|
|
# TODO: WTF: když tohle nakreslím až po kandidátech, tak se
|
|
|
|
# TODO: WTF: když tohle nakreslím až po kandidátech, tak se
|
|
|
|
# kandidáti vyrenderují mimo bbox.
|
|
|
|
# kandidáti vyrenderují mimo bbox.
|
|
|
|
okrsku_secteno = len(okrsky.keys())
|
|
|
|
okrsku_zbyva = OKRSKU_CELKEM - data.secteno_okrsku
|
|
|
|
okrsku_zbyva = OKRSKU_CELKEM - okrsku_secteno
|
|
|
|
|
|
|
|
plt.pie(
|
|
|
|
plt.pie(
|
|
|
|
[okrsku_secteno, okrsku_zbyva],
|
|
|
|
[data.secteno_okrsku, okrsku_zbyva],
|
|
|
|
colors=['#000088', '#cccccc'],
|
|
|
|
colors=['#000088', '#cccccc'],
|
|
|
|
center=(1, -1), radius=0.3,
|
|
|
|
center=(1, -1), radius=0.3,
|
|
|
|
)
|
|
|
|
)
|
|
|
@ -123,10 +152,10 @@ def zpracuj_davky(fns: Sequence[str]):
|
|
|
|
'NEZAPOČÍTANÉ',
|
|
|
|
'NEZAPOČÍTANÉ',
|
|
|
|
)
|
|
|
|
)
|
|
|
|
# FIXME: průběžné výsledky nemají některé kandidáty. Tohle bychom neměli opravovat tady.
|
|
|
|
# FIXME: průběžné výsledky nemají některé kandidáty. Tohle bychom neměli opravovat tady.
|
|
|
|
x = [celkovy_vysledek.get(i, 0) for i in order]
|
|
|
|
x = [data.kandidati.get(i, 0) for i in order]
|
|
|
|
print(ts, x)
|
|
|
|
print(data.timestamp, x)
|
|
|
|
labels = order
|
|
|
|
labels = order
|
|
|
|
label = str(ts)
|
|
|
|
label = str(data.timestamp)
|
|
|
|
colors = {
|
|
|
|
colors = {
|
|
|
|
'Petr Pavel': '#627210',
|
|
|
|
'Petr Pavel': '#627210',
|
|
|
|
'Danuše Nerudová': '#811367',
|
|
|
|
'Danuše Nerudová': '#811367',
|
|
|
@ -144,10 +173,9 @@ def zpracuj_davky(fns: Sequence[str]):
|
|
|
|
plt.text(0, -1.2, label, ha='center')
|
|
|
|
plt.text(0, -1.2, label, ha='center')
|
|
|
|
|
|
|
|
|
|
|
|
# save
|
|
|
|
# save
|
|
|
|
fn = f'progress_png/{ts}.png'
|
|
|
|
fn = f'progress_png/{data.timestamp}.png'
|
|
|
|
plt.savefig(fn)
|
|
|
|
plt.savefig(fn)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Path('./progress_png').mkdir(exist_ok=True)
|
|
|
|
zpracuj_davky(
|
|
|
|
for kolac in po_sekundach.values():
|
|
|
|
sorted(glob('davky/*.xml'))
|
|
|
|
visualize_data(kolac)
|
|
|
|
)
|
|
|
|
|
|
|
|