body.exercise: add cardio summary, move cross trainer to a separate file
This commit is contained in:
parent
eb14d5988d
commit
f02c572cc0
2 changed files with 58 additions and 8 deletions
50
my/body/exercise/cardio.py
Normal file
50
my/body/exercise/cardio.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
'''
|
||||||
|
Cardio data, filtered from Endomondo and inferred from other data sources
|
||||||
|
'''
|
||||||
|
from ...core.pandas import check_dataframe as cdf
|
||||||
|
|
||||||
|
import pandas as pd # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
CARDIO = {
|
||||||
|
'Running',
|
||||||
|
'Running, treadmill',
|
||||||
|
'Cross training',
|
||||||
|
'Walking',
|
||||||
|
'Skating',
|
||||||
|
'Spinning',
|
||||||
|
'Skiing',
|
||||||
|
'Table tennis',
|
||||||
|
'Rope jumping',
|
||||||
|
}
|
||||||
|
# todo if it has HR data, take it into the account??
|
||||||
|
NOT_CARDIO = {
|
||||||
|
'Other',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@cdf
|
||||||
|
def endomondo_cardio() -> pd.DataFrame:
|
||||||
|
assert len(CARDIO.intersection(NOT_CARDIO)) == 0, (CARDIO, NOT_CARDIO)
|
||||||
|
|
||||||
|
from ..endomondo import dataframe as EDF
|
||||||
|
df = EDF()
|
||||||
|
|
||||||
|
# not sure...
|
||||||
|
# df = df[df['heart_rate_avg'].notna()]
|
||||||
|
|
||||||
|
is_cardio = df['sport'].isin(CARDIO)
|
||||||
|
not_cardio = df['sport'].isin(NOT_CARDIO)
|
||||||
|
neither = ~is_cardio & ~not_cardio
|
||||||
|
# if neither -- count, but warn? or show error?
|
||||||
|
|
||||||
|
# todo error about the rest??
|
||||||
|
# todo append errors?
|
||||||
|
df.loc[neither, 'error'] = 'Unexpected exercise type, please mark as cardio or non-cardio'
|
||||||
|
df = df[is_cardio | neither]
|
||||||
|
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
def dataframe():
|
||||||
|
return endomondo_cardio()
|
|
@ -1,5 +1,5 @@
|
||||||
'''
|
'''
|
||||||
My exercise data, arbitrated between differen sources (mainly, Endomondo and various manual plaintext notes)
|
My cross trainer exercise data, arbitrated between differen sources (mainly, Endomondo and various manual plaintext notes)
|
||||||
|
|
||||||
This is probably too specific to my needs, so later I will move it away to a personal 'layer'.
|
This is probably too specific to my needs, so later I will move it away to a personal 'layer'.
|
||||||
For now it's worth keeping it here as an example and perhaps utility functions might be useful for other HPI modules.
|
For now it's worth keeping it here as an example and perhaps utility functions might be useful for other HPI modules.
|
||||||
|
@ -8,7 +8,7 @@ For now it's worth keeping it here as an example and perhaps utility functions m
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from ..core.pandas import check_dataframe as cdf
|
from ...core.pandas import check_dataframe as cdf
|
||||||
|
|
||||||
from my.config import exercise as config
|
from my.config import exercise as config
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ def cross_trainer_data():
|
||||||
# todo eh. not sure if there is a way of getting around writing code...
|
# todo eh. not sure if there is a way of getting around writing code...
|
||||||
# I guess would be nice to have a means of specifying type in the column? maybe multirow column names??
|
# I guess would be nice to have a means of specifying type in the column? maybe multirow column names??
|
||||||
# need to look up org-mode standard..
|
# need to look up org-mode standard..
|
||||||
from ..core.orgmode import parse_org_datetime
|
from ...core.orgmode import parse_org_datetime
|
||||||
mappers = {
|
mappers = {
|
||||||
'duration': lambda s: parse_mm_ss(s),
|
'duration': lambda s: parse_mm_ss(s),
|
||||||
'date' : lambda s: tzify(parse_org_datetime(s)),
|
'date' : lambda s: tzify(parse_org_datetime(s)),
|
||||||
|
@ -83,13 +83,13 @@ _DELTA = timedelta(hours=10)
|
||||||
|
|
||||||
# todo check error handling by introducing typos (e.g. especially dates) in org-mode
|
# todo check error handling by introducing typos (e.g. especially dates) in org-mode
|
||||||
@cdf
|
@cdf
|
||||||
def cross_trainer_dataframe():
|
def dataframe():
|
||||||
'''
|
'''
|
||||||
Attaches manually logged data (which Endomondo can't capture) and attaches it to Endomondo
|
Attaches manually logged data (which Endomondo can't capture) and attaches it to Endomondo
|
||||||
'''
|
'''
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
from ..endomondo import dataframe as EDF
|
from ...endomondo import dataframe as EDF
|
||||||
edf = EDF()
|
edf = EDF()
|
||||||
edf = edf[edf['sport'].str.contains('Cross training')]
|
edf = edf[edf['sport'].str.contains('Cross training')]
|
||||||
|
|
||||||
|
@ -160,12 +160,12 @@ def cross_trainer_dataframe():
|
||||||
|
|
||||||
|
|
||||||
def stats():
|
def stats():
|
||||||
from ..core import stat
|
from ...core import stat
|
||||||
return stat(cross_trainer_data())
|
return stat(cross_trainer_data)
|
||||||
|
|
||||||
|
|
||||||
def compare_manual():
|
def compare_manual():
|
||||||
df = cross_trainer_dataframe()
|
df = dataframe()
|
||||||
df = df.set_index('start_time')
|
df = df.set_index('start_time')
|
||||||
|
|
||||||
df = df[[
|
df = df[[
|
Loading…
Add table
Reference in a new issue