HPI/my/body/weight.py
2024-08-28 04:06:32 +01:00

99 lines
2.2 KiB
Python

'''
Weight data (manually logged)
'''
from dataclasses import dataclass
from datetime import datetime
from typing import Any, Iterator
from my.core import make_logger
from my.core.error import Res, extract_error_datetime, set_error_datetime
from my import orgmode
config = Any
def make_config() -> config:
from my.config import weight as user_config # type: ignore[attr-defined]
return user_config()
log = make_logger(__name__)
@dataclass
class Entry:
dt: datetime
value: float
# TODO comment??
Result = Res[Entry]
def from_orgmode() -> Iterator[Result]:
cfg = make_config()
orgs = orgmode.query()
for o in orgmode.query().all():
if 'weight' not in o.tags:
continue
try:
# TODO can it throw? not sure
created = o.created
assert created is not None
except Exception as e:
log.exception(e)
yield e
continue
try:
w = float(o.heading)
except Exception as e:
set_error_datetime(e, dt=created)
log.exception(e)
yield e
continue
# FIXME use timezone provider
created = cfg.default_timezone.localize(created)
assert created is not None # ??? somehow mypy wasn't happy?
yield Entry(
dt=created,
value=w,
# TODO add org note content as comment?
)
def make_dataframe(data: Iterator[Result]):
import pandas as pd
def it():
for e in data:
if isinstance(e, Exception):
dt = extract_error_datetime(e)
yield {
'dt': dt,
'error': str(e),
}
else:
yield {
'dt': e.dt,
'weight': e.value,
}
df = pd.DataFrame(it())
df = df.set_index('dt')
# TODO not sure about UTC??
df.index = pd.to_datetime(df.index, utc=True)
return df
def dataframe():
entries = from_orgmode()
return make_dataframe(entries)
# TODO move to a submodule? e.g. my.body.weight.orgmode?
# so there could be more sources
# not sure about my.body thing though