diff --git a/my/body/exercise/cardio.py b/my/body/exercise/cardio.py new file mode 100644 index 0000000..2c6a7e5 --- /dev/null +++ b/my/body/exercise/cardio.py @@ -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() diff --git a/my/body/exercise.py b/my/body/exercise/cross_trainer.py similarity index 93% rename from my/body/exercise.py rename to my/body/exercise/cross_trainer.py index 797fadf..3457412 100644 --- a/my/body/exercise.py +++ b/my/body/exercise/cross_trainer.py @@ -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'. 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 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 @@ -46,7 +46,7 @@ def cross_trainer_data(): # 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?? # need to look up org-mode standard.. - from ..core.orgmode import parse_org_datetime + from ...core.orgmode import parse_org_datetime mappers = { 'duration': lambda s: parse_mm_ss(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 @cdf -def cross_trainer_dataframe(): +def dataframe(): ''' Attaches manually logged data (which Endomondo can't capture) and attaches it to Endomondo ''' import pandas as pd - from ..endomondo import dataframe as EDF + from ...endomondo import dataframe as EDF edf = EDF() edf = edf[edf['sport'].str.contains('Cross training')] @@ -160,12 +160,12 @@ def cross_trainer_dataframe(): def stats(): - from ..core import stat - return stat(cross_trainer_data()) + from ...core import stat + return stat(cross_trainer_data) def compare_manual(): - df = cross_trainer_dataframe() + df = dataframe() df = df.set_index('start_time') df = df[[