Skip to content

Instantly share code, notes, and snippets.

@zdimension
Last active July 4, 2024 05:12
Show Gist options
  • Save zdimension/8bf11dd61a6e18f70ddad9f47fdecef6 to your computer and use it in GitHub Desktop.
Save zdimension/8bf11dd61a6e18f70ddad9f47fdecef6 to your computer and use it in GitHub Desktop.
wrote this code quickly, didn't spend any time making it look good, a third is probably copilot
import json
import sys
from datetime import datetime, timedelta
def parse(d):
return datetime.fromisoformat(d)
def proc(d):
s, e = map(parse, d)
return e - s
#f = json.load(sys.stdin)
# for all folder in current folder
import os
f = []
for folder in os.listdir():
if not os.path.isdir(folder):
continue
# for each json file
for file in os.listdir(folder):
if not file.endswith(".json"):
continue
with open(os.path.join(folder, file), encoding="utf-8") as fp:
try:
data = json.load(fp)["timelineObjects"]
except:
print(file)
raise
for obj in data:
if act := obj.get("activitySegment", None):
if act.get("activityType") == "WALKING":
if "distance" in act:
dist = act["distance"]
else:
dist = act["waypointPath"]["distanceMeters"]
d = act["duration"]
d = (d["startTimestamp"], d["endTimestamp"])
speed = (dist / 1000) / (proc(d).total_seconds() / 3600)
if speed > 15:
continue
f.append((dist, d))
import numpy as np
import pytz
walk_data = [((dist / 1000) / (proc(d).total_seconds() / 3600), d[0])
for (dist, d) in f
if dist > 100 and parse(d[0]) >= datetime(2015, 9, 1, tzinfo=pytz.utc) and parse(d[0]) <= datetime(2025, 6, 30, tzinfo=pytz.utc)]
walks = np.array([x[0] for x in walk_data])
med = np.median(walks)
print(med)
print(np.average(walks))
walks = walks[walks > 1]
print(walks)
import matplotlib.pyplot as plt
ax = plt.subplot(111)
ax.hist(walks, bins=45)
ax.grid('on', linestyle='--', linewidth=0.5)
ax.set_xlabel("Walk speed (km/h)")
ax.set_ylabel("Walk count")
# export to high quality png
plt.savefig('walk.png', dpi=300)
# write histo data to json
with open("walk.json", "w") as fp:
hist, bins = np.histogram(walks, bins=45)
json.dump({"hist": hist.tolist(), "bins": bins.tolist()}, fp)
# average walking speed per year
from collections import defaultdict
walks_per_year = defaultdict(list)
for dist, date in f:
year = (parse(date[0]) - timedelta(days=9*30)).year
walks_per_year[year].append(dist / 1000)
av_per_year = {year: np.sum(dists) for year, dists in walks_per_year.items() if year >= 2017}
# plot average walking speed per year
plt.clf()
ax = plt.subplot(111)
ax.bar(av_per_year.keys(), av_per_year.values())
with open("yearly.json", "w") as fp:
json.dump(av_per_year, fp)
ax.grid('on', linestyle='--', linewidth=0.5)
ax.set_xlabel("School year")
ax.set_ylabel("Distance walked (km)")
plt.savefig('walk_per_year.png', dpi=300)
walks_per_month = defaultdict(list)
for dist, date in f:
if date[0] < "2017-09":
continue
adjusted = date[0][:len("yyyy-mm")]
if dist / 1000 > 10:
print(date, dist / 1000)
walks_per_month[adjusted].append(dist / 1000)
av_per_month = {month: np.sum(dists) for month, dists in sorted(walks_per_month.items(), key= lambda x: x[0])}
print(av_per_month)
plt.clf()
ax = plt.subplot(111)
#ax.bar(av_per_month.keys(), av_per_month.values())
# area under line
ax.fill_between(list(av_per_month.keys()), 0, list(av_per_month.values()), color="skyblue", alpha=0.4)
with open("monthly.json", "w") as fp:
json.dump(av_per_month, fp)
ax.grid('on', linestyle='--', linewidth=0.5)
ax.set_xlabel("Month")
ax.set_ylabel("Distance walked (km)")
plt.savefig('walk_per_month.png', dpi=300)
vals = list(av_per_month.values())
# get 3-month moving average
WIDTH = 3
#WEIGHTS = np.ones(WIDTH) / WIDTH
WEIGHTS = np.array([0.25, 0.5, 0.25])
moving_avg = [np.average(vals[i-(WIDTH//2):i+(WIDTH//2)+1], weights=WEIGHTS) for i in range(WIDTH//2, len(vals) - WIDTH//2)]
plt.clf()
ax = plt.subplot(111)
ax.plot(list(av_per_month.keys())[WIDTH//2:-(WIDTH//2)], moving_avg)
ax.grid('on', linestyle='--', linewidth=0.5)
ax.set_xlabel("Month")
ax.set_ylabel("Distance walked (km)")
plt.savefig('walk_per_month_moving_avg.png', dpi=300)
with open("moving_avg.json", "w") as fp:
json.dump(dict(zip(list(av_per_month.keys())[1:-1], moving_avg)), fp)
import json
import sys
from datetime import datetime, timedelta
def parse(d):
return datetime.fromisoformat(d)
def proc(d):
s, e = map(parse, d)
return e - s
#f = json.load(sys.stdin)
# for all folder in current folder
import os
import xml.etree.ElementTree as ET
f = []
for file in os.listdir("Activités"):
if not file.endswith(".tcx"):
continue
with open(os.path.join("Activités", file), encoding="utf-8") as fp:
root = tree.getroot()
for act in root.iter("{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Activity"):
# if attribute sport = walking
if act.attrib["Sport"] == "Walking":
# get child lap
lap = act.find("{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Lap")
start_time = lap.attrib["StartTime"]
dist = float(lap.find("{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}DistanceMeters").text)
time = float(lap.find("{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}TotalTimeSeconds").text)
d = (parse(start_time).isoformat(), (parse(start_time) + timedelta(seconds=time)).isoformat())
speed = (dist / 1000) / (time / 3600)
if speed > 15:
continue
f.append((dist, d))
import numpy as np
import pytz
walk_data = [((dist / 1000) / (proc(d).total_seconds() / 3600), d[0])
for (dist, d) in f
if dist > 100 and proc(d).total_seconds() > 300 and parse(d[0]) >= datetime(2015, 9, 1, tzinfo=pytz.utc) and parse(d[0]) <= datetime(2025, 6, 30, tzinfo=pytz.utc)]
walks = np.array([x[0] for x in walk_data])
med = np.median(walks)
print(med)
print(np.average(walks))
walks = walks[walks > 1]
print(walks)
import matplotlib.pyplot as plt
ax = plt.subplot(111)
ax.hist(walks, bins=45)
ax.grid('on', linestyle='--', linewidth=0.5)
ax.set_xlabel("Walk speed (km/h)")
ax.set_ylabel("Walk count")
# export to high quality png
plt.savefig('walk.png', dpi=300)
# write histo data to json
with open("walk.json", "w") as fp:
hist, bins = np.histogram(walks, bins=45)
json.dump({"hist": hist.tolist(), "bins": bins.tolist()}, fp)
# average walking speed per year
from collections import defaultdict
walks_per_year = defaultdict(list)
for dist, date in f:
year = (parse(date[0]) - timedelta(days=9*30)).year
walks_per_year[year].append(dist / 1000)
av_per_year = {year: np.sum(dists) for year, dists in walks_per_year.items() if year >= 2017}
# plot average walking speed per year
plt.clf()
ax = plt.subplot(111)
ax.bar(av_per_year.keys(), av_per_year.values())
with open("yearly.json", "w") as fp:
json.dump(av_per_year, fp)
ax.grid('on', linestyle='--', linewidth=0.5)
ax.set_xlabel("School year")
ax.set_ylabel("Distance walked (km)")
plt.savefig('walk_per_year.png', dpi=300)
walks_per_month = defaultdict(list)
for dist, date in f:
if date[0] < "2017-09":
continue
adjusted = date[0][:len("yyyy-mm")]
if dist / 1000 > 10:
print(date, dist / 1000)
walks_per_month[adjusted].append(dist / 1000)
av_per_month = {month: np.sum(dists) for month, dists in sorted(walks_per_month.items(), key= lambda x: x[0])}
print(av_per_month)
plt.clf()
ax = plt.subplot(111)
#ax.bar(av_per_month.keys(), av_per_month.values())
# area under line
ax.fill_between(list(av_per_month.keys()), 0, list(av_per_month.values()), color="skyblue", alpha=0.4)
with open("monthly.json", "w") as fp:
json.dump(av_per_month, fp)
ax.grid('on', linestyle='--', linewidth=0.5)
ax.set_xlabel("Month")
ax.set_ylabel("Distance walked (km)")
plt.savefig('walk_per_month.png', dpi=300)
vals = list(av_per_month.values())
# get 3-month moving average
WIDTH = 3
#WEIGHTS = np.ones(WIDTH) / WIDTH
WEIGHTS = np.array([0.25, 0.5, 0.25])
moving_avg = [np.average(vals[i-(WIDTH//2):i+(WIDTH//2)+1], weights=WEIGHTS) for i in range(WIDTH//2, len(vals) - WIDTH//2)]
plt.clf()
ax = plt.subplot(111)
ax.plot(list(av_per_month.keys())[WIDTH//2:-(WIDTH//2)], moving_avg)
ax.grid('on', linestyle='--', linewidth=0.5)
ax.set_xlabel("Month")
ax.set_ylabel("Distance walked (km)")
plt.savefig('walk_per_month_moving_avg.png', dpi=300)
with open("moving_avg.json", "w") as fp:
json.dump(dict(zip(list(av_per_month.keys())[1:-1], moving_avg)), fp)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment