-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
92f41fa
commit b0f2645
Showing
5 changed files
with
146 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
backend/active_statistics/statistics/tables/top_hundred.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
""" | ||
The idea is that this is a generic "top 100's" table creator for all Strava | ||
activities. I can simply say I want "a table of the top 100 longest runs" or | ||
"shortest runs" or "most kudosed" or "hottest" activities or whatever, and this | ||
code can handle getting that data, and displaying it later in a table. | ||
""" | ||
|
||
from typing import Any, Callable, Iterator | ||
|
||
import pandas as pd | ||
from active_statistics.statistics.utils.strava_links import get_activity_url, get_link | ||
from stravalib import unithelper as uh | ||
from stravalib.model import Activity, ActivityType | ||
|
||
|
||
def get_top_hundred_table_function( | ||
activity_type: ActivityType, | ||
attribute_name: str, | ||
attribute_column_name: str, | ||
attribute_conversion_function: Callable[[Any], Any], | ||
) -> Callable[[Iterator[Activity]], pd.DataFrame]: | ||
def top_hundred_table_function(activities: Iterator[Activity]) -> pd.DataFrame: | ||
activity_names = [] | ||
attribute_column = [] | ||
activity_links = [] | ||
|
||
for activity in activities: | ||
if activity.type == activity_type: | ||
activity_names.append(activity.name) | ||
attribute_column.append( | ||
attribute_conversion_function(getattr(activity, attribute_name)) | ||
) | ||
activity_links.append(get_link(get_activity_url(activity.id))) | ||
|
||
# Create a DataFrame with the specified attribute as a column | ||
data = { | ||
"Activity Name": activity_names, | ||
attribute_column_name: attribute_column, | ||
"Activity Link": activity_links, | ||
} | ||
df = pd.DataFrame(data) | ||
|
||
# Sort the df | ||
df = df.sort_values(by=[attribute_column_name], ascending=False) | ||
|
||
# Only keep top 100 | ||
df = df.head(100) | ||
|
||
# Add a rank column as the first column | ||
df.insert(0, "rank", df.reset_index().index + 1) | ||
|
||
# Shorten the values | ||
df[attribute_column_name] = df[attribute_column_name].apply( | ||
lambda x: f"{x:.2f}" | ||
) | ||
|
||
return df | ||
|
||
return top_hundred_table_function | ||
|
||
|
||
def distance_conversion_function_to_km(quantity: uh.Quantity) -> float: | ||
return float(uh.kilometers(quantity).magnitude) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from active_statistics.statistics.tables import top_hundred | ||
|
||
|
||
class TestTopHundredLongestRuns: | ||
def test_cumulative_time_spent(self, some_basic_runs_and_rides) -> None: | ||
table_function = top_hundred.get_top_hundred_table_function( | ||
"Run", | ||
"distance", | ||
"Distance (km)", | ||
top_hundred.distance_conversion_function_to_km, | ||
) | ||
table_function(some_basic_runs_and_rides) | ||
|
||
def test_no_data(self, no_activities_at_all) -> None: | ||
table_function = top_hundred.get_top_hundred_table_function( | ||
"Run", | ||
"distance", | ||
"Distance (km)", | ||
top_hundred.distance_conversion_function_to_km, | ||
) | ||
table_function(no_activities_at_all) | ||
|
||
|
||
class TestTopHundredLongestRides: | ||
def test_cumulative_time_spent(self, some_basic_runs_and_rides) -> None: | ||
table_function = top_hundred.get_top_hundred_table_function( | ||
"Ride", | ||
"distance", | ||
"Distance (km)", | ||
top_hundred.distance_conversion_function_to_km, | ||
) | ||
table_function(some_basic_runs_and_rides) | ||
|
||
def test_no_data(self, no_activities_at_all) -> None: | ||
table_function = top_hundred.get_top_hundred_table_function( | ||
"Ride", | ||
"distance", | ||
"Distance (km)", | ||
top_hundred.distance_conversion_function_to_km, | ||
) | ||
table_function(no_activities_at_all) |