diff options
author | Andrew Cady <d@jerkface.net> | 2022-10-04 00:17:58 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2022-10-04 00:17:58 -0400 |
commit | 4f6af3442e7a4842e6cabb8a875060bfda1215e1 (patch) | |
tree | 73d5163757ca0c2992c0f2376e053b03d15ff94f | |
parent | 5f71638722aeb5eb2860fc3019dcd80414ea3cb1 (diff) |
compute 1rm by choosing the best of multiple specified performances
-rwxr-xr-x | repgoal.hs | 33 |
1 files changed, 16 insertions, 17 deletions
@@ -63,36 +63,35 @@ import Brick.Util (fg, bg, on, clamp) | |||
63 | import Brick.Widgets.Core | 63 | import Brick.Widgets.Core |
64 | import Brick.Widgets.Table | 64 | import Brick.Widgets.Table |
65 | 65 | ||
66 | data ExerciseStats = ExerciseStats { | 66 | data Performance = Achieved { |
67 | exerciseName :: Text, | ||
68 | achievedReps :: Integer, | 67 | achievedReps :: Integer, |
69 | achievedWeight :: Rational | 68 | achievedWeight :: Rational |
70 | } | 69 | } |
71 | 70 | ||
72 | data ExerciseTarget = ExerciseTarget { | 71 | data ExerciseTarget = ExerciseTarget { |
72 | exerciseName :: Text, | ||
73 | targetWeight :: Rational, | 73 | targetWeight :: Rational, |
74 | stats :: ExerciseStats | 74 | stats :: [Performance] |
75 | } | 75 | } |
76 | 76 | ||
77 | exercises :: [ExerciseTarget] | 77 | exercises :: [ExerciseTarget] |
78 | exercises = [ | 78 | exercises = [ |
79 | ExerciseTarget 345 $ ExerciseStats "Deadlift" 9 315, | 79 | ExerciseTarget "Deadlift" 345 $ [Achieved 5 360, Achieved 9 315], |
80 | ExerciseTarget 130 $ ExerciseStats "Press" 9 120 | 80 | ExerciseTarget "Press" 130 $ [Achieved 6 130, Achieved 9 120] |
81 | ] | 81 | ] |
82 | 82 | ||
83 | computeRepGoal :: ExerciseTarget -> (Integer) | 83 | computeRepGoal :: ExerciseTarget -> (Integer) |
84 | computeRepGoal ExerciseTarget{..} = head $ filter isPR [2..] | 84 | computeRepGoal ExerciseTarget{..} = head $ filter isPR [2..] |
85 | where | 85 | where |
86 | isPR n = let goal1rm = computeOneRepMax $ stats { achievedReps = n, achievedWeight = targetWeight } | 86 | isPR n = computeOneRepMax (Achieved n targetWeight) > computeOneRepMax (bestPerformance stats) |
87 | in goal1rm > computeOneRepMax stats | ||
88 | |||
89 | -- The 1RM estimation formula from Jim Wendler's 5-3-1 Powerlifting | ||
90 | -- manual: | ||
91 | 87 | ||
92 | -- Estimated 1 RM = Weight x Reps x 0.0333 + Weight. | 88 | bestPerformance :: [Performance] -> Performance |
89 | bestPerformance = head . sortBy (flip $ comparing computeOneRepMax) | ||
93 | 90 | ||
94 | computeOneRepMax :: ExerciseStats -> Rational | 91 | -- The formula from Jim Wendler's 5-3-1: |
95 | computeOneRepMax ExerciseStats{..} = achievedWeight * (realToFrac achievedReps * 0.0333 + 1) | 92 | -- 1RM = Weight x Reps x 0.0333 + Weight. |
93 | computeOneRepMax :: Performance -> Rational | ||
94 | computeOneRepMax Achieved{..} = achievedWeight * (realToFrac achievedReps * 0.0333 + 1) | ||
96 | 95 | ||
97 | showRational :: Rational -> String | 96 | showRational :: Rational -> String |
98 | showRational = printf "%.3f" . (realToFrac :: Rational -> Float) | 97 | showRational = printf "%.3f" . (realToFrac :: Rational -> Float) |
@@ -103,14 +102,14 @@ drawUI () = [a] | |||
103 | a = hCenter $ renderTable $ table $ | 102 | a = hCenter $ renderTable $ table $ |
104 | map str ["Exercise", "Achieved Reps", "Computed 1RM", "Goal Reps", "Goal+1"] : map toRow exercises | 103 | map str ["Exercise", "Achieved Reps", "Computed 1RM", "Goal Reps", "Goal+1"] : map toRow exercises |
105 | toRow x@ExerciseTarget{..} = | 104 | toRow x@ExerciseTarget{..} = |
106 | let ExerciseStats{..} = stats | 105 | let best@Achieved{..} = bestPerformance stats |
107 | repGoal = computeRepGoal x | 106 | repGoal = computeRepGoal x |
108 | goalTo1RM g = computeOneRepMax $ ExerciseStats exerciseName g targetWeight | 107 | goalTo1RM g = computeOneRepMax $ Achieved g targetWeight |
109 | in | 108 | in |
110 | [ | 109 | [ |
111 | txt exerciseName, | 110 | txt $ exerciseName, |
112 | str $ printf "%d @ %s" achievedReps (showRational achievedWeight), | 111 | str $ printf "%d @ %s" achievedReps (showRational achievedWeight), |
113 | str $ showRational $ computeOneRepMax stats, | 112 | str $ showRational $ computeOneRepMax best, |
114 | str $ printf "%d @ %s ≈ 1 @ %s" (repGoal) (showRational targetWeight) (showRational (goalTo1RM repGoal)), | 113 | str $ printf "%d @ %s ≈ 1 @ %s" (repGoal) (showRational targetWeight) (showRational (goalTo1RM repGoal)), |
115 | str $ printf "%d @ %s ≈ 1 @ %s" (repGoal + 1) (showRational targetWeight) (showRational (goalTo1RM $ repGoal + 1)) | 114 | str $ printf "%d @ %s ≈ 1 @ %s" (repGoal + 1) (showRational targetWeight) (showRational (goalTo1RM $ repGoal + 1)) |
116 | ] | 115 | ] |