From 7bfa16c10a051757dfdc689be419e6a03791e321 Mon Sep 17 00:00:00 2001 From: James Turk Date: Tue, 15 Dec 2015 01:00:00 -0500 Subject: [PATCH] add old shaft files for reference, can delete them as they're used --- old-shaft-files/lifting/lifting_tags.py | 15 ++ old-shaft-files/lifting/models.py | 82 ++++++++++ old-shaft-files/lifting/plans.py | 31 ++++ old-shaft-files/lifting/tests.py | 147 ++++++++++++++++++ old-shaft-files/lifting/views.py | 56 +++++++ .../templates/lifting/_er-row.html | 24 +++ .../templates/lifting/_form-group.html | 7 + .../templates/lifting/edit_plan.html | 34 ++++ old-shaft-files/templates/lifting/plan.html | 33 ++++ .../templates/lifting/plan_edit.html | 54 +++++++ old-shaft-files/templates/lifting/plans.html | 36 +++++ old-shaft-files/templates/lifting/rules.html | 56 +++++++ 12 files changed, 575 insertions(+) create mode 100644 old-shaft-files/lifting/lifting_tags.py create mode 100644 old-shaft-files/lifting/models.py create mode 100644 old-shaft-files/lifting/plans.py create mode 100644 old-shaft-files/lifting/tests.py create mode 100644 old-shaft-files/lifting/views.py create mode 100644 old-shaft-files/templates/lifting/_er-row.html create mode 100644 old-shaft-files/templates/lifting/_form-group.html create mode 100644 old-shaft-files/templates/lifting/edit_plan.html create mode 100644 old-shaft-files/templates/lifting/plan.html create mode 100644 old-shaft-files/templates/lifting/plan_edit.html create mode 100644 old-shaft-files/templates/lifting/plans.html create mode 100644 old-shaft-files/templates/lifting/rules.html diff --git a/old-shaft-files/lifting/lifting_tags.py b/old-shaft-files/lifting/lifting_tags.py new file mode 100644 index 0000000..67dd1b6 --- /dev/null +++ b/old-shaft-files/lifting/lifting_tags.py @@ -0,0 +1,15 @@ +from django import template +from django.template.loader import render_to_string + +register = template.Library() + + +@register.filter +def formfield(value, arg): + if ',' in arg: + size, units = arg.split(',') + else: + size = arg + units = None + return render_to_string('lifting/_form-group.html', + {'field': value, 'size': size, 'units': units}) diff --git a/old-shaft-files/lifting/models.py b/old-shaft-files/lifting/models.py new file mode 100644 index 0000000..de49596 --- /dev/null +++ b/old-shaft-files/lifting/models.py @@ -0,0 +1,82 @@ + + +class Plan(models.Model): + name = models.CharField(max_length=100) + tags = models.ManyToManyField(PlanTag, related_name='plans') + public = models.BooleanField(default=False) + owner = models.ForeignKey(User, related_name='plans', null=True) + cloned_from = models.ForeignKey('self', null=True) + + objects = ByNameManager() + + def __str__(self): + return '{0}'.format(self.name) + + def get_absolute_url(self): + return reverse('lifting.views.plan', args=[str(self.id)]) + + def natural_key(self): + return (self.name,) + + def get_days(self, user): + exercise_rules = {} + days = [] + for day in self.days.all(): + day_sets = [] + for exercise in day.exercises.all(): + for reps in exercise.get_sets(): + rules = exercise_rules.setdefault(exercise.exercise, + exercise.exercise.rules.get(user=user)) + day_sets.append( + Set(exercise=exercise.exercise, + weight=round_to(rules.work_weight*exercise.percent, rules.increment), + reps=reps, + type='planned') + ) + if exercise.raise_weight: + rules.work_weight += rules.increment + days.append(day_sets) + return days + + +class PlanDay(models.Model): + plan = models.ForeignKey(Plan, related_name='days') + name = models.CharField(max_length=100) + order = models.PositiveIntegerField() + + def __str__(self): + return '{0}: {1}'.format(self.plan, self.name) + + class Meta: + ordering = ['order'] + + +class PlanExercise(models.Model): + plan_day = models.ForeignKey(PlanDay, related_name='exercises') + exercise = models.ForeignKey(Exercise) + order = models.PositiveIntegerField() + sets = models.CharField(max_length=100) + percent = models.DecimalField(max_digits=4, decimal_places=3, default=1) + raise_weight = models.BooleanField(default=False) + + def get_sets(self): + return [int(s) for s in self.sets.split(',')] + + def get_set_display(self): + sets = [] + last_reps = None + last_reps_num = 0 + for s in self.get_sets(): + if last_reps and s != last_reps: + sets.append('{0}x{1}'.format(last_reps_num, last_reps)) + last_reps_num = 0 + last_reps_num += 1 + last_reps = s + sets.append('{0}x{1}'.format(last_reps_num, last_reps)) + return ', '.join(sets) + + def get_percent_display(self): + return '{0:%}'.format(self.percent) + + class Meta: + ordering = ['order'] diff --git a/old-shaft-files/lifting/plans.py b/old-shaft-files/lifting/plans.py new file mode 100644 index 0000000..0365ddd --- /dev/null +++ b/old-shaft-files/lifting/plans.py @@ -0,0 +1,31 @@ +from decimal import Decimal as D +from .models import ExerciseRules, Set +from .utils import round_to + + +def warmup_ss(exercise, weight, user): + """ + Starting Strength Warmup + ======================== + (start)x5 x2 + (40%)x5 + (60%)x3 + (80%)x2 + """ + + # get relevant rules + rules, _ = ExerciseRules.objects.get_or_create(user=user, exercise=exercise) + start = rules.start_weight + + # empty bar sets + sets = [Set(exercise=exercise, weight=start, reps=5, type='warmup')]*2 + + if D('0.8')*weight < start: + return [] + + for reps, pct in ((5, D('0.4')), (3, D('0.6')), (2, D('0.8'))): + ww = round_to(weight * pct, D('5')) + if ww > start: + sets.append(Set(exercise=exercise, weight=ww, reps=reps, type='warmup')) + + return sets diff --git a/old-shaft-files/lifting/tests.py b/old-shaft-files/lifting/tests.py new file mode 100644 index 0000000..f695f67 --- /dev/null +++ b/old-shaft-files/lifting/tests.py @@ -0,0 +1,147 @@ +from decimal import Decimal as D +from django.test import TestCase +from django.contrib.auth.models import User +from .models import Exercise, UserSettings, ExerciseRules, Plan +from .plans import warmup_ss +from .utils import round_to + + +def _seteq(s1, exercise, weight, reps): + try: + assert s1.exercise == exercise + assert s1.weight == weight + assert s1.reps == reps + except AssertionError: + raise AssertionError('{0} != {1}x{2}'.format(s1, weight, reps)) + + + +class PlanTests(TestCase): + + def setUp(self): + self.user = User.objects.create_user(username='user') + self.squat = Exercise.objects.create(name='squat') + self.bench = Exercise.objects.create(name='bench press') + ExerciseRules.objects.create(user=self.user, exercise=self.squat, work_weight=200) + ExerciseRules.objects.create(user=self.user, exercise=self.bench, work_weight=100) + self.tm = Plan.objects.create(name='Texas Method') + + a1 = self.tm.days.create(name='A week - Volume day', order=1) + a1.exercises.create(exercise=self.squat, order=1, sets='5,5,5,5,5', percent=D('0.85')) + a1.exercises.create(exercise=self.bench, order=2, sets='5,5,5,5,5', percent=D('0.85')) + + a2 = self.tm.days.create(name='A week - Recovery day', order=2) + a2.exercises.create(exercise=self.squat, order=1, sets='5,5', percent=D('0.8')) + + # exaggerated raise_weight for tests + a3 = self.tm.days.create(name='A week - Record day', order=3) + a3.exercises.create(exercise=self.squat, order=1, sets='5', percent=D(1), + raise_weight=True) + a3.exercises.create(exercise=self.bench, order=2, sets='5', percent=D(1), + raise_weight=True) + + b1 = self.tm.days.create(name='B week - Volume day', order=4) + b1.exercises.create(exercise=self.squat, order=1, sets='5,5,5,5,5', percent=D('0.85')) + + b2 = self.tm.days.create(name='B week - Recovery day', order=5) + b2.exercises.create(exercise=self.squat, order=1, sets='5,5', percent=D('0.8')) + b2.exercises.create(exercise=self.bench, order=1, sets='5,5', percent=D('0.8')) + + b3 = self.tm.days.create(name='B week - Record day', order=6) + b3.exercises.create(exercise=self.squat, order=2, sets='5', percent=D(1)) + + def test_get_days(self): + a1, a2, a3, b1, b2, b3 = self.tm.get_days(self.user) + + _seteq(a1[0], self.squat, 170, 5) + _seteq(a1[1], self.squat, 170, 5) + _seteq(a1[2], self.squat, 170, 5) + _seteq(a1[3], self.squat, 170, 5) + _seteq(a1[4], self.squat, 170, 5) + _seteq(a1[5], self.bench, 85, 5) + _seteq(a1[6], self.bench, 85, 5) + _seteq(a1[7], self.bench, 85, 5) + _seteq(a1[8], self.bench, 85, 5) + _seteq(a1[9], self.bench, 85, 5) + + _seteq(a2[0], self.squat, 160, 5) + _seteq(a2[1], self.squat, 160, 5) + + _seteq(a3[0], self.squat, 200, 5) + _seteq(a3[1], self.bench, 100, 5) + + # b record day raised by 5 + _seteq(b3[0], self.squat, 205, 5) + + +class WarmupTests(TestCase): + + def setUp(self): + self.exercise = Exercise.objects.create(name='bench press') + self.user = User.objects.create_user(username='user') + + def test_round_to(self): + assert round_to(D('21'), D('2.5')) == D('20') + assert round_to(D('23'), D('2.5')) == D('22.5') + assert round_to(D('23'), D('5')) == D('20') + assert round_to(D('24.5'), D('2.5')) == D('22.5') + assert round_to(D('24.9'), D('5')) == D('25') + + def test_warmup_ss(self): + # <=55: no warmup + assert warmup_ss(self.exercise, D('10'), self.user) == [] + assert warmup_ss(self.exercise, D('55'), self.user) == [] + + # 60: just the bar + sets = warmup_ss(self.exercise, D('60'), self.user) + assert len(sets) == 2, sets + _seteq(sets[0], self.exercise, 45, 5) + _seteq(sets[1], self.exercise, 45, 5) + + sets = warmup_ss(self.exercise, D('70'), self.user) + _seteq(sets[0], self.exercise, 45, 5) + _seteq(sets[1], self.exercise, 45, 5) + _seteq(sets[2], self.exercise, 55, 2) + + sets = warmup_ss(self.exercise, D('95'), self.user) + _seteq(sets[0], self.exercise, 45, 5) + _seteq(sets[1], self.exercise, 45, 5) + _seteq(sets[2], self.exercise, 55, 3) + _seteq(sets[3], self.exercise, 75, 2) + + sets = warmup_ss(self.exercise, D('135'), self.user) + _seteq(sets[0], self.exercise, 45, 5) + _seteq(sets[1], self.exercise, 45, 5) + _seteq(sets[2], self.exercise, 50, 5) + _seteq(sets[3], self.exercise, 80, 3) + _seteq(sets[4], self.exercise, 105, 2) + + sets = warmup_ss(self.exercise, D('170'), self.user) + _seteq(sets[0], self.exercise, 45, 5) + _seteq(sets[1], self.exercise, 45, 5) + _seteq(sets[2], self.exercise, 65, 5) + _seteq(sets[3], self.exercise, 100, 3) + _seteq(sets[4], self.exercise, 135, 2) + + sets = warmup_ss(self.exercise, D('250'), self.user) + _seteq(sets[0], self.exercise, 45, 5) + _seteq(sets[1], self.exercise, 45, 5) + _seteq(sets[2], self.exercise, 100, 5) + _seteq(sets[3], self.exercise, 150, 3) + _seteq(sets[4], self.exercise, 200, 2) + + # slightly crazy jump + sets = warmup_ss(self.exercise, D('315'), self.user) + _seteq(sets[0], self.exercise, 45, 5) + _seteq(sets[1], self.exercise, 45, 5) + _seteq(sets[2], self.exercise, 125, 5) + _seteq(sets[3], self.exercise, 185, 3) + _seteq(sets[4], self.exercise, 250, 2) + + # this is probably crazy & should be fixed + sets = warmup_ss(self.exercise, D('500'), self.user) + _seteq(sets[0], self.exercise, 45, 5) + _seteq(sets[1], self.exercise, 45, 5) + _seteq(sets[2], self.exercise, 200, 5) + _seteq(sets[3], self.exercise, 300, 3) + _seteq(sets[4], self.exercise, 400, 2) diff --git a/old-shaft-files/lifting/views.py b/old-shaft-files/lifting/views.py new file mode 100644 index 0000000..e0a3ab9 --- /dev/null +++ b/old-shaft-files/lifting/views.py @@ -0,0 +1,56 @@ +from decimal import Decimal as D +from django.shortcuts import render, get_object_or_404 +from django.views.decorators.http import require_http_methods, require_GET +from django.contrib.auth.decorators import login_required +from .models import UserSettings, ExerciseRules, Exercise, Plan +from .forms import UserSettingsForm, PlanForm + + + +@require_http_methods(["GET", "POST"]) +@login_required +def plan_edit(request, id): + """ edit details of a plan """ + plan = get_object_or_404(Plan, pk=id) + exercises = Exercise.objects.all() + if request.method == 'GET': + pform = PlanForm(instance=plan) + return render(request, 'lifting/plan_edit.html', + {'pform': pform, 'plan': plan, 'exercises': exercises}) + + +@require_http_methods(["GET", "POST"]) +@login_required +def rules(request): + """ a view that allows a user to view/edit their list of rules """ + gr, _ = UserSettings.objects.get_or_create(user=request.user) + ers = list(ExerciseRules.objects.filter(user=request.user)) + exercises = Exercise.objects.exclude(id__in=[er.exercise_id for er in ers]) + if request.method == 'GET': + grform = UserSettingsForm(instance=gr) + elif request.method == 'POST': + grform = UserSettingsForm(request.POST, instance=gr) + if grform.is_valid(): + grform.save() + for exercise, start, inc, work in zip(request.POST.getlist('er.exercise'), + request.POST.getlist('er.start_weight'), + request.POST.getlist('er.increment'), + request.POST.getlist('er.work_weight')): + exercise = int(exercise) + start = D(start) + inc = D(inc) + work = D(work) + + er, _ = ExerciseRules.objects.get_or_create(user=request.user, + exercise_id=int(exercise)) + er.start_weight = start + er.increment = inc + er.work_weight = work + er.save() + return render(request, 'lifting/rules.html', + {'grform': grform, 'exercise_rules': ers, 'exercises': exercises, }) + + +def er_row(request, eid): + return render(request, 'lifting/_er-row.html', + {'er': ExerciseRules(user=request.user, exercise=Exercise.objects.get(pk=eid))}) diff --git a/old-shaft-files/templates/lifting/_er-row.html b/old-shaft-files/templates/lifting/_er-row.html new file mode 100644 index 0000000..cdc2b5a --- /dev/null +++ b/old-shaft-files/templates/lifting/_er-row.html @@ -0,0 +1,24 @@ + + + + {{er.exercise}} + + +
+ + lbs +
+ + +
+ + lbs +
+ + +
+ + lbs +
+ + diff --git a/old-shaft-files/templates/lifting/_form-group.html b/old-shaft-files/templates/lifting/_form-group.html new file mode 100644 index 0000000..920ab89 --- /dev/null +++ b/old-shaft-files/templates/lifting/_form-group.html @@ -0,0 +1,7 @@ +
+ +
+ + {% if units %}{{units}}{% endif %} +
+
diff --git a/old-shaft-files/templates/lifting/edit_plan.html b/old-shaft-files/templates/lifting/edit_plan.html new file mode 100644 index 0000000..4409486 --- /dev/null +++ b/old-shaft-files/templates/lifting/edit_plan.html @@ -0,0 +1,34 @@ +{% extends "lifting/base.html" %} +{% load lifting %} + +{% block content %} + + +
+ {% for day in plan.days.all %} +
+ + {{day.name}} + + + + + + {% for e in day.exercises.all %} + + + + + + {% endfor %} + +
ExerciseSetsPercent
{{e.exercise}}{{e.get_set_display}}{{e.get_percent_display}}
+
+ {% endfor %} +
+{% endblock %} + +{% block script %} + +{% endblock %} diff --git a/old-shaft-files/templates/lifting/plan.html b/old-shaft-files/templates/lifting/plan.html new file mode 100644 index 0000000..98ee4b0 --- /dev/null +++ b/old-shaft-files/templates/lifting/plan.html @@ -0,0 +1,33 @@ +{% extends "lifting/base.html" %} +{% load lifting %} + +{% block content %} +

{{plan}}

+ +
+ {% for day in plan.days.all %} +
+

{{day.name}}

+ + + + + + {% for e in day.exercises.all %} + + + + + + {% endfor %} + +
ExerciseSetsPercent
{{e.exercise}}{{e.get_set_display}}{{e.get_percent_display}}
+
+ {% endfor %} +
+{% endblock %} + +{% block script %} + +{% endblock %} diff --git a/old-shaft-files/templates/lifting/plan_edit.html b/old-shaft-files/templates/lifting/plan_edit.html new file mode 100644 index 0000000..61b77e8 --- /dev/null +++ b/old-shaft-files/templates/lifting/plan_edit.html @@ -0,0 +1,54 @@ +{% extends "lifting/base.html" %} +{% load lifting %} + +{% block content %} + +
+ +{{pform.name|formfield:"3"}} +{{pform.tags|formfield:"5"}} + +
+ +
+ {% for day in plan.days.all %} +
+
+ +
+ +
+
+
+
+ + + + + + {% for e in day.exercises.all %} + + + + + + {% endfor %} + +
ExerciseSetsPercent
+ + {{e.get_set_display}}{{e.get_percent_display}}
+
+ {% endfor %} +
+ +
+{% endblock %} + +{% block script %} + +{% endblock %} diff --git a/old-shaft-files/templates/lifting/plans.html b/old-shaft-files/templates/lifting/plans.html new file mode 100644 index 0000000..8d8a525 --- /dev/null +++ b/old-shaft-files/templates/lifting/plans.html @@ -0,0 +1,36 @@ +{% extends "lifting/base.html" %} +{% load lifting %} + +{% block content %} + + + + + + + + + + + + {% for plan in plans %} + + + + + + + + {% endfor %} + +
PlanTagsPopularity  
{{plan}} + {% for tag in plan.tags.all %} + {{tag.name}} + {% endfor %} + {{plan.popularity}}cloneuse plan
+{% endblock content %} + +{% block script %} + +{% endblock %} diff --git a/old-shaft-files/templates/lifting/rules.html b/old-shaft-files/templates/lifting/rules.html new file mode 100644 index 0000000..3dbbe57 --- /dev/null +++ b/old-shaft-files/templates/lifting/rules.html @@ -0,0 +1,56 @@ +{% extends "lifting/base.html" %} +{% load lifting %} + +{% block content %} +
+ {% csrf_token %} +

Global Settings

+ {{grform.bar|formfield:"2,lbs"}} + {{grform.plates|formfield:"3,lbs"}} +
+

Exercise Settings

+ + + + + + + + + + + {% for er in exercise_rules %} + {% include "lifting/_er-row.html" %} + {% endfor %} + +
ExerciseStart WeightIncrementWorking Weight
+
+
+
+ +
+
+ +
+
+ +
+{% endblock content %} + +{% block script %} + +{% endblock %}