Skip to content

Commit

Permalink
Merge pull request #228 from msusicky/develop
Browse files Browse the repository at this point in the history
2.2.4
  • Loading branch information
jan-stanek authored Mar 17, 2021
2 parents 0d8fc79 + 4f737e0 commit a7b28bf
Show file tree
Hide file tree
Showing 18 changed files with 1,898 additions and 302 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
[![deploy-production](https://github.com/msusicky/ockovani-covid/actions/workflows/deploy-production.yml/badge.svg)](https://github.com/msusicky/ockovani-covid/actions/workflows/deploy-production.yml)
[![update-data](https://github.com/msusicky/ockovani-covid/actions/workflows/update-data.yml/badge.svg)](https://github.com/msusicky/ockovani-covid/actions/workflows/update-data.yml)
[![update-web](https://github.com/msusicky/ockovani-covid/actions/workflows/update-web.yml/badge.svg)](https://github.com/msusicky/ockovani-covid/actions/workflows/update-web.yml)
[![post-tweet](https://github.com/msusicky/ockovani-covid/actions/workflows/post-tweet.yml/badge.svg)](https://github.com/msusicky/ockovani-covid/actions/workflows/post-tweet.yml)

# COVID-19 data o očkování
Za systémem stojí Jan Staněk (http://jstanek.cz/), Marek Sušický (marek(at)susicky.net) a přátele, kteří poskytli cenné připomínky.
Expand Down
7 changes: 6 additions & 1 deletion app/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,9 @@ def compute_metrics_command(datum):
def post_tweet_command():
"""Post statistics as a tweet."""
twitter_bot = TwitterBot()
twitter_bot.post_tweet()
result = twitter_bot.post_tweet()

if result:
exit(0)
else:
exit(1)
67 changes: 35 additions & 32 deletions app/etl.py

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions app/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,26 @@
@app.template_filter()
def format_number(number):
"""Converts number to string with space separated thoudands."""
return 'bez dat' if number is None else ('{:,}'.format(number).replace(',', ' '))
return 'bez dat' if number is None else ('{:,}'.format(round(number)).replace(',', ' '))


@app.template_filter()
def format_number_delta(number):
"""Converts number to string with space separated thoudands."""
return 'bez dat' if number is None else (('+' if number > 0 else '') + '{:,}'.format(number).replace(',', ' '))
return 'bez dat' if number is None else (('+' if number > 0 else '') + format_number(number))


@app.template_filter()
def format_decimal(number, digits=1):
"""Converts number to string with space separated thoudands and one digit after decimal point."""
return 'bez dat' if number is None else ('{:,}'.format(round(number, digits)).replace(',', ' ').replace('.', ','))
return 'bez dat' if number is None \
else ('{:,}'.format(round(number, digits)).replace(',', ' ').replace('.', ','))


@app.template_filter()
def format_decimal_delta(number):
def format_decimal_delta(number, digits=1):
"""Converts number to string with space separated thoudands and one digit after decimal point."""
return 'bez dat' if number is None else (('+' if number > 0 else '') + '{:,}'.format(round(number, 1)).replace(',', ' ').replace('.', ','))
return 'bez dat' if number is None else (('+' if number > 0 else '') + format_decimal(number, digits))


@app.template_filter()
Expand Down
30 changes: 21 additions & 9 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class KrajMetriky(db.Model):
rezervace_cekajici = Column(Integer) # pocet rezervaci cekajicich na ockovani (vsechny kalendare)
rezervace_cekajici_zmena_den = Column(Integer) # pocet rezervaci cekajicich na ockovani (vsechny kalendare) - zmena za den
rezervace_cekajici_zmena_tyden = Column(Integer) # pocet rezervaci cekajicich na ockovani (vsechny kalendare) - zmena za tyden
rezervace_kapacita = Column(Integer) # kapacita na aktualni den (vsechny kalendare)
rezervace_kapacita_zmena_den = Column(Integer) # kapacita na aktualni den (vsechny kalendare) - zmena za den
rezervace_kapacita_zmena_tyden = Column(Integer) # kapacita na aktualni den (vsechny kalendare) - zmena za tyden
registrace_celkem = Column(Integer) # pocet vsech registraci
registrace_celkem_zmena_den = Column(Integer) # pocet vsech registraci - zmena za den
registrace_celkem_zmena_tyden = Column(Integer) # pocet vsech registraci - zmena za tyden
Expand Down Expand Up @@ -55,9 +58,6 @@ class KrajMetriky(db.Model):
vakciny_prijate_pocet = Column(Integer) # pocet prijatych vakcin
vakciny_prijate_pocet_zmena_den = Column(Integer) # pocet prijatych vakcin - zmena za den
vakciny_prijate_pocet_zmena_tyden = Column(Integer) # pocet prijatych vakcin - zmena za tyden
vakciny_vydane_pocet = Column(Integer) # pocet vydanych vakcin
vakciny_vydane_pocet_zmena_den = Column(Integer) # pocet vydanych vakcin - zmena za den
vakciny_vydane_pocet_zmena_tyden = Column(Integer) # pocet vydanych vakcin - zmena za tyden
vakciny_ockovane_pocet = Column(Integer) # pocet ockovanych vakcin
vakciny_ockovane_pocet_zmena_den = Column(Integer) # pocet ockovanych vakcin - zmena za den
vakciny_ockovane_pocet_zmena_tyden = Column(Integer) # pocet ockovanych vakcin - zmena za tyden
Expand Down Expand Up @@ -106,6 +106,9 @@ class OkresMetriky(db.Model):
rezervace_cekajici = Column(Integer) # pocet rezervaci cekajicich na ockovani (vsechny kalendare)
rezervace_cekajici_zmena_den = Column(Integer) # pocet rezervaci cekajicich na ockovani (vsechny kalendare) - zmena za den
rezervace_cekajici_zmena_tyden = Column(Integer) # pocet rezervaci cekajicich na ockovani (vsechny kalendare) - zmena za tyden
rezervace_kapacita = Column(Integer) # kapacita na aktualni den (vsechny kalendare)
rezervace_kapacita_zmena_den = Column(Integer) # kapacita na aktualni den (vsechny kalendare) - zmena za den
rezervace_kapacita_zmena_tyden = Column(Integer) # kapacita na aktualni den (vsechny kalendare) - zmena za tyden
registrace_celkem = Column(Integer) # pocet vsech registraci
registrace_celkem_zmena_den = Column(Integer) # pocet vsech registraci - zmena za den
registrace_celkem_zmena_tyden = Column(Integer) # pocet vsech registraci - zmena za tyden
Expand All @@ -127,9 +130,6 @@ class OkresMetriky(db.Model):
vakciny_prijate_pocet = Column(Integer) # pocet prijatych vakcin
vakciny_prijate_pocet_zmena_den = Column(Integer) # pocet prijatych vakcin - zmena za den
vakciny_prijate_pocet_zmena_tyden = Column(Integer) # pocet prijatych vakcin - zmena za tyden
vakciny_vydane_pocet = Column(Integer) # pocet vydanych vakcin
vakciny_vydane_pocet_zmena_den = Column(Integer) # pocet vydanych vakcin - zmena za den
vakciny_vydane_pocet_zmena_tyden = Column(Integer) # pocet vydanych vakcin - zmena za tyden
vakciny_ockovane_pocet = Column(Integer) # pocet ockovanych vakcin
vakciny_ockovane_pocet_zmena_den = Column(Integer) # pocet ockovanych vakcin - zmena za den
vakciny_ockovane_pocet_zmena_tyden = Column(Integer) # pocet ockovanych vakcin - zmena za tyden
Expand Down Expand Up @@ -158,6 +158,18 @@ def __repr__(self):
self.orp_kod, self.pocet, self.vek)


class PopulaceKategorie(db.Model):
__tablename__ = 'populace_kategorie'

vekova_skupina = Column(Unicode, primary_key=True)
min_vek = Column(Integer)
max_vek = Column(Integer)

def __repr__(self):
return "<PopulaceKategorie(vekova_skupina='%s', min_vek=%s, max_vek=%s)>" % (
self.vekova_skupina, self.min_vek, self.max_vek)


class OckovaciMisto(db.Model):
__tablename__ = 'ockovaci_mista'

Expand Down Expand Up @@ -196,6 +208,9 @@ class OckovaciMistoMetriky(db.Model):
rezervace_cekajici = Column(Integer) # pocet rezervaci cekajicich na ockovani (vsechny kalendare)
rezervace_cekajici_zmena_den = Column(Integer) # pocet rezervaci cekajicich na ockovani (vsechny kalendare) - zmena za den
rezervace_cekajici_zmena_tyden = Column(Integer) # pocet rezervaci cekajicich na ockovani (vsechny kalendare) - zmena za tyden
rezervace_kapacita = Column(Integer) # kapacita na aktualni den (vsechny kalendare)
rezervace_kapacita_zmena_den = Column(Integer) # kapacita na aktualni den (vsechny kalendare) - zmena za den
rezervace_kapacita_zmena_tyden = Column(Integer) # kapacita na aktualni den (vsechny kalendare) - zmena za tyden
registrace_celkem = Column(Integer) # pocet vsech registraci
registrace_celkem_zmena_den = Column(Integer) # pocet vsech registraci - zmena za den
registrace_celkem_zmena_tyden = Column(Integer) # pocet vsech registraci - zmena za tyden
Expand Down Expand Up @@ -232,9 +247,6 @@ class OckovaciMistoMetriky(db.Model):
vakciny_prijate_pocet = Column(Integer) # pocet prijatych vakcin
vakciny_prijate_pocet_zmena_den = Column(Integer) # pocet prijatych vakcin - zmena za den
vakciny_prijate_pocet_zmena_tyden = Column(Integer) # pocet prijatych vakcin - zmena za tyden
vakciny_vydane_pocet = Column(Integer) # pocet vydanych vakcin
vakciny_vydane_pocet_zmena_den = Column(Integer) # pocet vydanych vakcin - zmena za den
vakciny_vydane_pocet_zmena_tyden = Column(Integer) # pocet vydanych vakcin - zmena za tyden
vakciny_ockovane_pocet = Column(Integer) # pocet ockovanych vakcin
vakciny_ockovane_pocet_zmena_den = Column(Integer) # pocet ockovanych vakcin - zmena za den
vakciny_ockovane_pocet_zmena_tyden = Column(Integer) # pocet ockovanych vakcin - zmena za tyden
Expand Down
51 changes: 49 additions & 2 deletions app/queries.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datetime import date
from datetime import date, timedelta

import numpy as np
from sqlalchemy import func

from app import db
Expand Down Expand Up @@ -47,7 +48,6 @@ def count_vaccines(filter_column, filter_value):
""".format(filter_column, filter_value),
db.engine
)

mista_ids = ','.join("'" + misto + "'" for misto in mista['ockovaci_misto_id'].tolist())

prijato = pd.read_sql_query(
Expand Down Expand Up @@ -114,3 +114,50 @@ def count_vaccines(filter_column, filter_value):
res = res.groupby(by=['vyrobce'], as_index=False).sum().sort_values(by=['vyrobce'])

return res


def count_registrations(import_id, filter_column, filter_value):
mista = pd.read_sql_query(
"""
select ockovaci_mista.id ockovaci_misto_id from ockovaci_mista join okresy on ockovaci_mista.okres_id=okresy.id
where {}='{}';
""".format(filter_column, filter_value),
db.engine
)
mista_ids = ','.join("'" + misto + "'" for misto in mista['ockovaci_misto_id'].tolist())

df = pd.read_sql_query(
"""
select *
from ockovani_registrace
where import_id = {} and ockovaci_misto_id in({})
""".format(import_id, mista_ids),
db.engine
)

df['datum_rezervace_fix'] = df['datum_rezervace'].where(df['datum_rezervace'] != date(1970, 1, 1))
df['fronta'] = df[['pocet']].where(df['rezervace'] == False).fillna(0).astype('int')
df['registrace_7'] = df[['pocet']].where(df['datum'] >= date.today() - timedelta(7))
df['registrace_7_rez'] = df[['pocet']].where((df['rezervace'] == True) & (df['datum'] >= date.today() - timedelta(7)))
df['registrace_14'] = df[['pocet']].where(df['datum'] >= date.today() - timedelta(14))
df['registrace_14_rez'] = df[['pocet']].where((df['rezervace'] == True) & (df['datum'] >= date.today() - timedelta(14)))
df['registrace_30'] = df[['pocet']].where(df['datum'] >= date.today() - timedelta(30))
df['registrace_30_rez'] = df[['pocet']].where((df['rezervace'] == True) & (df['datum'] >= date.today() - timedelta(30)))
df['cekani'] = (df['datum_rezervace_fix'] - df['datum']).dt.days
df['rezervace_7'] = df[['pocet']].where((df['rezervace'] == True) & (df['datum_rezervace_fix'] >= date.today() - timedelta(7)))
df['rezervace_7_x_cekani'] = df['cekani'] * df['rezervace_7']

df = df.groupby(['vekova_skupina', 'povolani']).sum()

df['uspesnost_7'] = ((df['registrace_7_rez'] / df['registrace_7']) * 100).replace({np.nan: None})
df['uspesnost_14'] = ((df['registrace_14_rez'] / df['registrace_14']) * 100).replace({np.nan: None})
df['uspesnost_30'] = ((df['registrace_30_rez'] / df['registrace_30']) * 100).replace({np.nan: None})
df['registrace_7'] = df['registrace_7'].astype('int')
df['registrace_7_rez'] = df['registrace_7_rez'].astype('int')
df['registrace_14'] = df['registrace_14'].astype('int')
df['registrace_14_rez'] = df['registrace_14_rez'].astype('int')
df['registrace_30'] = df['registrace_30'].astype('int')
df['registrace_30_rez'] = df['registrace_30_rez'].astype('int')
df['prumer_cekani'] = ((df['rezervace_7_x_cekani'] / df['rezervace_7']) / 7).replace({np.nan: None})

return df.reset_index().sort_values(by=['vekova_skupina', 'povolani'])
4 changes: 4 additions & 0 deletions app/static/styles/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@
.w-20 {
width: 20% !important;
}

.w-40 {
width: 40% !important;
}
17 changes: 17 additions & 0 deletions app/templates/kraj.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@ <h3>Kraj: {{ kraj.nazev }} </h3>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#stats">Statistiky</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#registration">Stav registrací</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#vaccines">Stav vakcín</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#vaccination">Stav očkování</a>
</li>
</ul>
</div>

Expand All @@ -40,21 +46,32 @@ <h3>Kraj: {{ kraj.nazev }} </h3>
<div class="row mb-n3">
{{ macros.metrika('Počet obyvatel (18+)', metriky.pocet_obyvatel_dospeli) }}
{{ macros.metrika('Očkovaní (obě dávky)', metriky.ockovani_pocet_2, delta_day=metriky.ockovani_pocet_2_zmena_den, delta_week=metriky.ockovani_pocet_2_zmena_tyden, color='std') }}
{{ macros.metrika('Očkovaní (obě dávky)', metriky.ockovani_pocet_2, delta_day=metriky.ockovani_pocet_2_zmena_den, delta_week=metriky.ockovani_pocet_2_zmena_tyden, color='std', decimal=True, unit='%', multiply=100, divide=metriky.pocet_obyvatel_dospeli) }}
{{ macros.metrika('Očkováno dávek', metriky.ockovani_pocet, delta_day=metriky.ockovani_pocet_zmena_den, delta_week=metriky.ockovani_pocet_zmena_tyden, color='std') }}
{{ macros.metrika('Přijaté vakcíny', metriky.vakciny_prijate_pocet, delta_day=metriky.vakciny_prijate_pocet_zmena_den, delta_week=metriky.vakciny_prijate_pocet_zmena_tyden, color='std') }}
{{ macros.metrika('Přibližně skladem', metriky.vakciny_skladem_pocet, delta_day=metriky.vakciny_skladem_pocet_zmena_den, delta_week=metriky.vakciny_skladem_pocet_zmena_tyden, warning='Odhadovaný počet dávek skladem.<br>Údaj je počítán z dat o distribuci vakcín, očkovaných lidech a znehodnocených vakcínách. Informace o počtu očkovaných přichází se zpožděním, proto může být reálný počet výrazně nižší. Tento údaj by měl být přesnější než počet uvedený v tabulce "Stav vakcín", který vychází z jiných dat.') }}
{{ macros.metrika('Čekající ve frontě', metriky.registrace_fronta, delta_day=metriky.registrace_fronta_zmena_den, delta_week=metriky.registrace_fronta_zmena_tyden, color='rev', info='Počet registrovaných čekajících na rezervaci konkrétního termínu (přibližně odpovídá čekajícím na SMS s PIN2).') }}
{{ macros.metrika('Čekající s rezervací', metriky.rezervace_cekajici, delta_day=metriky.rezervace_cekajici_zmena_den, delta_week=metriky.rezervace_cekajici_zmena_tyden, info='Počet registrovaných s rezervovaným konkrétním termínem na očkování.') }}
{{ macros.metrika('Dnešní kapacita', metriky.rezervace_kapacita, delta_day=metriky.rezervace_kapacita_zmena_den, delta_week=metriky.rezervace_kapacita_zmena_tyden, color='std', info='Dnešní kapacita pro očkování první dávkou. Získáno z maximální kapacity uvedené v rezervačním systému.') }}
{{ macros.metrika('Čekání na rezervaci', metriky.registrace_prumer_cekani, delta_day=metriky.registrace_prumer_cekani_zmena_den, delta_week=metriky.registrace_prumer_cekani_zmena_tyden, decimal=True, unit='týdne', divide=7, color='rev', info='Průměrná doba mezi registrací a rezervací konkrétního termínu za posledních 7 dní (přibližně odpovídá čekání na SMS s PIN2).') }}
{{ macros.metrika('7denní úspěšnost', metriky.registrace_tydenni_uspesnost, delta_day=metriky.registrace_tydenni_uspesnost_zmena_den, delta_week=metriky.registrace_tydenni_uspesnost_zmena_tyden, decimal=True, unit='%', multiply=100, color='std', info='Poměr počtu registrovaných za posledních 7 dní s vybraným termínem ku počtu všech registrovaných za posledních 7 dní.') }}
{{ macros.metrika('14denní úspěšnost', metriky.registrace_14denni_uspesnost, delta_day=metriky.registrace_14denni_uspesnost_zmena_den, delta_week=metriky.registrace_14denni_uspesnost_zmena_tyden, decimal=True, unit='%', multiply=100, color='std', info='Poměr počtu registrovaných za posledních 14 dní s vybraným termínem ku počtu všech registrovaných za posledních 14 dní.') }}
{{ macros.metrika('30denní úspěšnost', metriky.registrace_30denni_uspesnost, delta_day=metriky.registrace_30denni_uspesnost_zmena_den, delta_week=metriky.registrace_30denni_uspesnost_zmena_tyden, decimal=True, unit='%', multiply=100, color='std', info='Poměr počtu registrovaných za posledních 30 dní s vybraným termínem ku počtu všech registrovaných za posledních 30 dní.') }}
</div>
</div>
<div class="tab-pane" id="registration">
{{ macros.stav_registraci(registrations) }}
</div>
<div class="tab-pane" id="vaccines">
<div class="mb-n3">
{{ macros.stav_vakcin(vaccines) }}
</div>
</div>
<div class="tab-pane" id="vaccination">
<div class="mb-n3">
{{ macros.stav_ockovani(vac_age) }}
</div>
</div>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit a7b28bf

Please sign in to comment.