Compare commits

..

2 Commits

@ -57,18 +57,18 @@ def get_results() -> Vysledek:
for kandidat in root.findall(rf'./{NS}CR/{NS}KANDIDAT'): for kandidat in root.findall(rf'./{NS}CR/{NS}KANDIDAT'):
ka = kandidat.attrib ka = kandidat.attrib
jmeno = f'{ka[r"JMENO"]} {ka[r"PRIJMENI"]}' jmeno = f'{ka[r"JMENO"]} {ka[r"PRIJMENI"]}'
hlasy = int(ka.get(r'HLASY_1KOLO', 0)) hlasy = int(ka.get(r'HLASY_2KOLO', 0))
kandidati[jmeno] = hlasy kandidati[jmeno] = hlasy
for ucast in root.findall(rf'./{NS}CR/{NS}UCAST'): for ucast in root.findall(rf'./{NS}CR/{NS}UCAST'):
if ucast.attrib[r'KOLO'] == '1': if ucast.attrib[r'KOLO'] == '2':
fucast = ucast.attrib fucast = ucast.attrib
return Vysledek(kandidati=kandidati, timestamp=timestamp, ucast=fucast) return Vysledek(kandidati=kandidati, timestamp=timestamp, ucast=fucast)
def fill_data(vysl) -> tuple[datetime, dict[str, int]]: def fill_data(vysl) -> tuple[datetime, dict[str, int]]:
"""Dopočítá ve výsledku zbytek dat.""" """Dopočítá ve výsledku zbytek dat."""
VOLICU_CELKEM = 8_245_962 VOLICU_CELKEM = 8_242_566
vysl.kandidati[r'NEPLATNÉ'] = int(vysl.ucast[r'ODEVZDANE_OBALKY']) - int(vysl.ucast[r'PLATNE_HLASY']) vysl.kandidati[r'NEPLATNÉ'] = int(vysl.ucast[r'ODEVZDANE_OBALKY']) - int(vysl.ucast[r'PLATNE_HLASY'])
vysl.kandidati[r'NEZAPOČÍTANÉ'] = max(0, VOLICU_CELKEM - int(vysl.ucast[r'ZAPSANI_VOLICI'])) vysl.kandidati[r'NEZAPOČÍTANÉ'] = max(0, VOLICU_CELKEM - int(vysl.ucast[r'ZAPSANI_VOLICI']))
vysl.kandidati[r'NEVOLILI'] = int(vysl.ucast[r'ZAPSANI_VOLICI']) - int(vysl.ucast[r'ODEVZDANE_OBALKY']) vysl.kandidati[r'NEVOLILI'] = int(vysl.ucast[r'ZAPSANI_VOLICI']) - int(vysl.ucast[r'ODEVZDANE_OBALKY'])
@ -79,19 +79,48 @@ def plot(ts, kand):
with VisuInter(): with VisuInter():
order = ( order = (
'Petr Pavel', 'Petr Pavel',
'Danuše Nerudová', #'Danuše Nerudová',
'Marek Hilšer', #'Marek Hilšer',
'Pavel Fischer', #'Pavel Fischer',
'Karel Diviš', #'Karel Diviš',
'Tomáš Zima', #'Tomáš Zima',
'Jaroslav Bašta', #'Jaroslav Bašta',
# 'NEPLATNÉ',
# 'NEVOLILI',
'Andrej Babiš', 'Andrej Babiš',
'NEZAPOČÍTANÉ',
)
x = [kand[i] for i in order]
labels = [f'{k}\n{kand[k]}' for k in order]
colors = {
'Petr Pavel': '#627210',
'Danuše Nerudová': '#811367',
'Andrej Babiš': '#262161',
'Jaroslav Bašta': '#B51119',
'Marek Hilšer': '#CA834E',
'Pavel Fischer': '#244C76',
'Karel Diviš': '#3B6E5D',
'Tomáš Zima': '#E5DE1A',
'NEPLATNÉ': '#000000',
'NEVOLILI': '#666666',
'NEZAPOČÍTANÉ': '#CCCCCC',
}
plt.pie(x, colors=[colors[i] for i in order], autopct='%1.3f %%', center=(-1.1, 0))
order = (
'Petr Pavel',
#'Danuše Nerudová',
#'Marek Hilšer',
#'Pavel Fischer',
#'Karel Diviš',
#'Tomáš Zima',
#'Jaroslav Bašta',
'NEPLATNÉ', 'NEPLATNÉ',
'NEVOLILI', 'NEVOLILI',
'Andrej Babiš',
'NEZAPOČÍTANÉ', 'NEZAPOČÍTANÉ',
) )
x = [kand[i] for i in order] x = [kand[i] for i in order]
labels = order labels = [f'{k}\n{kand[k]}' for k in order]
label = f'Data z {ts}' label = f'Data z {ts}'
colors = { colors = {
'Petr Pavel': '#627210', 'Petr Pavel': '#627210',
@ -106,7 +135,7 @@ def plot(ts, kand):
'NEVOLILI': '#666666', 'NEVOLILI': '#666666',
'NEZAPOČÍTANÉ': '#CCCCCC', 'NEZAPOČÍTANÉ': '#CCCCCC',
} }
plt.pie(x, labels=labels, colors=[colors[i] for i in order], autopct='%1.3f %%') plt.pie(x, colors=[colors[i] for i in order], autopct='%1.3f %%', center=(1.1, 0))
plt.text(0, -1.2, label, ha='center') plt.text(0, -1.2, label, ha='center')
def visu_once(): def visu_once():

@ -0,0 +1,99 @@
#!/usr/bin/env python3
import requests
from matplotlib import pyplot as plt
import xml.etree.ElementTree as ET
from dataclasses import dataclass
from datetime import datetime
from io import StringIO
# In order of what we know:
class VisuWindow:
def __enter__(self):
plt.close()
plt.clf()
def __exit__(self, _et, _ev, _tb):
plt.show(block=False)
# Alternative: plot to file
class VisuFile:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
plt.clf()
def __exit__(self, _et, _ev, _tb):
plt.savefig(self.filename, format='pdf')
class VisuInter:
def __init__(self):
plt.ion()
def __enter__(self):
plt.clf()
def __exit__(self, _et, _ev, _tb):
plt.show(block=False)
def get_xml():
URL=r'https://www.volby.cz/appdata/kz2024/odata/vysledky.xml'
response = requests.get(URL)
return StringIO(response.content.decode())
@dataclass
class Vysledek:
kandidati: dict[str, int]
timestamp: datetime
ucast: dict
def get_results() -> Vysledek:
NS = r'{http://www.w3.org/namespace/}' # fuck you xml
xml = get_xml()
root = ET.parse(xml).getroot()
kandidati = {}
timestamp = datetime.fromisoformat(root.attrib[r'DATUM_CAS_GENEROVANI'])
for kandidat in root.findall(rf'./{NS}KRZAST[@CIS_KRZAST="1"]/{NS}STRANA'):
ka = kandidat.attrib
jmeno = f'{ka[r"NAZ_STR"]}'
hlasy = kandidat.findall(rf'./{NS}HODNOTY_STRANA')[0].attrib[r'HLASY']
kandidati[jmeno] = hlasy
for ucast in root.findall(rf'./{NS}KRZAST[@CIS_KRZAST="1"]/{NS}UCAST'):
fucast = ucast.attrib
return Vysledek(kandidati=kandidati, timestamp=timestamp, ucast=fucast)
def fill_data(vysl) -> tuple[datetime, dict[str, int]]:
"""Dopočítá ve výsledku zbytek dat."""
print(vysl)
VOLICU_CELKEM = 1_044_056
vysl.kandidati[r'NEPLATNÉ'] = int(vysl.ucast[r'ODEVZDANE_OBALKY']) - int(vysl.ucast[r'PLATNE_HLASY'])
vysl.kandidati[r'NEZAPOČÍTANÉ'] = max(0, VOLICU_CELKEM - int(vysl.ucast[r'ZAPSANI_VOLICI']))
vysl.kandidati[r'NEVOLILI'] = int(vysl.ucast[r'ZAPSANI_VOLICI']) - int(vysl.ucast[r'ODEVZDANE_OBALKY'])
# Na ztracené obálky (rozdíl vydaných obálek a odevzdaných) kašleme, to by mělo být velmi zanedbatelné číslo
return vysl.timestamp, vysl.kandidati
def plot(ts, kand):
with VisuInter():
labels, values = list(zip(*kand.items()))
plt.pie(values, autopct='%1.3f %%', labels=labels)
plt.text(0, -1.2, f'Data z {ts}', ha='center')
def visu_once():
while True:
try:
v = get_results()
break
except OSError:
print('fuu')
plt.pause(1)
continue
ts, k = fill_data(v)
plot(ts, k)
def loop(refresh=30):
while True:
visu_once()
plt.pause(refresh)
loop()

@ -109,6 +109,8 @@ def zpracuj_davky(fns: Sequence[str]):
timestamp = ts, timestamp = ts,
secteno_okrsku = len(okrsky.keys()) secteno_okrsku = len(okrsky.keys())
)) ))
print(okrsky[(538132,7)])
exit()
return data return data
# FIXME: ne globálním datům! # FIXME: ne globálním datům!
@ -205,3 +207,6 @@ def make_anim():
anim.write_videofile('progress.mkv', codec='hevc', fps=24) anim.write_videofile('progress.mkv', codec='hevc', fps=24)
make_anim() make_anim()
#for kd in po_sekundach.values():
# mplfig_to_npimage(visualize_data(kd))

Loading…
Cancel
Save