-
Notifications
You must be signed in to change notification settings - Fork 1
strava competitor - idk if it works at all -- we be vibing #315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
haversine==2.8.0 | ||
typing-extensions==4.8.0 |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,183 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
import haversine | ||||||||||||||||||||||||||||||||||||||||||||||
import datetime | ||||||||||||||||||||||||||||||||||||||||||||||
import json | ||||||||||||||||||||||||||||||||||||||||||||||
import os | ||||||||||||||||||||||||||||||||||||||||||||||
from typing import Dict, List, Tuple, Optional, Union, Any | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
def calculate_distance(coords: List[Tuple[float, float]]) -> float: | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Non-decreasing Distance with Additional Coordinates
view all inputs Unit Tests# Unit Test for "Non-decreasing Distance with Additional Coordinates": Adding more coordinates to the list should not decrease the total distance calculated by the function.
def benchify_test_distance_non_decreasing_with_more_coords(coords):
initial_distance = calculate_distance(coords)
new_coord = (0.0, 0.0)
new_distance = calculate_distance(coords + [new_coord])
assert new_distance >= initial_distance
def benchify_test_distance_non_decreasing_with_more_coords_exec_test_passing_0():
coords=[(0.0, 0.0), (0.0, 0.0)]
benchify_test_distance_non_decreasing_with_more_coords(coords) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Non-negative Distance Calculation
view all inputs Unit Tests# Unit Test for "Non-negative Distance Calculation": The function should always return a non-negative distance, regardless of the input coordinates.
def benchify_test_distance_is_non_negative(coords):
distance = calculate_distance(coords)
assert distance >= 0.0
def benchify_test_distance_is_non_negative_exec_test_passing_0():
coords=[(0.0, 0.0), (0.0, 0.0)]
benchify_test_distance_is_non_negative(coords) |
||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
Calculate total distance in kilometers given a list of GPS coordinates. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||||||
coords: List of (latitude, longitude) tuples | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||||
Total distance in kilometers | ||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
total_distance = 0.0 | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
for i in range(len(coords) - 1): | ||||||||||||||||||||||||||||||||||||||||||||||
# Calculate distance between consecutive points using haversine formula | ||||||||||||||||||||||||||||||||||||||||||||||
distance = haversine.haversine(coords[i], coords[i+1], unit='km') | ||||||||||||||||||||||||||||||||||||||||||||||
total_distance += distance | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
return total_distance | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
def calculate_elevation_gain(elevation_data: List[float]) -> float: | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Elevation gain is non-negative
view all inputs Unit Tests# Unit Test for "Elevation gain is non-negative": The function `calculate_elevation_gain` should always return a non-negative value, as it only sums positive elevation differences.
def benchify_test_elevation_gain_non_negative(elevation_data):
result = calculate_elevation_gain(elevation_data)
assert result >= 0
def benchify_test_elevation_gain_non_negative_exec_test_passing_0():
elevation_data=[0.0, 0.0]
benchify_test_elevation_gain_non_negative(elevation_data) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Zero gain for non-increasing elevation
view all inputs Unit Tests# Unit Test for "Zero gain for non-increasing elevation": If all elements in `elevation_data` are the same or in non-increasing order, the function should return zero, as there would be no positive elevation gain.
def benchify_test_zero_gain_for_non_increasing_elevation(elevation_data):
sorted_data = sorted(elevation_data, reverse=True)
result = calculate_elevation_gain(sorted_data)
assert result == 0
def benchify_test_zero_gain_for_non_increasing_elevation_exec_test_passing_0():
elevation_data=[0.0, 0.0]
benchify_test_zero_gain_for_non_increasing_elevation(elevation_data) |
||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
Calculate total elevation gain in meters from a list of elevation points. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||||||
elevation_data: List of elevation values in meters | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||||
Total elevation gain in meters | ||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
gain = 0.0 | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
for i in range(len(elevation_data) - 1): | ||||||||||||||||||||||||||||||||||||||||||||||
# Only count positive elevation changes | ||||||||||||||||||||||||||||||||||||||||||||||
diff = elevation_data[i+1] - elevation_data[i] | ||||||||||||||||||||||||||||||||||||||||||||||
if diff > 0: | ||||||||||||||||||||||||||||||||||||||||||||||
gain += diff | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
return gain | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
def calculate_pace(distance_km: float, duration_seconds: int) -> Tuple[int, int]: | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅
view all inputs Unit Tests# Unit Test for "`calculate_pace` returns (0, 0) for non-positive distance": If `distance_km` is zero or negative, `calculate_pace` should return a tuple (0, 0), indicating an invalid or undefined pace.
def benchify_test_calculate_pace_non_positive_distance(distance_km, duration_seconds):
assert calculate_pace(distance_km, duration_seconds) == (0, 0)
def benchify_test_calculate_pace_non_positive_distance_exec_test_passing_0():
distance_km=0.0
duration_seconds=0
benchify_test_calculate_pace_non_positive_distance(distance_km, duration_seconds) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅
view all inputs Unit Tests# Unit Test for "`calculate_pace` returns non-negative minutes and seconds": For positive `distance_km`, `calculate_pace` should return a tuple where both `minutes` and `seconds` are non-negative integers.
def benchify_test_calculate_pace_non_negative_output(distance_km, duration_seconds):
minutes, seconds = calculate_pace(distance_km, duration_seconds)
assert minutes >= 0 and seconds >= 0
def benchify_test_calculate_pace_non_negative_output_exec_test_passing_0():
distance_km=0.0001
duration_seconds=0
benchify_test_calculate_pace_non_negative_output(distance_km, duration_seconds) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌
view all inputs Stack Trace
|
||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
Calculate pace in minutes per kilometer. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||||||
distance_km: Distance in kilometers | ||||||||||||||||||||||||||||||||||||||||||||||
duration_seconds: Duration in seconds | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||||
Tuple of (minutes, seconds) per kilometer | ||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
if distance_km <= 0: | ||||||||||||||||||||||||||||||||||||||||||||||
return (0, 0) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Calculate seconds per kilometer | ||||||||||||||||||||||||||||||||||||||||||||||
seconds_per_km = duration_seconds / distance_km | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Convert to minutes and seconds | ||||||||||||||||||||||||||||||||||||||||||||||
minutes = int(seconds_per_km // 60) | ||||||||||||||||||||||||||||||||||||||||||||||
seconds = int(seconds_per_km % 60) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
return (minutes, seconds) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
def save_activity(user_id: str, activity_data: Dict[str, Any], | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Unique Activity ID Generation
view all inputs Stack Trace
Unit Tests# Unit Test for "Unique Activity ID Generation": The function `save_activity` should generate a unique activity ID for each call, assuming `user_id` and the current timestamp are unique at the time of the call.
def benchify_test_unique_activity_id(user_id, activity_data):
activity_id1 = save_activity(user_id, activity_data.copy())
activity_id2 = save_activity(user_id, activity_data.copy())
assert activity_id1 != activity_id2
def benchify_test_unique_activity_id_exec_test_failing_0():
user_id='0'
activity_data={}
benchify_test_unique_activity_id(user_id, activity_data) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Directory Creation and JSON File Saving
view all inputs Stack Trace
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Activity Data Modification
view all inputs Stack Trace
Unit Tests# Unit Test for "Activity Data Modification": The function `save_activity` should add an 'id' key with the generated activity ID and a 'timestamp' key with the current timestamp to the `activity_data` dictionary before saving it.
def benchify_test_activity_data_modification(user_id, activity_data):
activity_id = save_activity(user_id, activity_data.copy())
assert "id" in activity_data
assert activity_data["id"] == activity_id
assert "timestamp" in activity_data
def benchify_test_activity_data_modification_exec_test_failing_0():
user_id='0'
activity_data={}
benchify_test_activity_data_modification(user_id, activity_data) |
||||||||||||||||||||||||||||||||||||||||||||||
base_dir: str = "data/activities") -> str: | ||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
Save activity data to disk and return the activity ID. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||||||
user_id: Unique identifier for the user | ||||||||||||||||||||||||||||||||||||||||||||||
activity_data: Dictionary containing activity information | ||||||||||||||||||||||||||||||||||||||||||||||
base_dir: Base directory for storing activity data | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||||
Activity ID | ||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
# Generate a unique activity ID | ||||||||||||||||||||||||||||||||||||||||||||||
activity_id = f"{user_id}_{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}" | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Add activity ID and timestamp to the data | ||||||||||||||||||||||||||||||||||||||||||||||
activity_data["id"] = activity_id | ||||||||||||||||||||||||||||||||||||||||||||||
activity_data["timestamp"] = datetime.datetime.now().isoformat() | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Create user directory if it doesn't exist | ||||||||||||||||||||||||||||||||||||||||||||||
user_dir = os.path.join(base_dir, user_id) | ||||||||||||||||||||||||||||||||||||||||||||||
os.makedirs(user_dir, exist_ok=True) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Save activity data as JSON | ||||||||||||||||||||||||||||||||||||||||||||||
file_path = os.path.join(user_dir, f"{activity_id}.json") | ||||||||||||||||||||||||||||||||||||||||||||||
with open(file_path, "w") as f: | ||||||||||||||||||||||||||||||||||||||||||||||
json.dump(activity_data, f, indent=2) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
return activity_id | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
def get_user_activities(user_id: str, limit: Optional[int] = None, | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Returns empty list if user directory does not exist
view all inputs Unit Tests# Unit Test for "Returns empty list if user directory does not exist": The function should return an empty list if the directory corresponding to the user_id does not exist.
def benchify_test_get_user_activities_no_directory(user_id, limit, activity_type, base_dir):
result = get_user_activities(user_id, limit, activity_type, base_dir)
assert result == []
def benchify_test_get_user_activities_no_directory_exec_test_passing_0():
user_id=''
limit=1
activity_type=''
base_dir=''
benchify_test_get_user_activities_no_directory(user_id, limit, activity_type, base_dir) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Returns activities sorted by timestamp
view all inputs Stack Trace
Unit Tests# Unit Test for "Returns activities sorted by timestamp": The function should return a list of activities sorted by the 'timestamp' key in descending order.
def benchify_test_get_user_activities_sorted_by_timestamp(user_id, limit, activity_type, base_dir):
user_dir = os.path.join(base_dir, user_id)
os.makedirs(user_dir, exist_ok=True)
activities = [
{'timestamp': '2023-10-01T12:00:00', 'type': 'run'},
{'timestamp': '2023-10-02T12:00:00', 'type': 'ride'},
{'timestamp': '2023-10-03T12:00:00', 'type': 'swim'}
]
for i, activity in enumerate(activities):
with open(os.path.join(user_dir, f'activity_{i}.json'), 'w') as f:
json.dump(activity, f)
result = get_user_activities(user_id, limit, activity_type, base_dir)
assert result == sorted(result, key=lambda x: x['timestamp'], reverse=True)
def benchify_test_get_user_activities_sorted_by_timestamp_exec_test_failing_0():
user_id=''
limit=1
activity_type=''
base_dir=''
benchify_test_get_user_activities_sorted_by_timestamp(user_id, limit, activity_type, base_dir) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Respects limit on number of activities returned
view all inputs Stack Trace
Unit Tests# Unit Test for "Respects limit on number of activities returned": The function should return at most 'limit' number of activities if 'limit' is provided and is a positive integer.
def benchify_test_get_user_activities_respects_limit(user_id, limit, activity_type, base_dir):
user_dir = os.path.join(base_dir, user_id)
os.makedirs(user_dir, exist_ok=True)
activities = [
{'timestamp': '2023-10-01T12:00:00', 'type': 'run'},
{'timestamp': '2023-10-02T12:00:00', 'type': 'ride'},
{'timestamp': '2023-10-03T12:00:00', 'type': 'swim'}
]
for i, activity in enumerate(activities):
with open(os.path.join(user_dir, f'activity_{i}.json'), 'w') as f:
json.dump(activity, f)
result = get_user_activities(user_id, limit, activity_type, base_dir)
assert len(result) <= limit
def benchify_test_get_user_activities_respects_limit_exec_test_failing_0():
user_id=''
limit=1
activity_type=''
base_dir=''
benchify_test_get_user_activities_respects_limit(user_id, limit, activity_type, base_dir) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Filters activities by type
view all inputs Stack Trace
Unit Tests# Unit Test for "Filters activities by type": The function should only include activities where the 'type' key matches the 'activity_type' if 'activity_type' is provided.
def benchify_test_get_user_activities_filters_by_type(user_id, limit, activity_type, base_dir):
user_dir = os.path.join(base_dir, user_id)
os.makedirs(user_dir, exist_ok=True)
activities = [
{'timestamp': '2023-10-01T12:00:00', 'type': 'run'},
{'timestamp': '2023-10-02T12:00:00', 'type': 'ride'},
{'timestamp': '2023-10-03T12:00:00', 'type': 'swim'}
]
for i, activity in enumerate(activities):
with open(os.path.join(user_dir, f'activity_{i}.json'), 'w') as f:
json.dump(activity, f)
result = get_user_activities(user_id, limit, activity_type, base_dir)
assert all(activity['type'] == activity_type for activity in result)
def benchify_test_get_user_activities_filters_by_type_exec_test_failing_0():
user_id=''
limit=1
activity_type='run'
base_dir=''
benchify_test_get_user_activities_filters_by_type(user_id, limit, activity_type, base_dir) |
||||||||||||||||||||||||||||||||||||||||||||||
activity_type: Optional[str] = None, | ||||||||||||||||||||||||||||||||||||||||||||||
base_dir: str = "data/activities") -> List[Dict[str, Any]]: | ||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
Retrieve a user's activities with optional filtering. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||||||
user_id: Unique identifier for the user | ||||||||||||||||||||||||||||||||||||||||||||||
limit: Maximum number of activities to return (newest first) | ||||||||||||||||||||||||||||||||||||||||||||||
activity_type: Filter by activity type (e.g., "run", "ride", "swim") | ||||||||||||||||||||||||||||||||||||||||||||||
base_dir: Base directory for storing activity data | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||||
List of activity data dictionaries | ||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
user_dir = os.path.join(base_dir, user_id) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Return empty list if user directory doesn't exist | ||||||||||||||||||||||||||||||||||||||||||||||
if not os.path.exists(user_dir): | ||||||||||||||||||||||||||||||||||||||||||||||
return [] | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
activities = [] | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Get all JSON files in the user directory | ||||||||||||||||||||||||||||||||||||||||||||||
for filename in os.listdir(user_dir): | ||||||||||||||||||||||||||||||||||||||||||||||
if filename.endswith(".json"): | ||||||||||||||||||||||||||||||||||||||||||||||
file_path = os.path.join(user_dir, filename) | ||||||||||||||||||||||||||||||||||||||||||||||
with open(file_path, "r") as f: | ||||||||||||||||||||||||||||||||||||||||||||||
activity = json.load(f) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Apply activity type filter if provided | ||||||||||||||||||||||||||||||||||||||||||||||
if activity_type is None or activity.get("type") == activity_type: | ||||||||||||||||||||||||||||||||||||||||||||||
activities.append(activity) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Sort activities by timestamp (newest first) | ||||||||||||||||||||||||||||||||||||||||||||||
activities.sort(key=lambda x: x.get("timestamp", ""), reverse=True) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Apply limit if provided | ||||||||||||||||||||||||||||||||||||||||||||||
if limit is not None and limit > 0: | ||||||||||||||||||||||||||||||||||||||||||||||
activities = activities[:limit] | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
return activities | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
def calculate_statistics(activities: List[Dict[str, Any]]) -> Dict[str, Any]: | ||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
Calculate summary statistics for a list of activities. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||||||
activities: List of activity dictionaries | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||||
Dictionary with summary statistics | ||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||
if not activities: | ||||||||||||||||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||||||||||||||||
"total_activities": 0, | ||||||||||||||||||||||||||||||||||||||||||||||
"total_distance": 0, | ||||||||||||||||||||||||||||||||||||||||||||||
"total_elevation_gain": 0, | ||||||||||||||||||||||||||||||||||||||||||||||
"total_duration": 0, | ||||||||||||||||||||||||||||||||||||||||||||||
"activity_types": {} | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
stats = { | ||||||||||||||||||||||||||||||||||||||||||||||
"total_activities": len(activities), | ||||||||||||||||||||||||||||||||||||||||||||||
"total_distance": 0, | ||||||||||||||||||||||||||||||||||||||||||||||
"total_elevation_gain": 0, | ||||||||||||||||||||||||||||||||||||||||||||||
"total_duration": 0, | ||||||||||||||||||||||||||||||||||||||||||||||
"activity_types": {} | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
for activity in activities: | ||||||||||||||||||||||||||||||||||||||||||||||
# Accumulate totals | ||||||||||||||||||||||||||||||||||||||||||||||
stats["total_distance"] += activity.get("distance", 0) | ||||||||||||||||||||||||||||||||||||||||||||||
stats["total_elevation_gain"] += activity.get("elevation_gain", 0) | ||||||||||||||||||||||||||||||||||||||||||||||
stats["total_duration"] += activity.get("duration", 0) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
# Count by activity type | ||||||||||||||||||||||||||||||||||||||||||||||
activity_type = activity.get("type", "unknown") | ||||||||||||||||||||||||||||||||||||||||||||||
if activity_type in stats["activity_types"]: | ||||||||||||||||||||||||||||||||||||||||||||||
stats["activity_types"][activity_type] += 1 | ||||||||||||||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||||||||||||||
stats["activity_types"][activity_type] = 1 | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
return stats |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Distance Calculation with Single Coordinate
The function should return 0.0 when the list of coordinates contains only one point, as there are no consecutive points to calculate a distance between.
coords=[(0.0, 0.0)]
view all inputs
The property-based test has passed, indicating that the
calculate_distance
function behaves as expected when given a list containing a single GPS coordinate, returning a distance of 0.0 as there are no consecutive points to calculate a distance between, with the test using the argumentcoords=[(0.0, 0.0)]
. This result aligns with the described property that the function should return 0.0 for a single point. The test confirms the function's correctness for this specific scenario.Unit Tests