use blood test data

This commit is contained in:
Dima Gerasimov 2019-08-17 09:35:04 +01:00
parent 23e6c91758
commit 3059fd85cb

View file

@ -1,25 +1,55 @@
#!/usr/bin/env python3
from datetime import datetime
from typing import Iterable, NamedTuple, Optional
from itertools import chain
import porg
from kython import listify
from kython.org import parse_org_date
from kython.kerror import Res, echain
from ..paths import LOGS
from ..paths import LOGS, MY
import pandas as pd # type: ignore
blood_tests_log = MY / 'blood.org'
blood_log = LOGS / 'blood.org'
class Entry(NamedTuple):
dt: datetime
ket: Optional[float]
glu: Optional[float]
extra: str
ket: Optional[float]=None
glu: Optional[float]=None
vitd: Optional[float]=None
b12: Optional[float]=None
hdl: Optional[float]=None
ldl: Optional[float]=None
trig: Optional[float]=None
extra: Optional[str]=None
def iter_data() -> Iterable[Entry]:
o = porg.Org.from_file(blood_log)
Result = Res[Entry]
class ParseError(Exception):
pass
def try_float(s: str) -> Optional[float]:
l = s.split()
if len(l) == 0:
return None
x = l[0].strip()
if len(x) == 0:
return None
return float(x)
def iter_gluc_keto_data() -> Iterable[Result]:
o = porg.Org.from_file(str(blood_log))
tbl = o.xpath('//table')
for l in tbl.lines:
kets = l['ket'].strip()
@ -27,8 +57,8 @@ def iter_data() -> Iterable[Entry]:
extra = l['notes']
dt = parse_org_date(l['datetime'])
assert isinstance(dt, datetime)
ket = None if len(kets) == 0 else float(kets)
glu = None if len(glus) == 0 else float(glus)
ket = try_float(kets)
glu = try_float(glus)
yield Entry(
dt=dt,
ket=ket,
@ -36,14 +66,51 @@ def iter_data() -> Iterable[Entry]:
extra=extra,
)
def iter_tests_data() -> Iterable[Result]:
o = porg.Org.from_file(str(blood_tests_log))
tbl = o.xpath('//table')
for d in tbl.lines:
try:
dt = parse_org_date(d['datetime'])
assert isinstance(dt, datetime)
# TODO rest
F = lambda n: try_float(d[n])
yield Entry(
dt=dt,
vitd=F('VD nm/L'),
b12 =F('B12 pm/L'),
hdl =F('HDL mm/L'),
ldl =F('LDL mm/L'),
trig=F('Trig mm/L'),
extra=d['misc'],
)
except Exception as e:
print(e)
yield echain(ParseError(str(d)), e)
def data():
datas = list(iter_data())
return list(sorted(datas, key=lambda d: d.dt))
datas = list(chain(iter_gluc_keto_data(), iter_tests_data()))
return list(sorted(datas, key=lambda d: getattr(d, 'dt', datetime.min)))
@listify(wrapper=pd.DataFrame)
def dataframe():
import pandas as pd
return pd.DataFrame(map(lambda e: e._asdict(), data()))
for d in data():
if isinstance(d, Exception):
yield {'error': str(d)}
else:
yield d._asdict()
def test():
print(dataframe())
assert len(dataframe()) > 10
def main():