Last active
February 2, 2025 06:29
-
-
Save ahaxu/c86de34e19be44a5c61483dcbdd0c083 to your computer and use it in GitHub Desktop.
98_runners_tet_2025.py
This file contains hidden or 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
def f(activities): | |
""" | |
customize rule for 98 runners | |
challenge Tet 2025 | |
""" | |
import math | |
from datetime import datetime | |
white_list_acts = [ | |
] | |
act_by_date = dict() | |
for act in activities: | |
dt_str = act.get('start_date_local') # 2021-02-12T20:40:00Z | |
dt_obj = datetime.strptime(dt_str, '%Y-%m-%dT%H:%M:%SZ') | |
# key for ac_by_date dict | |
dt_ymd = int("{}{}{}".format(dt_obj.year, dt_obj.month, dt_obj.day)) | |
# check if act has minimum 1km | |
min_km = math.floor(act["distance"]/1000) | |
if min_km < 1: | |
print('act id {} with km {} not satisfied'.format( | |
act.get('id'), min_km)) | |
continue | |
# check gps | |
start_latlng = act.get('start_latlng') | |
end_latlng = act.get('end_latlng') | |
# print('debug latlong {} {} {}'.format(act.get('id'), start_latlng, end_latlng)) | |
if len(start_latlng) == 0 or len(end_latlng) == 0: | |
print('act id {} has no GPS'.format(act.get('id'))) | |
continue | |
# round with 2 decimal | |
km = round(act["distance"] / 1000, 2) | |
# check if act over 42.2km | |
if km > 42.2: | |
print('act id {} with km {} over 42.2 km'.format( | |
act.get('id'), km)) | |
continue | |
if act.get('id') in white_list_acts: | |
act["block"] = km | |
act["km"] = km | |
act["point"] = km | |
if dt_ymd in act_by_date: | |
act_by_date[dt_ymd].append(act) | |
else: | |
act_by_date[dt_ymd] = [act] | |
print("whitelist act id {} - name {}".format(act.get('id'), act.get('name'))) | |
continue | |
# check rest time | |
gap_time_in_minutes = abs( | |
act.get('elapsed_time', 0) - act.get('moving_time', 0)) / 60 | |
if gap_time_in_minutes > 30: | |
print("act_id {}: over 30 mins".format(act.get('id'))) | |
continue | |
# check avg_pace first | |
avg_pace = round((1000/act.get('average_speed', 0))/60, 1) | |
if act.get('type') == "Run" \ | |
and (3 <= avg_pace <= 12): | |
# check valid split pace via splits_metric | |
if act.get('splits_metric') is None: | |
print('act id {} has no splits_metric info'.format(act.get('id'))) | |
continue | |
is_valid_split_pace = True | |
for split in act.get('splits_metric'): | |
print('split {}'.format(split)) | |
if split.get('distance') < 100: | |
print( | |
'consider valid pace for distance less than 100m {}'.format(split)) | |
continue | |
if int(split.get('average_speed')) == 0: | |
is_valid_split_pace = False | |
print('invalid average speed') | |
print(split) | |
break | |
split_pace = round( | |
(1000/split.get('average_speed', 0))/60, 1) | |
if split_pace < 3 or split_pace > 12: | |
is_valid_split_pace = False | |
print('act id {} has in valid split pace, split no: {}, split_pace: {}'.format( | |
act.get('id'), split.get('split'), split_pace)) | |
break | |
# if valid split pace add to act_by_date | |
if is_valid_split_pace: | |
act['block'] = km | |
act['km'] = km | |
act['point'] = km | |
if dt_ymd in act_by_date: | |
act_by_date[dt_ymd].append(act) | |
else: | |
act_by_date[dt_ymd] = [act] | |
valid_acts = [] | |
for d in sorted(act_by_date): | |
print("debug act by date {}".format(d)) | |
print("debug act by date len {}".format(len(act_by_date.get(d)))) | |
# sort by start_date_local | |
aacts = sorted(act_by_date.get( | |
d), key=lambda x: x.get('start_date_local'), reverse=True) | |
for a in aacts: | |
# x2 km/point | |
if d in [202521, 202522, 202528, 202529, 2025215, 2025216]: | |
print('x2 day {} - {}'.format(d, km)) | |
a['block'] = 2 * a.get('block') | |
a['km'] = 1 * a.get('km') | |
a['point'] = 2 * a.get('point') | |
valid_acts.append(a) | |
print('valid_acts len: {}'.format(len(valid_acts))) | |
return valid_acts | |
acts = f(activities) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment