Anchor forecast top sets to latest rep target
This commit is contained in:
@@ -173,8 +173,9 @@ def _round_weight(value, increment, direction='nearest'):
|
||||
|
||||
def infer_rep_targets(repetitions, buffer=5):
|
||||
"""Return an expanded rep range based on the currently visible history."""
|
||||
numeric_reps = sorted({int(round(float(value))) for value in repetitions if value is not None})
|
||||
if not numeric_reps:
|
||||
numeric_rep_values = [int(round(float(value))) for value in repetitions if value is not None]
|
||||
numeric_reps = sorted(set(numeric_rep_values))
|
||||
if not numeric_rep_values:
|
||||
return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5, None, None
|
||||
|
||||
observed_min = min(numeric_reps)
|
||||
@@ -182,9 +183,10 @@ def infer_rep_targets(repetitions, buffer=5):
|
||||
target_min = max(1, observed_min - buffer)
|
||||
target_max = min(20, observed_max + buffer)
|
||||
target_reps = list(range(target_min, target_max + 1))
|
||||
centered_reps = int(round(float(np.median(numeric_reps))))
|
||||
centered_reps = max(target_min, min(target_max, centered_reps))
|
||||
return target_reps, centered_reps, observed_min, observed_max
|
||||
# Default to the latest recorded rep target so the first forecast comparison
|
||||
# is like-for-like. The full expanded range remains available in the table.
|
||||
default_reps = max(target_min, min(target_max, numeric_rep_values[-1]))
|
||||
return target_reps, default_reps, observed_min, observed_max
|
||||
|
||||
|
||||
def _top_set_estimates(e1rm, lower_e1rm, upper_e1rm, target_reps, increment):
|
||||
@@ -349,7 +351,7 @@ def get_exercise_graph_model(title, estimated_1rm, repetitions, weight, start_da
|
||||
forecast_start_position = None
|
||||
if forecast.get('available'):
|
||||
forecast_start_position = round((observed_max_date - observed_min_date).days / total_span, 3)
|
||||
for point in forecast['points']:
|
||||
for point_index, point in enumerate(forecast['points']):
|
||||
position = round((point['date'] - observed_min_date).days / total_span, 3)
|
||||
forecast_points.append((round(((point['value'] - min_e1rm) / e1rm_range) * vb_height, 1), position))
|
||||
forecast_band_lower.append((round(((point['lower'] - min_e1rm) / e1rm_range) * vb_height, 1), position))
|
||||
@@ -358,8 +360,17 @@ def get_exercise_graph_model(title, estimated_1rm, repetitions, weight, start_da
|
||||
(top_set for top_set in point['top_sets'] if top_set['repetitions'] == forecast['selected_reps']),
|
||||
None
|
||||
)
|
||||
top_set_message = ''
|
||||
if selected_top_set:
|
||||
if point_index == 0:
|
||||
top_set_message = f" · Recorded {_format_kg(weight[-1])}kg × {int(repetitions[-1])}"
|
||||
forecast_details.append({
|
||||
'position': position,
|
||||
'date': point['date'].strftime('%d %b %y'),
|
||||
'kind': 'Current reading',
|
||||
'e1rm': f"{_format_kg(forecast['last_value'])}kg",
|
||||
'top_set': f"{_format_kg(weight[-1])}kg × {int(repetitions[-1])} reps",
|
||||
'range': 'Observed value'
|
||||
})
|
||||
elif selected_top_set:
|
||||
top_set_message = (
|
||||
f" · Est. {selected_top_set['weight_display']}kg × {selected_top_set['repetitions']} "
|
||||
f"(range {selected_top_set['lower_weight_display']}–{selected_top_set['upper_weight_display']}kg)"
|
||||
|
||||
Reference in New Issue
Block a user