Skip to content

Commit

Permalink
Merge pull request #3 from voynow/2-mid-week-update
Browse files Browse the repository at this point in the history
2 mid week update
  • Loading branch information
voynow authored Aug 12, 2024
2 parents 4511dc2 + 0c22768 commit 0e0cc3e
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 53 deletions.
3 changes: 1 addition & 2 deletions src/activities.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,14 @@ def preprocess_activities_df(df: pl.DataFrame) -> pl.DataFrame:
)


def get_activities_df(strava_client: Client) -> pl.DataFrame:
def get_activities_df(strava_client: Client, num_weeks: int = 8) -> pl.DataFrame:
"""
Fetches and returns activities data for a given athlete ID as a DataFrame,
cleansed and processed
:param athlete_id: The Strava athlete ID
:return: A cleaned and processed DataFrame of the athlete's activities
"""
num_weeks = 8
timedela_x_weeks = datetime.now() - timedelta(weeks=num_weeks)
activities = strava_client.get_activities(
after=timedela_x_weeks, before=datetime.now()
Expand Down
15 changes: 10 additions & 5 deletions src/lambda_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,26 @@


def lambda_handler(event, context):
client_preferences = "A) Training for a marathon B) This will be my second marathon C) Prefer workouts on Wednesdays and long runs on Saturdays"

# activities setup
athlete_id = os.environ["JAMIES_ATHLETE_ID"]
strava_client = get_strava_client(athlete_id)

# process activities data
activities_df = get_activities_df(strava_client)

# gen training week pipeline
day_of_week_summaries = get_day_of_week_summaries(activities_df)
weekly_summaries = get_weekly_summaries(activities_df)
training_week = generate_training_week(
client_preferences=client_preferences,
weekly_summaries=weekly_summaries,
day_of_week_summaries=day_of_week_summaries,
)

# Generate the training week
training_week = generate_training_week(weekly_summaries, day_of_week_summaries)
# save data to db and trigger email
upsert_training_week_with_coaching(
athlete_id=athlete_id, training_week_with_coaching=training_week
)

send_email(
subject="Training Schedule Just Dropped 🏃",
html_content=training_week_to_html(training_week),
Expand Down
2 changes: 1 addition & 1 deletion src/types/training_week.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class TrainingSession(BaseModel):
notes: str = Field(description="notes for the session e.g. pace, terrain, etc.")

def __str__(self):
return f"{self.day}: {self.session_type}"
return f"session_type={self.session_type}, distance={self.distance}, notes={self.notes}"

def __repr__(self):
return self.__str__()
Expand Down
19 changes: 0 additions & 19 deletions src/types/training_week_skeleton.py

This file was deleted.

94 changes: 68 additions & 26 deletions test.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"athlete_id='98390356' token still valid until 2024-08-11 17:48:40+00:00\n"
"athlete_id='98390356' token still valid until 2024-08-12 00:18:57+00:00\n"
]
}
],
Expand Down Expand Up @@ -88,34 +88,76 @@
"# )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Mid-Week Update"
]
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"mon: speed workout, 6.0 miles, Intervals. 1 mile warm-up, 4x800m at a pace of 7m 30s with 400m recovery, 1 mile cool-down.\n",
"tues: easy run, 5.0 miles, Pace of around 9 minutes 30 seconds. Flat terrain.\n",
"wed: speed workout, 7.0 miles, Tempo run. 1 mile warm-up, 5 miles at 8m 15s pace, 1 mile cool-down.\n",
"thurs: rest day, 0.0 miles, Complete rest to recover from mid-week workout.\n",
"fri: moderate run, 6.0 miles, Pace of around 9 minutes 15 seconds.\n",
"sat: long run, 15.0 miles, Keep a steady pace around 9m 45s. Mimic race conditions, include nutrition strategies.\n",
"sun: easy run, 3.0 miles, Recovery jog. Keep a slow, conversational pace.\n",
"\n",
"typical_week_training_review: Based on your recent training data, Wednesdays and Saturdays align well with your preferences for workouts and long runs, respectively. You typically accumulate a higher number of runs on Wednesdays, averaging 4.76 miles at a pace of 9 minutes and 20 seconds, which indicates a solid mid-week workout. Saturdays are marked by your long runs, averaging 10.17 miles at a pace of about 9 minutes and 59 seconds, aligning perfectly with your schedule for endurance building. You tend to rest or have less intense runs on Thursdays, as evidenced by the single run of 1.66 miles with a slower pace of 10 minutes and 58 seconds. Incorporating additional speed work on either Monday, given your moderate mileage and pace (9 minutes and 34 seconds), or Friday, considering your relatively consistent pace (9 minutes and 54 seconds), could further enhance your performance. This balanced approach, combined with strategic rest days, will aid in progressively building the stamina and speed necessary for your upcoming marathon.\n",
"weekly_mileage_target: Reviewing your past training weeks, it's clear that your mileage has been consistently increasing, a positive trend as you prepare for your marathon. Your mileage has progressed from 28.7 miles in Week 25 to 40.19 miles in Week 31, with your longest runs also showing a strong and steady increase, up to 14.03 miles in the most recent week. Given this steady build-up, for next week, I recommend a slight increase to around 42 miles while incorporating a long run of approximately 15 miles. This will continue to build your endurance while following a sensible progressive overload strategy. Keep your workouts on Wednesdays focused on speed or tempo runs and maintain your long run on Saturday to simulate race conditions efficiently. Great work, and let's keep this momentum going!"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"from src.types.training_week import TrainingWeek\n",
"from src.types.training_week_with_coaching import TrainingWeekWithCoaching\n",
"import polars as pl\n",
"\n",
"def calc_weekly_total_mileage(training_week: TrainingWeek) -> float:\n",
" \"\"\"\n",
" Calculates the total mileage for a given week\n",
"\n",
" :param training_week: instance of TrainingWeek\n",
" :return: The total mileage\n",
" \"\"\" \n",
" return sum(\n",
" [\n",
" getattr(training_week, attrib).distance \n",
" for attrib in training_week.__dict__\n",
" ]\n",
" )\n",
" \n",
"\n",
"def get_mid_week_delta(\n",
" training_week_with_coaching: TrainingWeekWithCoaching,\n",
" activities: pl.DataFrame\n",
") -> float:\n",
" \"\"\"\n",
" Assumes that activities is truncated to the current week, calculating the \n",
" difference between target mileage and actual mileage thus far this week\n",
"\n",
" :param training_week_with_coaching: instance TrainingWeekWithCoaching\n",
" :param activities: DataFrame of activities thus far this week\n",
" :return: The mileage delta as a float\n",
" \"\"\"\n",
" actual_mileage = activities['distance_in_miles'].sum()\n",
" weekly_target = calc_weekly_total_mileage(\n",
" training_week_with_coaching.training_week\n",
" )\n",
" mileage_delta = weekly_target - actual_mileage\n",
"\n",
" return mileage_delta"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [],
"source": [
"resp = get_training_week_with_coaching(athlete_id)\n",
"resp"
"@freeze_time(\"2024-08-08 20:00:00\")\n",
"def mock_get_activities_df(strava_client, num_weeks=8):\n",
" return get_activities_df(strava_client, num_weeks)\n",
"\n",
"training_week_with_coaching = get_training_week_with_coaching(athlete_id)\n",
"activities = mock_get_activities_df(strava_client, num_weeks=1)\n",
"\n",
"mid_week_detla = get_mid_week_delta(\n",
" training_week_with_coaching=training_week_with_coaching,\n",
" activities=activities\n",
")"
]
},
{
Expand Down

0 comments on commit 0e0cc3e

Please sign in to comment.