From be8806c28f95d3dcb1f677245e2f840b7aeb9642 Mon Sep 17 00:00:00 2001 From: Mike Shoup Date: Wed, 3 Jul 2019 19:52:24 -0600 Subject: [PATCH] Add hops --- src/humulus/filters.py | 27 ++++++++++++++++++++----- src/humulus/templates/recipes/info.html | 2 ++ tests/conftest.py | 2 +- tests/test_filters.py | 17 ++++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/humulus/filters.py b/src/humulus/filters.py index 010a927..8c13d19 100644 --- a/src/humulus/filters.py +++ b/src/humulus/filters.py @@ -14,9 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +import math + def recipe_og(recipe): """Returns a recipe's Original Gravity""" + if 'fermentables' not in recipe: + return '0.000' points = 0 grain_points = 0 # Loop through fermentables, adding up points @@ -37,8 +41,8 @@ def recipe_og(recipe): def recipe_fg(recipe): """Returns a recipe's final gravity""" - if 'yeast' not in recipe: - return 0.0 + if 'yeast' not in recipe or 'fermentables' not in recipe: + return '0.000' og = float(recipe_og(recipe)) og_delta = 0.0 # Adjust original gravity by removing nonfermentables (i.e., Lactose) @@ -54,15 +58,28 @@ def recipe_fg(recipe): float(recipe['yeast']['high_attenuation']) ) / 200 ) - print(og - 1 - og_delta) - print(attenuation) - print(og_delta) return '{:.3f}'.format( round(1 + (og - 1 - og_delta)*(1 - attenuation) + og_delta, 3) ) +def recipe_ibu(recipe): + """Return a recipe's IBU""" + if 'hops' not in recipe: + return '0' + bigness = 1.65 * 0.000125**(float(recipe_og(recipe)) - 1) + ibu = 0.0 + for h in recipe['hops']: + mgl = ( + float(h['alpha']) * float(h['amount']) * 7490.0 / + (float(recipe['volume']) * 100.0) + ) + btf = (1 - math.exp(-0.04 * float(h['duration']))) / 4.15 + ibu += bigness * btf * mgl + return '{:.0f}'.format(ibu) + def create_filters(app): app.add_template_filter(recipe_og) app.add_template_filter(recipe_fg) + app.add_template_filter(recipe_ibu) diff --git a/src/humulus/templates/recipes/info.html b/src/humulus/templates/recipes/info.html index 4c9ab2d..56e57c5 100644 --- a/src/humulus/templates/recipes/info.html +++ b/src/humulus/templates/recipes/info.html @@ -36,6 +36,8 @@
{{ recipe|recipe_og }}
FG
{{ recipe|recipe_fg }}
+
IBU
+
{{ recipe|recipe_ibu }}
diff --git a/tests/conftest.py b/tests/conftest.py index f1fef06..917f4fd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -251,7 +251,7 @@ def sample_recipes(): { 'alpha': '5.0', 'amount': '0.5', - 'duration': '10', + 'duration': '30', 'name': 'East Kent Goldings (UK)', 'use': 'Boil' } diff --git a/tests/test_filters.py b/tests/test_filters.py index 3f10516..7a59cbd 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -19,8 +19,25 @@ from humulus.filters import * def test_recipe_og(sample_recipes): assert recipe_og(sample_recipes['lager']) == '1.054' assert recipe_og(sample_recipes['sweetstout']) == '1.038' + # Remove fermentables, verify 0 is returned + sample_recipes['lager'].pop('fermentables') + assert recipe_og(sample_recipes['lager']) == '0.000' def test_recipe_fg(sample_recipes): assert recipe_fg(sample_recipes['lager']) == '1.014' assert recipe_fg(sample_recipes['sweetstout']) == '1.015' + # Remove fermentables, verify 0 is returned + sample_recipes['lager'].pop('fermentables') + assert recipe_fg(sample_recipes['lager']) == '0.000' + # Remove yeast, verify 0 is returned + sample_recipes['sweetstout'].pop('yeast') + assert recipe_fg(sample_recipes['sweetstout']) == '0.000' + + +def test_recipe_ibu(sample_recipes): + assert recipe_ibu(sample_recipes['lager']) == '26' + assert recipe_ibu(sample_recipes['sweetstout']) == '34' + # Remove hops, verify 0 is returned + sample_recipes['lager'].pop('hops') + assert recipe_ibu(sample_recipes['lager']) == '0'