118 lines
2.5 KiB
Python
Executable file
118 lines
2.5 KiB
Python
Executable file
#!/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 mycfg import paths
|
|
|
|
import pandas as pd # type: ignore
|
|
|
|
|
|
class Entry(NamedTuple):
|
|
dt: datetime
|
|
|
|
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
|
|
|
|
|
|
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(paths.blood.blood_log))
|
|
tbl = o.xpath('//table')
|
|
for l in tbl.lines:
|
|
kets = l['ket'].strip()
|
|
glus = l['glu'].strip()
|
|
extra = l['notes']
|
|
dt = parse_org_date(l['datetime'])
|
|
assert isinstance(dt, datetime)
|
|
ket = try_float(kets)
|
|
glu = try_float(glus)
|
|
yield Entry(
|
|
dt=dt,
|
|
ket=ket,
|
|
glu=glu,
|
|
extra=extra,
|
|
)
|
|
|
|
|
|
def iter_tests_data() -> Iterable[Result]:
|
|
o = porg.Org.from_file(str(paths.blood.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(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():
|
|
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():
|
|
print(data())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|