proper pandas frame

This commit is contained in:
Dima Gerasimov 2019-04-11 13:31:43 +01:00
parent b471a337aa
commit 9c94431791

View file

@ -3,6 +3,9 @@ from typing import Dict, Any, List
import json import json
from datetime import datetime, date, time from datetime import datetime, date, time
from pathlib import Path from pathlib import Path
import logging
from kython.klogging import setup_logzero
BDIR = Path('/L/backups/jawbone') BDIR = Path('/L/backups/jawbone')
PHASES_FILE = BDIR / 'phases.json' PHASES_FILE = BDIR / 'phases.json'
@ -10,14 +13,16 @@ SLEEPS_FILE = BDIR / 'sleeps.json'
GRAPHS_DIR = BDIR / 'graphs' GRAPHS_DIR = BDIR / 'graphs'
def get_logger():
return logging.getLogger('jawbone-provider')
fromtimestamp = datetime.fromtimestamp # TODO careful fromtimestamp = datetime.fromtimestamp # TODO careful
XID = str # TODO how to shared with backup thing? XID = str # TODO how to shared with backup thing?
Phases = Dict[XID, Any] Phases = Dict[XID, Any]
phases: Phases = json.loads(PHASES_FILE.read_text()) phases: Phases = json.loads(PHASES_FILE.read_text())
# TODO namedtuple, cproperty? # TODO namedtuple, cproperty?
@ -42,9 +47,12 @@ class SleepEntry:
def xid(self) -> XID: def xid(self) -> XID:
return self.js['xid'] return self.js['xid']
@property
def _details(self): def _details(self):
return self.js['details'] return self.js['details']
# TODO figure out timezones..
# not sure how.. I guess by the american ones
@property @property
def created(self) -> datetime: def created(self) -> datetime:
return fromtimestamp(self.js['time_created']) return fromtimestamp(self.js['time_created'])
@ -55,14 +63,28 @@ class SleepEntry:
@property @property
def asleep(self) -> datetime: def asleep(self) -> datetime:
return fromtimestamp(self._details()['asleep_time']) return fromtimestamp(self._details['asleep_time'])
@property
def sleep_start(self) -> datetime:
return self.asleep # TODO careful, maybe use same logic as emfit
@property
def bed_time(self) -> int:
return int((self.sleep_end - self.sleep_start).total_seconds()) // 60
@property
def sleep_end(self) -> datetime:
return fromtimestamp(self._details['awake_time'])
@property @property
def graph(self) -> Path: def graph(self) -> Path:
return GRAPHS_DIR / (self.xid + ".png") return GRAPHS_DIR / (self.xid + ".png")
# TODO might be useful to cache these??
@property @property
def phases(self) -> List[datetime]: def phases(self) -> List[datetime]:
# TODO make sure they are consistent with emfit?
return [fromtimestamp(i['time']) for i in phases[self.xid]] return [fromtimestamp(i['time']) for i in phases[self.xid]]
def __str__(self) -> str: def __str__(self) -> str:
@ -161,11 +183,21 @@ def plot_one(sleep: SleepEntry, fig: Figure, axes: Axes, xlims=None, showtext=Tr
axes.text(xlims[1] - timedelta(hours=1.5), 20, str(sleep),) axes.text(xlims[1] - timedelta(hours=1.5), 20, str(sleep),)
# plt.text(sleep.asleep(), 0, hhmm(sleep.asleep())) # plt.text(sleep.asleep(), 0, hhmm(sleep.asleep()))
from kython import make_dict from kython import make_dict, group_by_key
def sleeps_by_date() -> Dict[date, SleepEntry]: def sleeps_by_date() -> Dict[date, SleepEntry]:
logger = get_logger()
sleeps = load_sleeps() sleeps = load_sleeps()
sleeps = [s for s in sleeps if s.graph.exists()] # TODO careful.. sleeps = [s for s in sleeps if s.graph.exists()] # TODO careful..
return make_dict(sleeps, key=SleepEntry.date_) res = {}
for dd, group in group_by_key(sleeps, key=lambda s: s.date_).items():
if len(group) == 1:
res[dd] = group[0]
else:
# TODO short ones I can ignore I guess. but won't bother now
logger.error('multiple sleeps on %s: %s', dd, group)
return res
# sleeps_count = 35 # len(sleeps) # apparently MPL fails at 298 with outofmemory or something # sleeps_count = 35 # len(sleeps) # apparently MPL fails at 298 with outofmemory or something
# start = 40 # start = 40
@ -225,3 +257,26 @@ def plot():
# plt.savefig('res.png', asp) # plt.savefig('res.png', asp)
plt.show() plt.show()
import pandas as pd # type: ignore
def get_dataframe():
sleeps = sleeps_by_date()
items = []
for dd, s in sleeps.items():
items.append({
'date' : dd, # TODO not sure... # TODO would also be great to sync column names...
'sleep_start': s.sleep_start,
'sleep_end' : s.sleep_end,
'bed_time' : s.bed_time,
})
# TODO tz is in sleeps json
res = pd.DataFrame(items)
return res
def main():
setup_logzero(get_logger())
print(get_dataframe())
if __name__ == '__main__':
main()