base unit conversions

This commit is contained in:
vabene1111
2023-03-15 17:30:23 +01:00
parent 27c5749b21
commit 6efe4ab08d
4 changed files with 92 additions and 29 deletions

View File

@ -1,51 +1,70 @@
from pint import UnitRegistry, UndefinedUnitError
from pint import UnitRegistry, UndefinedUnitError, PintError
from cookbook.models import Ingredient, Unit
CONVERT_TO_UNITS = {
'metric': ['g', 'kg', 'ml', 'l'],
'us': ['ounce', 'pound', 'fluid_ounce', 'pint', 'quart', 'gallon'],
'uk': ['ounce', 'pound', 'imperial_fluid_ounce', 'imperial_pint', 'imperial_quart', 'imperial_gallon'],
}
def base_conversions(ingredient_list):
ingredient_list = [{'amount': 1, 'unit': 'g'}, {'amount': 1, 'unit': 'Gramm'}, {'amount': 1, 'unit': 'Stück'}]
ureg = UnitRegistry()
pint_converted_list = []
pint_converted_list = ingredient_list.copy()
for i in ingredient_list:
try:
pint_converted_list.append(ureg.Quantity(f'{i["amount"]} {i["unit"]}'))
except UndefinedUnitError:
conversion_unit = i.unit.name
if i.unit.base_unit:
conversion_unit = i.unit.base_unit
quantitiy = ureg.Quantity(f'{i.amount} {conversion_unit}')
for u in CONVERT_TO_UNITS['metric'] + CONVERT_TO_UNITS['us'] + CONVERT_TO_UNITS['uk']:
converted = quantitiy.to(u)
ingredient = Ingredient(amount=converted.m, unit=Unit(name=str(converted.units)), food=ingredient_list[0].food, )
if not any(x.unit.name == ingredient.unit.name for x in pint_converted_list):
pint_converted_list.append(ingredient)
except PintError:
pass
print(pint_converted_list)
return pint_converted_list
def get_conversions(amount, unit, food):
conversions = []
if unit:
for c in unit.unit_conversion_base_relation.all():
r = _uc_convert(c, amount, unit, food)
def get_conversions(ingredient):
conversions = [ingredient]
if ingredient.unit:
for c in ingredient.unit.unit_conversion_base_relation.all():
r = _uc_convert(c, ingredient.amount, ingredient.unit, ingredient.food)
if r not in conversions:
conversions.append(r)
for c in unit.unit_conversion_converted_relation.all():
r = _uc_convert(c, amount, unit, food)
for c in ingredient.unit.unit_conversion_converted_relation.all():
r = _uc_convert(c, ingredient.amount, ingredient.unit, ingredient.food)
if r not in conversions:
conversions.append(r)
conversions += base_conversions(conversions)
return conversions
def _uc_convert(uc, amount, unit, food):
if uc.food is None or uc.food == food:
if unit == uc.base_unit:
return {
'amount': amount * (uc.converted_amount / uc.base_amount),
'unit': {
'id': uc.converted_unit.id,
'name': uc.converted_unit.name,
'plural_name': uc.converted_unit.plural_name
},
}
return Ingredient(amount=amount * (uc.converted_amount / uc.base_amount), unit=uc.converted_unit, food=food)
# return {
# 'amount': amount * (uc.converted_amount / uc.base_amount),
# 'unit': {
# 'id': uc.converted_unit.id,
# 'name': uc.converted_unit.name,
# 'plural_name': uc.converted_unit.plural_name
# },
# }
else:
return {
'amount': amount * (uc.base_amount / uc.converted_amount),
'unit': {
'id': uc.base_unit.id,
'name': uc.base_unit.name,
'plural_name': uc.base_unit.plural_name
},
}
return Ingredient(amount=amount * (uc.base_amount / uc.converted_amount), unit=uc.base_unit, food=food)
# return {
# 'amount': amount * (uc.base_amount / uc.converted_amount),
# 'unit': {
# 'id': uc.base_unit.id,
# 'name': uc.base_unit.name,
# 'plural_name': uc.base_unit.plural_name
# },
# }

View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.7 on 2023-03-15 14:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0193_alter_unitconversion_base_unit_and_more'),
]
operations = [
migrations.AddField(
model_name='unit',
name='base_unit',
field=models.TextField(blank=True, default=None, max_length=256, null=True),
),
]

View File

@ -534,6 +534,7 @@ class Unit(ExportModelOperationsMixin('unit'), models.Model, PermissionModelMixi
name = models.CharField(max_length=128, validators=[MinLengthValidator(1)])
plural_name = models.CharField(max_length=128, null=True, blank=True, default=None)
description = models.TextField(blank=True, null=True)
base_unit = models.TextField(max_length=256, null=True, blank=True, default=None)
space = models.ForeignKey(Space, on_delete=models.CASCADE)
objects = ScopedManager(space='space')

View File

@ -0,0 +1,25 @@
from django_scopes import scopes_disabled
from cookbook.helper.unit_conversion_helper import get_conversions
from cookbook.models import Unit, Food, Ingredient
def test_unit_conversions(space_1):
with scopes_disabled():
unit_gram = Unit.objects.create(name='gram', base_unit='g', space=space_1)
unit_pcs = Unit.objects.create(name='pcs', base_unit='', space=space_1)
unit_floz1 = Unit.objects.create(name='fl. oz 1', base_unit='imperial_fluid_ounce', space=space_1) # US and UK use different volume systems (US vs imperial)
unit_floz2 = Unit.objects.create(name='fl. oz 2', base_unit='fluid_ounce', space=space_1)
food_1 = Food.objects.create(name='Test Food 1', space=space_1)
ingredient_food_1_gram = Ingredient.objects.create(
food=food_1,
unit=unit_gram,
amount=100,
space=space_1,
)
print('\n----------- TEST ---------------')
print(get_conversions(ingredient_food_1_gram))