add old shaft files for reference, can delete them as they're used

This commit is contained in:
James Turk 2015-12-15 01:00:00 -05:00
parent e23b136b3a
commit 7bfa16c10a
12 changed files with 575 additions and 0 deletions

View File

@ -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})

View File

@ -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']

View File

@ -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

View File

@ -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)

View File

@ -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))})

View File

@ -0,0 +1,24 @@
<tr>
<input type="hidden" name="er.exercise" value="{{er.exercise.id}}" />
<td class="col-md-3">
{{er.exercise}}
</td>
<td class="col-md-2">
<div class="input-group">
<input type="text" class="form-control" name="er.start_weight" value="{{er.start_weight}}" />
<span class="input-group-addon">lbs</span>
</div>
</td>
<td class="col-md-2">
<div class="input-group">
<input type="text" class="form-control" name="er.increment" value="{{er.increment}}" />
<span class="input-group-addon">lbs</span>
</div>
</td>
<td class="col-md-2">
<div class="input-group">
<input type="text" class="form-control" name="er.work_weight" value="{{er.work_weight}}" />
<span class="input-group-addon">lbs</span>
</div>
</td>
</tr>

View File

@ -0,0 +1,7 @@
<div class="form-group {% if field.errors %}has-error{% endif %}">
<label class="col-md-2 control-label" for="{{field.id_for_label}}">{{field.label}}: </label>
<div class="col-md-{{size}}{% if units %}input-group{% endif %}">
<input type="text" class="form-control" id="{{field.id_for_label}}" name="{{field.html_name}}" value="{{field.value}}" />
{% if units %}<span class="input-group-addon">{{units}}</span>{% endif %}
</div>
</div>

View File

@ -0,0 +1,34 @@
{% extends "lifting/base.html" %}
{% load lifting %}
{% block content %}
<input type="text" name="plan.name">
<div class="row">
{% for day in plan.days.all %}
<div class="col-md-4">
<input type="day.name">
{{day.name}}
<table class="table">
<thead>
<th>Exercise</th><th>Sets</th><th>Percent</th>
</thead>
<tbody>
{% for e in day.exercises.all %}
<tr>
<td>{{e.exercise}}</td>
<td>{{e.get_set_display}}</td>
<td>{{e.get_percent_display}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</div>
{% endblock %}
{% block script %}
<script>
</script>
{% endblock %}

View File

@ -0,0 +1,33 @@
{% extends "lifting/base.html" %}
{% load lifting %}
{% block content %}
<h2>{{plan}}</h2>
<div class="row">
{% for day in plan.days.all %}
<div class="col-md-4">
<h4>{{day.name}}</h4>
<table class="table">
<thead>
<th>Exercise</th><th>Sets</th><th>Percent</th>
</thead>
<tbody>
{% for e in day.exercises.all %}
<tr>
<td>{{e.exercise}}</td>
<td>{{e.get_set_display}}</td>
<td>{{e.get_percent_display}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</div>
{% endblock %}
{% block script %}
<script>
</script>
{% endblock %}

View File

@ -0,0 +1,54 @@
{% extends "lifting/base.html" %}
{% load lifting %}
{% block content %}
<form class="form-horizontal" method="POST">
{{pform.name|formfield:"3"}}
{{pform.tags|formfield:"5"}}
<hr>
<div class="row">
{% for day in plan.days.all %}
<div class="col-md-6">
<div class="form-group">
<label class="col-md-2 control-label" for="day.name">Day: </label>
<div class="col-md-9">
<input type="text" class="form-control" id="day.name" name="day.name" value="{{day.name}}" />
</div>
</div>
</div>
<div class="col-md-6">
<table class="table">
<thead>
<th>Exercise</th><th>Sets</th><th>Percent</th>
</thead>
<tbody>
{% for e in day.exercises.all %}
<tr>
<td>
<select id="new-exercise" class="form-control">
{% for exercise in exercises %}
<option value="{{exercise.id}}" {% if e.exercise_id == exercise.id %}selected{% endif %}>{{exercise}}</option>
{% endfor %}
</select>
</td>
<td>{{e.get_set_display}}</td>
<td>{{e.get_percent_display}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</div>
</form>
{% endblock %}
{% block script %}
<script>
</script>
{% endblock %}

View File

@ -0,0 +1,36 @@
{% extends "lifting/base.html" %}
{% load lifting %}
{% block content %}
<table class="table">
<thead>
<tr>
<th>Plan</th>
<th>Tags</th>
<th>Popularity</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody id="exercise-rules">
{% for plan in plans %}
<tr>
<td><a href="{{plan.get_absolute_url}}">{{plan}}</a></td>
<td>
{% for tag in plan.tags.all %}
<span style="background-color: #{{tag.color}};" class="label">{{tag.name}}</span>
{% endfor %}
</td>
<td>{{plan.popularity}}</td>
<td>clone</td>
<td>use plan</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock content %}
{% block script %}
<script>
</script>
{% endblock %}

View File

@ -0,0 +1,56 @@
{% extends "lifting/base.html" %}
{% load lifting %}
{% block content %}
<form class="form-horizontal" method="POST">
{% csrf_token %}
<h3>Global Settings</h3>
{{grform.bar|formfield:"2,lbs"}}
{{grform.plates|formfield:"3,lbs"}}
<hr>
<h3>Exercise Settings</h3>
<table class="table">
<thead>
<tr>
<th>Exercise</th>
<th>Start Weight</th>
<th>Increment</th>
<th>Working Weight</th>
</tr>
</thead>
<tbody id="exercise-rules">
{% for er in exercise_rules %}
{% include "lifting/_er-row.html" %}
{% endfor %}
</tbody>
</table>
<hr>
<div class="form-group">
<div class="col-md-2">
<button id="add-exercise" type="button" class="btn">Add Exercise: </button>
</div>
<div class="col-md-5">
<select id="new-exercise" class="form-control">
{% for exercise in exercises %}
<option value="{{exercise.id}}">{{exercise}}</option>
{% endfor %}
</select>
</div>
</div>
<button type="submit" class="btn btn-primary">Save Settings</button>
</form>
{% endblock content %}
{% block script %}
<script>
$(function() {
$('#add-exercise').click(function() {
var val = $('#new-exercise').val();
$.get('/_er-row/' + val + '/', function(data) {
$('#exercise-rules').append(data);
$('#new-exercise > option[value=' + val + ']').remove();
});
});
});
</script>
{% endblock %}