mirror of
https://github.com/shouptech/humulus.git
synced 2026-02-03 16:09:44 +00:00
Add hops
This commit is contained in:
parent
7505938acc
commit
be8806c28f
4 changed files with 42 additions and 6 deletions
|
|
@ -14,9 +14,13 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
def recipe_og(recipe):
|
def recipe_og(recipe):
|
||||||
"""Returns a recipe's Original Gravity"""
|
"""Returns a recipe's Original Gravity"""
|
||||||
|
if 'fermentables' not in recipe:
|
||||||
|
return '0.000'
|
||||||
points = 0
|
points = 0
|
||||||
grain_points = 0
|
grain_points = 0
|
||||||
# Loop through fermentables, adding up points
|
# Loop through fermentables, adding up points
|
||||||
|
|
@ -37,8 +41,8 @@ def recipe_og(recipe):
|
||||||
|
|
||||||
def recipe_fg(recipe):
|
def recipe_fg(recipe):
|
||||||
"""Returns a recipe's final gravity"""
|
"""Returns a recipe's final gravity"""
|
||||||
if 'yeast' not in recipe:
|
if 'yeast' not in recipe or 'fermentables' not in recipe:
|
||||||
return 0.0
|
return '0.000'
|
||||||
og = float(recipe_og(recipe))
|
og = float(recipe_og(recipe))
|
||||||
og_delta = 0.0
|
og_delta = 0.0
|
||||||
# Adjust original gravity by removing nonfermentables (i.e., Lactose)
|
# Adjust original gravity by removing nonfermentables (i.e., Lactose)
|
||||||
|
|
@ -54,15 +58,28 @@ def recipe_fg(recipe):
|
||||||
float(recipe['yeast']['high_attenuation'])
|
float(recipe['yeast']['high_attenuation'])
|
||||||
) / 200
|
) / 200
|
||||||
)
|
)
|
||||||
print(og - 1 - og_delta)
|
|
||||||
print(attenuation)
|
|
||||||
print(og_delta)
|
|
||||||
return '{:.3f}'.format(
|
return '{:.3f}'.format(
|
||||||
round(1 + (og - 1 - og_delta)*(1 - attenuation) + og_delta, 3)
|
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):
|
def create_filters(app):
|
||||||
app.add_template_filter(recipe_og)
|
app.add_template_filter(recipe_og)
|
||||||
app.add_template_filter(recipe_fg)
|
app.add_template_filter(recipe_fg)
|
||||||
|
app.add_template_filter(recipe_ibu)
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@
|
||||||
<dd>{{ recipe|recipe_og }}</dd>
|
<dd>{{ recipe|recipe_og }}</dd>
|
||||||
<dt>FG</dt>
|
<dt>FG</dt>
|
||||||
<dd>{{ recipe|recipe_fg }}</dd>
|
<dd>{{ recipe|recipe_fg }}</dd>
|
||||||
|
<dt>IBU</dt>
|
||||||
|
<dd>{{ recipe|recipe_ibu }}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ def sample_recipes():
|
||||||
{
|
{
|
||||||
'alpha': '5.0',
|
'alpha': '5.0',
|
||||||
'amount': '0.5',
|
'amount': '0.5',
|
||||||
'duration': '10',
|
'duration': '30',
|
||||||
'name': 'East Kent Goldings (UK)',
|
'name': 'East Kent Goldings (UK)',
|
||||||
'use': 'Boil'
|
'use': 'Boil'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,25 @@ from humulus.filters import *
|
||||||
def test_recipe_og(sample_recipes):
|
def test_recipe_og(sample_recipes):
|
||||||
assert recipe_og(sample_recipes['lager']) == '1.054'
|
assert recipe_og(sample_recipes['lager']) == '1.054'
|
||||||
assert recipe_og(sample_recipes['sweetstout']) == '1.038'
|
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):
|
def test_recipe_fg(sample_recipes):
|
||||||
assert recipe_fg(sample_recipes['lager']) == '1.014'
|
assert recipe_fg(sample_recipes['lager']) == '1.014'
|
||||||
assert recipe_fg(sample_recipes['sweetstout']) == '1.015'
|
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'
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue