From 673303a7bd65bf84f0c47372ab9270e10398a294 Mon Sep 17 00:00:00 2001 From: Mike Shoup Date: Thu, 11 Jul 2019 13:55:49 -0600 Subject: [PATCH] Add filters for sorting hops --- src/humulus/filters.py | 57 ++++++++++++++++++++++ src/humulus/templates/recipes/_macros.html | 2 +- src/humulus/templates/recipes/info.html | 2 +- tests/test_filters.py | 32 ++++++++++++ 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/humulus/filters.py b/src/humulus/filters.py index 8266739..aafc495 100644 --- a/src/humulus/filters.py +++ b/src/humulus/filters.py @@ -111,6 +111,62 @@ def recipe_srm(recipe): return '{:.0f}'.format(1.4922 * (mcu**0.6859)) +def sort_hops(hops, form=False): + """Sorts a list of hops by use in recipe.""" + by_use = {'FWH': [], 'Boil': [], 'Whirlpool': [], 'Dry-Hop': []} + + # Split hops into each use type. + for hop in hops: + if form: + by_use[hop.use.data].append(hop) + else: + by_use[hop['use']].append(hop) + + if form: + hops_sorted = sorted( + by_use['FWH'], + key=lambda hop: float(hop.duration.data), + reverse=True + ) + hops_sorted.extend( + sorted(by_use['Boil'], + key=lambda hop: float(hop.duration.data), + reverse=True) + ) + hops_sorted.extend( + sorted(by_use['Whirlpool'], + key=lambda hop: float(hop.duration.data), + reverse=True) + ) + hops_sorted.extend( + sorted(by_use['Dry-Hop'], + key=lambda hop: float(hop.duration.data), + reverse=True) + ) + else: + hops_sorted = sorted( + by_use['FWH'], + key=lambda hop: float(hop['duration']), + reverse=True + ) + hops_sorted.extend( + sorted(by_use['Boil'], + key=lambda hop: float(hop['duration']), + reverse=True) + ) + hops_sorted.extend( + sorted(by_use['Whirlpool'], + key=lambda hop: float(hop['duration']), + reverse=True) + ) + hops_sorted.extend( + sorted(by_use['Dry-Hop'], + key=lambda hop: float(hop['duration']), + reverse=True) + ) + return hops_sorted + + def create_filters(app): app.add_template_filter(recipe_og) app.add_template_filter(recipe_fg) @@ -118,3 +174,4 @@ def create_filters(app): app.add_template_filter(recipe_ibu_ratio) app.add_template_filter(recipe_abv) app.add_template_filter(recipe_srm) + app.add_template_filter(sort_hops) diff --git a/src/humulus/templates/recipes/_macros.html b/src/humulus/templates/recipes/_macros.html index 4214e74..a7f99a6 100644 --- a/src/humulus/templates/recipes/_macros.html +++ b/src/humulus/templates/recipes/_macros.html @@ -82,7 +82,7 @@ function getSpecsURL() { -#}

Hops

- {% for hop in form.hops %} + {% for hop in form.hops|sort_hops(form=True) %}
diff --git a/src/humulus/templates/recipes/info.html b/src/humulus/templates/recipes/info.html index c00ebf9..ca8a46b 100644 --- a/src/humulus/templates/recipes/info.html +++ b/src/humulus/templates/recipes/info.html @@ -149,7 +149,7 @@ Usage - {%- for hop in recipe.hops -%} + {%- for hop in recipe.hops|sort_hops -%} {{ hop.name }} {{ hop.amount|float|round(2) }} oz. diff --git a/tests/test_filters.py b/tests/test_filters.py index 0dd825f..4f0b1cd 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -12,8 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +from decimal import Decimal from humulus.filters import * +from humulus.recipes import HopForm def test_recipe_og(sample_recipes): @@ -71,3 +73,33 @@ def test_recipe_srm(sample_recipes): # Remove fermentables, verify 0 is returned sample_recipes['lager'].pop('fermentables') assert recipe_srm(sample_recipes['lager']) == '0' + + +def test_sort_hops(): + # Test with no form + hops = [ + {'name': '4', 'use': 'Dry-Hop', 'duration': '5'}, + {'name': '3', 'use': 'Whirlpool', 'duration': '10'}, + {'name': '2', 'use': 'Boil', 'duration': '5'}, + {'name': '1', 'use': 'Boil', 'duration': '15'}, + {'name': '0', 'use': 'FWH', 'duration': '60'}, + ] + assert sort_hops(hops) == [ + {'name': '0', 'use': 'FWH', 'duration': '60'}, + {'name': '1', 'use': 'Boil', 'duration': '15'}, + {'name': '2', 'use': 'Boil', 'duration': '5'}, + {'name': '3', 'use': 'Whirlpool', 'duration': '10'}, + {'name': '4', 'use': 'Dry-Hop', 'duration': '5'}, + ] + + # Test with form + hop_forms = [] + for hop in hops: + form = HopForm() + form.name.data = hop['name'] + form.use.data = hop['use'] + form.duration.data = Decimal(hop['duration']) + hop_forms.append(form) + + for num, hop in enumerate(sort_hops(hop_forms, form=True)): + assert hop.name.data == str(num)