Commit f913790

mo khan <mo@mokhan.ca>
2016-06-30 05:11:38
use WarmUp model to calculate warm up sets.
1 parent a6a5f83
app/models/user_recommendation.rb
@@ -9,19 +9,11 @@ class UserRecommendation
 
   def prepare_sets
     target_weight = next_weight
-    warm_up_sets = []
-    if target_weight >= 65.lbs
-      warm_up_sets << warm_up(45.lbs, 5)
-      warm_up_sets << warm_up(45.lbs, 5)
-    end
-    warm_up_sets << warm_up(65.lbs, 3) if target_weight >= 95.lbs
-    warm_up_sets << warm_up(75.lbs, 3) if target_weight >= 105.lbs
-    warm_up_sets << warm_up(85.lbs, 3) if target_weight >= 125.lbs
-    warm_up_sets << warm_up(95.lbs, 5) if target_weight >= 135.lbs
+    warm_up = WarmUp.calculate_for(exercise, target_weight)
     work_sets = recommended_sets.times.map do
       work_set(target_weight, repetitions)
     end
-    (warm_up_sets + work_sets).compact
+    (warm_up.sets + work_sets).compact
   end
 
   def repetitions
app/models/warm_up.rb
@@ -0,0 +1,360 @@
+class WarmUp
+  DEADLIFT_INCREMENT_THRESHOLD_LB=220.0
+  attr_reader :exercise, :sets
+
+  def initialize(exercise)
+    @sets = []
+    @exercise = exercise
+  end
+
+  def add_set(weight, repetitions)
+    @sets << ExerciseSet.new(
+      type: :warm_up,
+      exercise: exercise,
+      target_weight: weight,
+      target_repetitions: repetitions,
+    )
+    self
+  end
+
+  def self.calculate_for(exercise, target_weight)
+    if exercise.name == "Deadlift"
+      return dead_lift_warmup(exercise, target_weight)
+    end
+
+    if exercise.name == "Barbell Row"
+      return barbell_row_warmup(exercise, target_weight)
+    end
+
+    return default_warmup(exercise, target_weight)
+  end
+
+  def self.dead_lift_warmup(exercise, target_weight)
+    warmup = WarmUp.new(exercise)
+    if (target_weight < 155.0)
+      return warmup
+    end
+    if (target_weight < 175.0)
+      return warmup.add_set(135.0, 5)
+    end
+    warmup.add_set(135.0, 5)
+    if (target_weight < 200.0)
+      return warmup.add_set(165.0, 5)
+    end
+    if (target_weight < DEADLIFT_INCREMENT_THRESHOLD_LB)
+      return warmup.add_set(175.0, 5)
+    end
+    if (target_weight < 225.0)
+      return warmup.add_set(185.0, 5)
+    end
+    warmup.add_set(185.0, 5)
+    if (target_weight < 240.0)
+      return warmup.add_set(205.0, 5)
+    end
+    if (target_weight < 250.0)
+      return warmup.add_set(215.0, 5)
+    end
+    if (target_weight < 270.0)
+      return warmup.add_set(225.0, 5)
+    end
+    warmup.add_set(225.0, 5)
+    if (target_weight < 275.0)
+      return warmup.add_set(245.0, 5)
+    end
+    if (target_weight < 290.0)
+      return warmup.add_set(255.0, 5)
+    end
+    if (target_weight < 301.0)
+      return warmup.add_set(265.0, 5)
+    end
+    warmup.add_set(265.0, 3)
+    if (target_weight < 320.0)
+      return warmup.add_set(285.0, 1)
+    end
+    if (target_weight < 330.0)
+      return warmup.add_set(295.0, 1)
+    end
+    if (target_weight < 340.0)
+      return warmup.add_set(305.0, 1)
+    end
+    if (target_weight < 350.0)
+      return warmup.add_set(315.0, 1)
+    end
+    warmup.add_set(315.0, 3)
+    if (target_weight < 360.0)
+      return warmup.add_set(335.0, 1)
+    end
+    if (target_weight < 370.0)
+      return warmup.add_set(340.0, 1)
+    end
+    if (target_weight < 380.0)
+      return warmup.add_set(345.0, 1)
+    end
+    if (target_weight < 390.0)
+      return warmup.add_set(350.0, 1)
+    end
+    if (target_weight < 395.0)
+      return warmup.add_set(355.0, 1)
+    end
+    if (target_weight < 400.0)
+      return warmup.add_set(360.0, 1)
+    end
+    return warmup.add_set(365.0, 1)
+  end
+
+  def self.barbell_row_warmup(exercise, target_weight)
+    warmup = WarmUp.new(exercise)
+    i = 3
+    barbellRow = exercise.name == "Barbell Row" ? 1 : 0
+    if ((barbellRow != 0 && target_weight < 105.0) || target_weight < 65.0)
+      return warmup
+    end
+    if (barbellRow != 0 && target_weight < 145.0)
+      return warmup.add_set(95.0, 5)
+    end
+    if (barbellRow == 0)
+      warmup.add_set(45.0, 5)
+      warmup.add_set(45.0, 5)
+      if (target_weight < 95.0)
+        return warmup
+      end
+    end
+    if (barbellRow != 0 && target_weight < 160.0)
+      return warmup.add_set(115.0, 5)
+    end
+    if (target_weight < 105.0)
+      return warmup.add_set(65.0, 3)
+    end
+    if (target_weight < 125.0)
+      return warmup.add_set(75.0, 3)
+    end
+    if (target_weight < 135.0)
+      return warmup.add_set(85.0, 3)
+    end
+    if (barbellRow == 0)
+      warmup.add_set(95.0, 5)
+      if (target_weight < 150.0)
+        return warmup.add_set(115.0, 3)
+      end
+      if (target_weight < 160.0)
+        return warmup.add_set(125.0, 3)
+      end
+      if (target_weight < 185.0)
+        return warmup.add_set(135.0, 3)
+      end
+    end
+    if (target_weight < 185.0)
+      return warmup.add_set(135.0, 3)
+    end
+    warmup.add_set(135.0, 5)
+    if (target_weight < 200.0)
+      return warmup.add_set(165.0, 3)
+    end
+    if (target_weight < DEADLIFT_INCREMENT_THRESHOLD_LB)
+      return warmup.add_set(175.0, 3)
+    end
+    if (target_weight < 225.0)
+      return warmup.add_set(185.0, 3)
+    end
+    if (barbellRow != 0)
+      warmup.add_set(185.0, 5)
+    else
+      warmup.add_set(185.0, target_weight < 305.0 ? 3 : 5)
+    end
+    if (target_weight < 240.0)
+      return warmup.add_set(205.0, 2)
+    end
+    if (target_weight < 250.0)
+      return warmup.add_set(215.0, 2)
+    end
+    if (target_weight < 270.0)
+      return warmup.add_set(225.0, 2)
+    end
+    if (barbellRow != 0)
+      warmup.add_set(225.0, 5)
+    else
+      warmup.add_set(225.0, target_weight < 305.0 ? 2 : 3)
+    end
+    if (target_weight < 275.0)
+      return warmup.add_set(245.0, 1)
+    end
+    if (target_weight < 290.0)
+      return warmup.add_set(255.0, 1)
+    end
+    if (target_weight < 301.0)
+      return warmup.add_set(265.0, 1)
+    end
+    if (barbellRow != 0)
+      warmup.add_set(265.0, 3)
+    elsif (target_weight < 305.0)
+      warmup.add_set(265.0, 1)
+    elsif (target_weight < 350.0)
+      warmup.add_set(265.0, 2)
+    else
+      warmup.add_set(265.0, 3)
+    end
+    if (target_weight < 320.0)
+      return warmup.add_set(285.0, 1)
+    end
+    if (target_weight < 330.0)
+      return warmup.add_set(295.0, 1)
+    end
+    if (target_weight < 340.0)
+      return warmup.add_set(305.0, 1)
+    end
+    if (target_weight < 350.0)
+      return warmup.add_set(315.0, 1)
+    end
+    if (barbellRow == 0)
+      i = 2
+    end
+    warmup.add_set(315.0, i)
+    if (target_weight < 355.0)
+      return warmup.add_set(330.0, 1)
+    end
+    if (target_weight < 370.0)
+      return warmup.add_set(340.0, 1)
+    end
+    if (target_weight < 380.0)
+      return warmup.add_set(345.0, 1)
+    end
+    if (target_weight < 390.0)
+      return warmup.add_set(350.0, 1)
+    end
+    if (target_weight < 395.0)
+      return warmup.add_set(355.0, 1)
+    end
+    if (target_weight < 400.0)
+      return warmup.add_set(360.0, 1)
+    end
+    return warmup.add_set(365.0, 1)
+  end
+
+  def self.default_warmup(exercise, target_weight)
+    warmup = WarmUp.new(exercise)
+    i = 3
+    barbellRow = exercise.name == "Barbell Row" ? 1 : 0
+    if ((barbellRow != 0 && target_weight < 105.0) || target_weight < 65.0)
+      return warmup
+    end
+    if (barbellRow != 0 && target_weight < 145.0)
+      return warmup.add_set(95.0, 5)
+    end
+    if (barbellRow == 0)
+      warmup.add_set(45.0, 5)
+      warmup.add_set(45.0, 5)
+      if (target_weight < 95.0)
+        return warmup
+      end
+    end
+    if (barbellRow != 0 && target_weight < 160.0)
+      return warmup.add_set(115.0, 5)
+    end
+    if (target_weight < 105.0)
+      return warmup.add_set(65.0, 3)
+    end
+    if (target_weight < 125.0)
+      return warmup.add_set(75.0, 3)
+    end
+    if (target_weight < 135.0)
+      return warmup.add_set(85.0, 3)
+    end
+    if (barbellRow == 0)
+      warmup.add_set(95.0, 5)
+      if (target_weight < 150.0)
+        return warmup.add_set(115.0, 3)
+      end
+      if (target_weight < 160.0)
+        return warmup.add_set(125.0, 3)
+      end
+      if (target_weight < 185.0)
+        return warmup.add_set(135.0, 3)
+      end
+    end
+    if (target_weight < 185.0)
+      return warmup.add_set(135.0, 3)
+    end
+    warmup.add_set(135.0, 5)
+    if (target_weight < 200.0)
+      return warmup.add_set(165.0, 3)
+    end
+    if (target_weight < DEADLIFT_INCREMENT_THRESHOLD_LB)
+      return warmup.add_set(175.0, 3)
+    end
+    if (target_weight < 225.0)
+      return warmup.add_set(185.0, 3)
+    end
+    if (barbellRow != 0)
+      warmup.add_set(185.0, 5)
+    else
+      warmup.add_set(185.0, target_weight < 305.0 ? 3 : 5)
+    end
+    if (target_weight < 240.0)
+      return warmup.add_set(205.0, 2)
+    end
+    if (target_weight < 250.0)
+      return warmup.add_set(215.0, 2)
+    end
+    if (target_weight < 270.0)
+      return warmup.add_set(225.0, 2)
+    end
+    if (barbellRow != 0)
+      warmup.add_set(225.0, 5)
+    else
+      warmup.add_set(225.0, target_weight < 305.0 ? 2 : 3)
+    end
+    if (target_weight < 275.0)
+      return warmup.add_set(245.0, 1)
+    end
+    if (target_weight < 290.0)
+      return warmup.add_set(255.0, 1)
+    end
+    if (target_weight < 301.0)
+      return warmup.add_set(265.0, 1)
+    end
+    if (barbellRow != 0)
+      warmup.add_set(265.0, 3)
+    elsif (target_weight < 305.0)
+      warmup.add_set(265.0, 1)
+    elsif (target_weight < 350.0)
+      warmup.add_set(265.0, 2)
+    else
+      warmup.add_set(265.0, 3)
+    end
+    if (target_weight < 320.0)
+      return warmup.add_set(285.0, 1)
+    end
+    if (target_weight < 330.0)
+      return warmup.add_set(295.0, 1)
+    end
+    if (target_weight < 340.0)
+      return warmup.add_set(305.0, 1)
+    end
+    if (target_weight < 350.0)
+      return warmup.add_set(315.0, 1)
+    end
+    if (barbellRow == 0)
+      i = 2
+    end
+    warmup.add_set(315.0, i)
+    if (target_weight < 355.0)
+      return warmup.add_set(330.0, 1)
+    end
+    if (target_weight < 370.0)
+      return warmup.add_set(340.0, 1)
+    end
+    if (target_weight < 380.0)
+      return warmup.add_set(345.0, 1)
+    end
+    if (target_weight < 390.0)
+      return warmup.add_set(350.0, 1)
+    end
+    if (target_weight < 395.0)
+      return warmup.add_set(355.0, 1)
+    end
+    if (target_weight < 400.0)
+      return warmup.add_set(360.0, 1)
+    end
+    return warmup.add_set(365.0, 1)
+  end
+end
spec/models/program_spec.rb
@@ -106,11 +106,10 @@ describe Program do
             workout = create(:workout, user: user, routine: routine_a)
             5.times { |n| workout.train(squat, 105, repetitions: 5) }
 
-            sets = subject.prepare_sets_for(user, squat)
-            warmup_sets = sets.find_all { |x| x.warm_up? }
-            expect(warmup_sets.length).to eql(4)
-            expect(warmup_sets.at(3).target_weight.lbs).to eql(75.lbs)
-            expect(warmup_sets.at(3).target_repetitions).to eql(3)
+            warmup_sets = subject.prepare_sets_for(user, squat).find_all { |x| x.warm_up? }
+            expect(warmup_sets.length).to eql(3)
+            expect(warmup_sets.last.target_weight.lbs).to eql(75.lbs)
+            expect(warmup_sets.last.target_repetitions).to eql(3)
           end
         end
 
@@ -119,11 +118,10 @@ describe Program do
             workout = create(:workout, user: user, routine: routine_a)
             5.times { |n| workout.train(squat, 125, repetitions: 5) }
 
-            sets = subject.prepare_sets_for(user, squat)
-            warmup_sets = sets.find_all { |x| x.warm_up? }
-            expect(warmup_sets.length).to eql(5)
-            expect(warmup_sets.at(4).target_weight.lbs).to eql(85.lbs)
-            expect(warmup_sets.at(4).target_repetitions).to eql(3)
+            warmup_sets = subject.prepare_sets_for(user, squat).find_all { |x| x.warm_up? }
+            expect(warmup_sets.length).to eql(3)
+            expect(warmup_sets.last.target_weight.lbs).to eql(85.lbs)
+            expect(warmup_sets.last.target_repetitions).to eql(3)
           end
         end
 
@@ -132,11 +130,10 @@ describe Program do
             workout = create(:workout, user: user, routine: routine_a)
             5.times { |n| workout.train(squat, 135, repetitions: 5) }
 
-            sets = subject.prepare_sets_for(user, squat)
-            warmup_sets = sets.find_all { |x| x.warm_up? }
-            expect(warmup_sets.length).to eql(6)
-            expect(warmup_sets.at(5).target_weight.lbs).to eql(95.lbs)
-            expect(warmup_sets.at(5).target_repetitions).to eql(5)
+            warmup_sets = subject.prepare_sets_for(user, squat).find_all { |x| x.warm_up? }
+            expect(warmup_sets.length).to eql(4)
+            expect(warmup_sets.last.target_weight.lbs).to eql(115.lbs)
+            expect(warmup_sets.last.target_repetitions).to eql(3)
           end
         end
       end
spec/models/warm_up_spec.rb
@@ -0,0 +1,102 @@
+require 'rails_helper'
+
+describe WarmUp do
+  describe ".calculate_for" do
+
+    describe "squat" do
+      let(:squat) { build(:exercise, name: 'Squat') }
+
+      (45..60).step(5).each do |target_weight|
+        it "has zero warm up sets" do
+          expect(WarmUp.calculate_for(squat, target_weight).sets).to be_empty
+        end
+      end
+
+      (65..400).step(5).each do |target_weight|
+        it "calculates the warm up sets at #{target_weight} lbs" do
+          sets = WarmUp.calculate_for(squat, target_weight).sets
+          expect(sets).to be_present
+          if target_weight >= 350
+            expect(sets.length).to eql(9)
+          elsif target_weight > 300
+            expect(sets.length).to eql(8)
+          elsif target_weight > 265
+            expect(sets.length).to eql(7)
+          elsif target_weight > 220
+            expect(sets.length).to eql(6)
+          elsif target_weight > 180
+            expect(sets.length).to eql(5)
+          elsif target_weight > 130
+            expect(sets.length).to eql(4)
+          elsif target_weight > 90
+            expect(sets.length).to eql(3)
+          elsif target_weight > 60
+            expect(sets.length).to eql(2)
+          end
+        end
+      end
+    end
+
+    describe "barbell row" do
+      let(:barbell_row) { build(:exercise, name: 'Barbell Row') }
+
+      (45..100).step(5).each do |target_weight|
+        it "has zero warm up sets" do
+          expect(WarmUp.calculate_for(barbell_row, target_weight).sets).to be_empty
+        end
+      end
+
+      (105..400).step(5).each do |target_weight|
+        it "calculates the warm up sets for #{target_weight} lbs" do
+          sets = WarmUp.calculate_for(barbell_row, target_weight).sets
+          expect(sets).to be_present
+          if target_weight >= 350
+            expect(sets.length).to eql(6)
+          elsif target_weight > 300
+            expect(sets.length).to eql(5)
+          elsif target_weight > 265
+            expect(sets.length).to eql(4)
+          elsif target_weight > 220
+            expect(sets.length).to eql(3)
+          elsif target_weight > 180
+            expect(sets.length).to eql(2)
+          elsif target_weight > 100
+            expect(sets.length).to eql(1)
+          end
+        end
+      end
+    end
+
+    describe "deadlift" do
+      let(:deadlift) { build(:exercise, name: 'Deadlift') }
+
+      (45..150).step(5).each do |target_weight|
+        it "has zero warm up sets at #{target_weight} lbs" do
+          expect(WarmUp.calculate_for(deadlift, target_weight).sets).to be_empty
+        end
+      end
+
+      (155..400).step(5).each do |target_weight|
+        it "calculates the warm up sets for #{target_weight} lbs" do
+          sets = WarmUp.calculate_for(deadlift, target_weight).sets
+          expect(sets).to be_present
+          if target_weight >= 350
+            expect(sets.length).to eql(6)
+          elsif target_weight > 300
+            expect(sets.length).to eql(5)
+          elsif target_weight > 265
+            expect(sets.length).to eql(4)
+          elsif target_weight > 220
+            expect(sets.length).to eql(3)
+          elsif target_weight > 170
+            expect(sets.length).to eql(2)
+          elsif target_weight > 100
+            expect(sets.length).to eql(1)
+          else
+            puts [target_weight, sets.map(&:target_weight)].inspect
+          end
+        end
+      end
+    end
+  end
+end