Files
covid/covid.py

159 lines
4.3 KiB
Python
Raw Permalink Normal View History

2020-03-22 05:29:19 +00:00
#!/usr/bin/python3
import csv
import datetime
import requests
2020-03-22 05:53:36 +00:00
def with_snapshot(func):
def wrapper(self, ts=None):
if not ts:
ts = self.Latest()
return func(self, self.Snapshots[ts])
return wrapper
def per_million(func):
def wrapper(self, *args, **kwargs):
count = func(self, *args, **kwargs)
return round(count * 1000000 / self.Population)
return wrapper
2020-03-22 05:29:19 +00:00
class State:
def __init__(self, population):
self.Population = population
self.Snapshots = {}
def AddSnapshot(self, ts, positive, negative, pending, hospitalized, dead):
self.Snapshots[ts] = Snapshot(positive, negative, pending, hospitalized, dead)
2020-03-22 05:53:36 +00:00
def Latest(self):
return max(self.Snapshots)
@with_snapshot
@per_million
def TestsPerMillion(self, snap):
return snap.Tests()
@with_snapshot
@per_million
def PositivePerMillion(self, snap):
return snap.Positive
@with_snapshot
@per_million
def HospitalizedPerMillion(self, snap):
return snap.Hospitalized
@with_snapshot
@per_million
def DeadPerMillion(self, snap):
return snap.Dead
@with_snapshot
def PositivePerTestBP(self, snap):
return round(snap.Positive * 10000 / snap.Tests()) if snap.Tests() else 0
2020-03-22 05:29:19 +00:00
def __str__(self):
2020-03-22 05:53:36 +00:00
return f'{self.Population:>10}=pop {len(self.Snapshots):>4}=snaps {self.TestsPerMillion():>6}=tpm {self.PositivePerMillion():>6}=ppm {self.HospitalizedPerMillion():>6}=hpm {self.DeadPerMillion():>6}=dpm {self.PositivePerTestBP():>4}=p‱'
2020-03-22 05:29:19 +00:00
class Snapshot:
def __init__(self, positive, negative, pending, hospitalized, dead):
2020-03-22 05:53:36 +00:00
self.Positive = positive or 0
self.Negative = negative or 0
self.Pending = pending or 0
self.Hospitalized = hospitalized or 0
self.Dead = dead or 0
def Tests(self):
return self.Positive + self.Negative
2020-03-22 05:29:19 +00:00
states = {}
2020-03-22 06:06:06 +00:00
latest = datetime.datetime.utcfromtimestamp(0)
2020-03-22 05:29:19 +00:00
def LoadPopulations():
with open('populations.csv', 'r') as fh:
reader = csv.DictReader(fh)
for row in reader:
states[row['State']] = State(int(row['Population']))
def LoadCovidTracking():
2020-03-22 06:06:06 +00:00
global latest, states
2020-03-22 05:29:19 +00:00
resp = requests.get('https://covidtracking.com/api/states/daily')
for row in resp.json():
ts = datetime.datetime.fromisoformat(row['dateChecked'][:-1])
states[row['state']].AddSnapshot(
ts,
row['positive'],
row['negative'],
row['pending'],
row['hospitalized'],
row['death'],
)
2020-03-22 06:06:06 +00:00
latest = max(latest, ts)
def SumTotal():
total = State(0)
positive = 0
negative = 0
pending = 0
hospitalized = 0
dead = 0
for state in states.values():
total.Population += state.Population
snap = state.Snapshots[state.Latest()]
positive += snap.Positive
negative += snap.Negative
pending += snap.Pending
hospitalized += snap.Hospitalized
dead += snap.Dead
total.AddSnapshot(
latest,
positive,
negative,
pending,
hospitalized,
dead,
)
states['ΣΣ'] = total
def PrintStates():
for code, state in sorted(states.items(), key=lambda x: x[1].Population):
print(f'{code} {state}')
2020-03-22 06:15:32 +00:00
def ExtrapolateWorstPPM():
worst = max(states.items(), key=lambda x: x[1].PositivePerMillion())
ppm = worst[1].PositivePerMillion()
print(f'Extrapolating worst {ppm}=ppm (from {worst[0]}) gives {round(states["ΣΣ"].Population * ppm / 1000000)} infected')
def ExtrapolateWorstHPM():
worst = max(states.items(), key=lambda x: x[1].HospitalizedPerMillion())
hpm = worst[1].HospitalizedPerMillion()
print(f'Extrapolating worst {hpm}=hpm (from {worst[0]}) gives {round(states["ΣΣ"].Population * hpm / 1000000)} hospitalized')
def ExtrapolateWorstDPM():
worst = max(states.items(), key=lambda x: x[1].DeadPerMillion())
dpm = worst[1].DeadPerMillion()
print(f'Extrapolating worst {dpm}=dpm (from {worst[0]}) gives {round(states["ΣΣ"].Population * dpm / 1000000)} dead')
2020-03-22 05:29:19 +00:00
LoadPopulations()
LoadCovidTracking()
2020-03-22 06:06:06 +00:00
SumTotal()
PrintStates()
2020-03-22 05:29:19 +00:00
2020-03-22 06:15:32 +00:00
print()
ExtrapolateWorstPPM()
ExtrapolateWorstHPM()
ExtrapolateWorstDPM()
2020-03-22 05:29:19 +00:00
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4