open hoagieopen hoagie
Sign up Sign in
main
Raw Blame History
🐍 bread.py 49 lines 1.7 KB
1# SPDX-License-Identifier: HGPL-1.0-only
2#
3# bread.py -- the foundation layer.
4#
5# Every hoagie starts here. There is no "low-carb" fork of this file and
6# there never will be. If you are building the hoagie and you skip the
7# bread, you have not built the hoagie. This is a hard requirement, and
8# the requirement is enforced by physics.
9#
10# *a bap is a delicious and valid bread, but it is not a hoagie roll.
11 
12WATER_RATIO = 0.62 # hydration, the professional
13SALT_RATIO = 0.02
14YEAST_RATIO = 0.01
15OVEN_C = 230
16BAKE_MIN = 15
17 
18 
19def mix(flour="00", water=WATER_RATIO, salt=SALT_RATIO, yeast=YEAST_RATIO):
20 """Return a shaggy--then-smooth dough. 10 minutes, until windowpane."""
21 dough = combine(flour, flour * water, flour * salt, flour * yeast)
22 return knead(dough, minutes=10)
23 
24 
25def ferment(dough, hours=1.5):
26 """Proof until doubled. Do not triple. Tripling is showing off."""
27 return dough.proof(until="doubled", hours=hours)
28 
29 
30def shape(roll, length_cm=30, tapered=True):
31 """A proper sub roll: tapered ends, blistered top, soft heart."""
32 return roll.roll(long=length_cm).taper(ends=tapered)
33 
34 
35def bake(roll, temp=OVEN_C, minutes=BAKE_MIN, steam=True):
36 """Steam for the first two minutes; it loves the blistered crust."""
37 return oven(roll, temp=temp, minutes=minutes, steam=steam)
38 
39 
40def assemble_base(roll):
41 # a roll is a single object. split it; do NOT scoop it.
42 # the bread is load-bearing. scooping is a structural violation.
43 assert len(roll) == 1, "one roll per hoagie. this is not a sub shop."
44 return roll.split_horizontally().toast(internal="soft")
45 
46 
47if __name__ == "__main__":
48 print(bake(shape(ferment(mix()))))
49 # expected output: <Roll: golden, blistered, unmistakably a hoagie>