Replace fixed DSL fields with parameterized metric expressions
This commit is contained in:
+19
-17
@@ -18,41 +18,41 @@ def daily(history, owner_id, zone, start, end, q, catalog):
|
||||
db.select(DailyHealth).where(DailyHealth.owner_id == owner_id,
|
||||
DailyHealth.day >= start, DailyHealth.day < end))}
|
||||
result = []
|
||||
last_run = last_long = None
|
||||
last_matching = {}
|
||||
streak = 0
|
||||
earlier = [r for r in history if r.day < start]
|
||||
if earlier:
|
||||
last_run = max(r.day for r in earlier)
|
||||
longs = [r.day for r in earlier if r.distance_m >= q["long_run"] * 1000]
|
||||
last_long = max(longs) if longs else None
|
||||
day = start - timedelta(days=1)
|
||||
while by_day[day]:
|
||||
streak += 1
|
||||
day -= timedelta(days=1)
|
||||
from .analysis_engine import matches
|
||||
|
||||
since_specs = [s for s in q["derived"] if "since" in s]
|
||||
for spec in since_specs:
|
||||
qualifying = [r.day for r in earlier if matches(r, spec["since"])]
|
||||
last_matching[spec["name"]] = max(qualifying) if qualifying else None
|
||||
for index in range((end - start).days):
|
||||
day = start + timedelta(days=index)
|
||||
rows = by_day[day]
|
||||
if rows:
|
||||
last_run = day
|
||||
streak += 1
|
||||
else:
|
||||
streak = 0
|
||||
if any(r.distance_m >= q["long_run"] * 1000 for r in rows):
|
||||
last_long = day
|
||||
values = {key: None for key in catalog}
|
||||
distance = sum(r.distance_m for r in rows)
|
||||
duration = sum(r.duration_s for r in rows)
|
||||
values.update(distance=distance / 1000, duration=duration / 3600,
|
||||
sessions=len(rows), count=1, run_day_streak=streak,
|
||||
days_since_run=(day - last_run).days if last_run else None,
|
||||
days_since_long_run=(day - last_long).days if last_long else None)
|
||||
for days in (7, 28):
|
||||
window = [r for d in range(days) for r in by_day[day - timedelta(days=d)]]
|
||||
values[f"rolling_{days}d_distance"] = sum(r.distance_m for r in window) / 1000
|
||||
values[f"rolling_{days}d_count"] = len(window)
|
||||
if days == 7:
|
||||
total = sum(r.distance_m for r in window)
|
||||
values["long_run_share"] = max(r.distance_m for r in window) / total * 100 if total else None
|
||||
sessions=len(rows), count=1, run_day_streak=streak)
|
||||
window = [r for d in range(7) for r in by_day[day - timedelta(days=d)]]
|
||||
total = sum(r.distance_m for r in window)
|
||||
values["long_run_share"] = max(r.distance_m for r in window) / total * 100 if total else None
|
||||
for spec in since_specs:
|
||||
name = spec["name"]
|
||||
if any(matches(r, spec["since"]) for r in rows):
|
||||
last_matching[name] = day
|
||||
last = last_matching[name]
|
||||
values[name] = (day - last).days if last else None
|
||||
for field in ("perceived_effort", "fatigue"):
|
||||
known = [r.values[field] for r in rows if valid(r.values.get(field))]
|
||||
values[field] = sum(known) / len(known) if known else None
|
||||
@@ -69,6 +69,8 @@ def daily(history, owner_id, zone, start, end, q, catalog):
|
||||
activity_id=None, activity_ids=[r.id for r in rows])
|
||||
result.append(row)
|
||||
for spec in q["derived"]:
|
||||
if "since" in spec:
|
||||
continue
|
||||
if "window" in spec:
|
||||
config = spec["window"]
|
||||
from .stats_analysis import statistic
|
||||
|
||||
Reference in New Issue
Block a user