#!/usr/bin/env python3 """Helper utilities for the fitness trainer agent. Usage: workout.py e1rm # Estimate 1RM (Epley) workout.py volume # Total tonnage workout.py training-max [pct] # Training max (default 90%) workout.py cycle # Suggest weights for a wave Examples: workout.py e1rm 185 5 workout.py volume 3 5 185 workout.py training-max 210 workout.py cycle 200 5x5 """ import sys import math def e1rm(weight: float, reps: int) -> float: """Estimate 1RM using the Epley formula.""" if reps == 0: return weight if reps == 1: return weight return weight * (1 + reps / 30) def volume(sets: int, reps: int, weight: float) -> float: """Calculate total tonnage.""" return sets * reps * weight def training_max(e1rm_val: float, pct: float = 0.90) -> float: """Calculate training max as a percentage of e1RM.""" return e1rm_val * pct def round_to_nearest(weight: float, increment: float = 5.0) -> float: """Round weight to the nearest plate increment.""" return round(weight / increment) * increment def suggest_cycle_weights(tm: float, sets: int, reps: int, steps: int = 4): """Suggest wave weights from ~80% to ~95% of training max. Args: tm: Training max sets: Sets per exercise reps: Reps per set (target) steps: Number of weeks in the wave """ print(f"Training max: {tm}lb") print(f"Scheme: {sets}x{reps}") print() for week in range(steps): pct = 0.80 + week * 0.05 week_weight = round_to_nearest(tm * pct) print(f" Week {week + 1}: {int(pct * 100)}% = {int(week_weight)}lb") def main(): if len(sys.argv) < 2: print(__doc__) sys.exit(1) cmd = sys.argv[1] if cmd == "e1rm": if len(sys.argv) < 4: print("Usage: workout.py e1rm ") sys.exit(1) w = float(sys.argv[2]) r = int(sys.argv[3]) est = round_to_nearest(e1rm(w, r)) print(f"e1RM: {int(est)}lb") elif cmd == "volume": if len(sys.argv) < 5: print("Usage: workout.py volume ") sys.exit(1) s = int(sys.argv[2]) r = int(sys.argv[3]) w = float(sys.argv[4]) print(f"Volume: {int(volume(s, r, w))}lb") elif cmd == "training-max": if len(sys.argv) < 3: print("Usage: workout.py training-max [pct]") sys.exit(1) e = float(sys.argv[2]) p = float(sys.argv[3]) if len(sys.argv) > 3 else 0.90 tm = round_to_nearest(training_max(e, p)) print(f"Training max: {int(tm)}lb") elif cmd == "cycle": if len(sys.argv) < 4: print("Usage: workout.py cycle ") sys.exit(1) tm = float(sys.argv[2]) scheme = sys.argv[3] try: parts = scheme.lower().split("x") sets = int(parts[0]) reps = int(parts[1]) except (IndexError, ValueError): print(f"Invalid scheme '{scheme}'. Use format like 3x5 or 5x5.") sys.exit(1) suggest_cycle_weights(tm, sets, reps) else: print(f"Unknown command: {cmd}") print(__doc__) sys.exit(1) if __name__ == "__main__": main()