diff --git a/inventory/migrations/0001_initial.py b/inventory/migrations/0001_initial.py index c061669..64ac64c 100644 --- a/inventory/migrations/0001_initial.py +++ b/inventory/migrations/0001_initial.py @@ -16,6 +16,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', auto_created=True, serialize=False, primary_key=True)), ('name', models.CharField(max_length=100)), ('weight_kg', models.DecimalField(max_digits=7, decimal_places=3)), + ('weight_lb', models.DecimalField(max_digits=7, decimal_places=3)), ], ), migrations.CreateModel( diff --git a/inventory/migrations/3000_initial_data.py b/inventory/migrations/3000_initial_data.py index 3b19093..bfb60eb 100644 --- a/inventory/migrations/3000_initial_data.py +++ b/inventory/migrations/3000_initial_data.py @@ -7,8 +7,8 @@ from django.db import models, migrations def make_bars(apps, schema_editor): Bar = apps.get_model('inventory', 'Bar') Bar.objects.bulk_create([ - Bar(id=1, name="Men's Olympic", weight_kg='20'), - Bar(id=2, name="Women's Olympic", weight_kg='15'), + Bar(id=1, name="Men's Olympic", weight_kg='20', weight_lb='45'), + Bar(id=2, name="Women's Olympic", weight_kg='15', weight_lb='35'), ]) diff --git a/inventory/models.py b/inventory/models.py index 578d0f4..ed2ced5 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -5,15 +5,12 @@ from common import remove_exponent, to_lb class Bar(models.Model): name = models.CharField(max_length=100) weight_kg = models.DecimalField(max_digits=7, decimal_places=3) + weight_lb = models.DecimalField(max_digits=7, decimal_places=3) def __str__(self): return '{} ({}kg / {}lb)'.format(self.name, remove_exponent(self.weight_kg), self.weight_lb) - @property - def weight_lb(self): - return to_lb(self.weight_kg) - class Lift(models.Model): name = models.CharField(max_length=200) diff --git a/lifting/models.py b/lifting/models.py index 099a506..207bbf7 100644 --- a/lifting/models.py +++ b/lifting/models.py @@ -1,3 +1,4 @@ +from decimal import Decimal from django.db import models from django.contrib.auth.models import User from django.contrib.postgres.fields import ArrayField @@ -22,6 +23,18 @@ class LiftingOptions(models.Model): plate_pairs = ArrayField(models.DecimalField(max_digits=7, decimal_places=3), default=['45','45','25','10','5','5','2.5','1.25']) + def plates_for_weight(self, weight): + side = [] + w = initial_weight = Decimal(weight) - self.default_bar.weight_lb + available = sorted(self.plate_pairs, reverse=True) + while w and available: + plate = available.pop(0) + if plate * 2 <= w: + w -= plate * 2 + side.append(plate) + if sum(side) * 2 != initial_weight: + raise ValueError('remaining weight {}'.format(initial_weight - sum(side) * 2)) + return side class Set(models.Model): user = models.ForeignKey(User, related_name='sets') diff --git a/lifting/tests.py b/lifting/tests.py index e6101e7..8844942 100644 --- a/lifting/tests.py +++ b/lifting/tests.py @@ -1,3 +1,4 @@ +from decimal import Decimal as D from django.test import TestCase from django.contrib.auth.models import User from lifting.models import LiftingOptions @@ -5,6 +6,30 @@ from lifting.models import LiftingOptions class TestLiftingOptions(TestCase): + def setUp(self): + self.user = User.objects.create_user(username='test', email='test@example.com', password='test') + def test_signal(self): - u = User.objects.create_user(username='test', email='test@example.com', password='test') - assert LiftingOptions.objects.filter(user=u).count() == 1 + assert LiftingOptions.objects.filter(user=self.user).count() == 1 + + def test_plates_for_weight(self): + opts = self.user.lifting_options + opts.plate_pairs = [D(45), D(45), D(25), D(10), D(5), D(5), D('2.5')] + opts.default_bar_id = 1 + + assert opts.plates_for_weight(45) == [] + assert opts.plates_for_weight(50) == [D('2.5')] + assert opts.plates_for_weight(90) == [D(10), D(5), D(5), D('2.5')] + assert opts.plates_for_weight(320) == [D(45), D(45), D(25), D(10), D(5), D(5), D('2.5')] + + def test_plates_for_weight_error(self): + opts = self.user.lifting_options + opts.plate_pairs = [D(45), D(45), D(25), D(10), D(5), D(5), D('2.5')] + opts.default_bar_id = 1 + # TODO: check amounts + with self.assertRaises(ValueError): + opts.plates_for_weight('47.5') + with self.assertRaises(ValueError): + opts.plates_for_weight(325) + with self.assertRaises(ValueError): + opts.plates_for_weight(30)