Last active
February 2, 2025 06:28
-
-
Save ahaxu/711ade07e6362356763e386070591a36 to your computer and use it in GitHub Desktop.
htr-tet-challenge-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): | |
import math | |
from datetime import datetime | |
white_list_acts = [ | |
13321551268, | |
13321963642, | |
13322559985, | |
13515471146 | |
] | |
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 3km | |
min_km = math.floor(act["distance"]/1000) | |
if min_km < 3: | |
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 if min km >= 3 | |
km = round(act["distance"] / 1000, 2) | |
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 <= 10): | |
# 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 > 10: | |
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)))) | |
aacts = sorted(act_by_date.get(d), key=lambda x: x.get('km'), reverse=True)[:2] | |
for a in aacts: | |
# x2 km/point for last day 2025129 | |
print('debug day xxx {}'.format(d)) | |
if d in [2025129]: | |
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