toji 1.6.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/example/calendar.ipynb +123 -0
  3. data/example/{schedule.yaml → calendar.yaml} +6 -30
  4. data/example/calendar_file.ipynb +338 -0
  5. data/example/example_core.rb +336 -0
  6. data/example/kake_recipe.rb +27 -0
  7. data/example/koji_making.ipynb +16 -15
  8. data/example/koji_making.rb +2 -1
  9. data/example/koji_making.yaml +9 -9
  10. data/example/koji_making_multi.ipynb +26 -25
  11. data/example/koji_recipe.rb +1 -1
  12. data/example/moromi.ipynb +25 -24
  13. data/example/moromi.rb +1 -0
  14. data/example/moromi.yaml +10 -4
  15. data/example/recipe.rb +75 -0
  16. data/example/shubo.ipynb +15 -14
  17. data/example/shubo.rb +2 -1
  18. data/example/shubo.yaml +10 -10
  19. data/lib/toji.rb +3 -1
  20. data/lib/toji/brew.rb +1 -2
  21. data/lib/toji/brew/base.rb +7 -71
  22. data/lib/toji/brew/builder.rb +47 -4
  23. data/lib/toji/brew/graph/bmd.rb +0 -1
  24. data/lib/toji/brew/graph/progress.rb +1 -1
  25. data/lib/toji/brew/koji.rb +0 -10
  26. data/lib/toji/brew/moromi.rb +2 -36
  27. data/lib/toji/brew/shubo.rb +0 -5
  28. data/lib/toji/brew/state.rb +58 -111
  29. data/lib/toji/brew/state_wrapper.rb +135 -0
  30. data/lib/toji/calendar.rb +123 -0
  31. data/lib/toji/{schedule → calendar}/date_column.rb +3 -6
  32. data/lib/toji/{schedule → calendar}/date_row.rb +6 -6
  33. data/lib/toji/ingredient.rb +10 -0
  34. data/lib/toji/ingredient/kake.rb +17 -0
  35. data/lib/toji/ingredient/kake/actual.rb +27 -0
  36. data/lib/toji/ingredient/kake/base.rb +18 -0
  37. data/lib/toji/ingredient/kake/expected.rb +41 -0
  38. data/lib/toji/ingredient/koji.rb +19 -0
  39. data/lib/toji/ingredient/koji/actual.rb +30 -0
  40. data/lib/toji/ingredient/koji/actual_fermentable.rb +15 -0
  41. data/lib/toji/ingredient/koji/base.rb +35 -0
  42. data/lib/toji/ingredient/koji/expected.rb +46 -0
  43. data/lib/toji/ingredient/koji/expected_fermentable.rb +15 -0
  44. data/lib/toji/{recipe → ingredient}/koji_rate.rb +1 -1
  45. data/lib/toji/ingredient/rice.rb +10 -0
  46. data/lib/toji/ingredient/rice/actual_steamable.rb +27 -0
  47. data/lib/toji/ingredient/rice/base.rb +41 -0
  48. data/lib/toji/ingredient/rice/expected_steamable.rb +29 -0
  49. data/lib/toji/ingredient/rice_rate.rb +35 -0
  50. data/lib/toji/product.rb +65 -0
  51. data/lib/toji/{schedule/product_event.rb → product/event.rb} +4 -4
  52. data/lib/toji/recipe.rb +120 -5
  53. data/lib/toji/recipe/step.rb +46 -59
  54. data/lib/toji/version.rb +1 -1
  55. metadata +32 -38
  56. data/example/rice_recipe.rb +0 -28
  57. data/example/schedule.ipynb +0 -393
  58. data/example/schedule_file.ipynb +0 -337
  59. data/example/three_step_mashing_recipe.rb +0 -67
  60. data/lib/toji/brew/state_accessor.rb +0 -13
  61. data/lib/toji/brew/state_record.rb +0 -72
  62. data/lib/toji/recipe/ingredient.rb +0 -10
  63. data/lib/toji/recipe/ingredient/koji.rb +0 -21
  64. data/lib/toji/recipe/ingredient/koji/actual.rb +0 -32
  65. data/lib/toji/recipe/ingredient/koji/actual_fermentable.rb +0 -17
  66. data/lib/toji/recipe/ingredient/koji/base.rb +0 -37
  67. data/lib/toji/recipe/ingredient/koji/expected.rb +0 -48
  68. data/lib/toji/recipe/ingredient/koji/expected_fermentable.rb +0 -17
  69. data/lib/toji/recipe/ingredient/rice.rb +0 -21
  70. data/lib/toji/recipe/ingredient/rice/actual.rb +0 -29
  71. data/lib/toji/recipe/ingredient/rice/actual_steamable.rb +0 -29
  72. data/lib/toji/recipe/ingredient/rice/base.rb +0 -51
  73. data/lib/toji/recipe/ingredient/rice/expected.rb +0 -43
  74. data/lib/toji/recipe/ingredient/rice/expected_steamable.rb +0 -31
  75. data/lib/toji/recipe/ingredient/yeast.rb +0 -21
  76. data/lib/toji/recipe/rice_rate.rb +0 -10
  77. data/lib/toji/recipe/rice_rate/base.rb +0 -21
  78. data/lib/toji/recipe/rice_rate/cooked.rb +0 -67
  79. data/lib/toji/recipe/rice_rate/steamed.rb +0 -30
  80. data/lib/toji/recipe/three_step_mashing.rb +0 -274
  81. data/lib/toji/recipe/yeast_rate.rb +0 -41
  82. data/lib/toji/schedule.rb +0 -11
  83. data/lib/toji/schedule/calendar.rb +0 -139
  84. data/lib/toji/schedule/date_interval_enumerator.rb +0 -45
  85. data/lib/toji/schedule/product.rb +0 -117
@@ -1,43 +0,0 @@
1
- module Toji
2
- module Recipe
3
- module Ingredient
4
- module Rice
5
- class Expected
6
- include Base
7
- include ExpectedSteamable
8
-
9
- def initialize(raw, rice_rate: Recipe::RiceRate::Cooked::DEFAULT)
10
- @raw = raw.to_f
11
-
12
- @rice_rate = rice_rate
13
- @soaked_rate = rice_rate.soaked_rate
14
- @before_steaming_rate = rice_rate.before_steaming_rate
15
- @steamed_rate = rice_rate.steamed_rate
16
- @cooled_rate = rice_rate.cooled_rate
17
- end
18
-
19
- def round(ndigit=0, half: :up)
20
- self.class.new(@raw.round(ndigit, half: half), rice_rate: @rice_rate)
21
- end
22
-
23
- def *(other)
24
- if Integer===other || Float===other
25
- self.class.new(@raw * other, rice_rate: @rice_rate)
26
- else
27
- x, y = other.coerce(self)
28
- x * y
29
- end
30
- end
31
-
32
- def self.create(x)
33
- if self===x
34
- x
35
- else
36
- new(x)
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,31 +0,0 @@
1
- module Toji
2
- module Recipe
3
- module Ingredient
4
- module Rice
5
- module ExpectedSteamable
6
- def soaking_water
7
- @raw * @soaked_rate
8
- end
9
-
10
- def soaked
11
- @raw + @raw * @soaked_rate
12
- end
13
-
14
- def steaming_water
15
- if @before_steaming_rate
16
- @raw * (@before_steaming_rate - @soaked_rate)
17
- end
18
- end
19
-
20
- def steamed
21
- @raw + @raw * @steamed_rate
22
- end
23
-
24
- def cooled
25
- @raw + @raw * @cooled_rate
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,21 +0,0 @@
1
- module Toji
2
- module Recipe
3
- module Ingredient
4
- class Yeast
5
-
6
- def initialize(total, rate: Recipe::YeastRate::RED_STAR)
7
- @total = total
8
- @rate = rate
9
- end
10
-
11
- def yeast
12
- @total * @rate.yeast_rate / 1000.0
13
- end
14
-
15
- def water
16
- yeast * @rate.water_rate
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,10 +0,0 @@
1
- require 'toji/recipe/rice_rate/base'
2
- require 'toji/recipe/rice_rate/cooked'
3
- require 'toji/recipe/rice_rate/steamed'
4
-
5
- module Toji
6
- module Recipe
7
- module RiceRate
8
- end
9
- end
10
- end
@@ -1,21 +0,0 @@
1
- module Toji
2
- module Recipe
3
- module RiceRate
4
- module Base
5
- # 浸漬米吸水率
6
- attr_reader :soaked_rate
7
-
8
- # 蒸し前浸漬米吸水率
9
- # 炊飯の場合は水を追加
10
- # 蒸しの場合は一晩経って蒸発した分を削減
11
- attr_reader :before_steaming_rate
12
-
13
- # 蒸米吸水率
14
- attr_reader :steamed_rate
15
-
16
- # 放冷後蒸米吸水率
17
- attr_reader :cooled_rate
18
- end
19
- end
20
- end
21
- end
@@ -1,67 +0,0 @@
1
- module Toji
2
- module Recipe
3
- module RiceRate
4
- class Cooked
5
- include Base
6
-
7
- # 炊飯器を使う場合
8
- #
9
- # 浸漬。
10
- # 25〜30分くらい浸漬させないと中心部まで水を吸わない。
11
- # => 吸水歩合 約1.30。
12
- #
13
- # 炊飯。
14
- # 吸水と炊く用の水を合わせて歩合1.50くらいにしないと中心部まで火が通らない、且つ側面が焦げる。
15
- # 圧力がかかる熟成炊きみたいな長めの炊飯が良い。
16
- # => 蒸米歩合 約1.40。
17
- #
18
- # 白米の60%の水で炊くと蒸米吸水率はだいたい38%くらいになる
19
- # 炊飯、放冷の過程で水分のうち36%程度は蒸発する
20
- #
21
- # 放冷。
22
- # 歩合1.36〜1.37くらいになる。
23
- # 更に歩合を下げたければ炊飯までは同じで、放冷に注力するのが良い。
24
-
25
- # 重量推移の例
26
- #
27
- # 浸漬
28
- # before
29
- # 白米(無洗米コシヒカリ) 100g
30
- # after
31
- # 吸水後白米 130g
32
- # (吸水歩合 30%)
33
- #
34
- # 炊飯
35
- # before
36
- # 吸水後白米 130g
37
- # 炊飯用水 20g
38
- # (吸水歩合+炊飯水率 50%)
39
- # after
40
- # 炊飯米 140g
41
- # (炊飯米吸水率 40%)
42
- #
43
- # 放冷
44
- # before
45
- # 炊飯米 140g
46
- # after
47
- # 放冷後炊飯米 136g
48
- # (放冷後炊飯米吸水率 36%)
49
-
50
- def initialize(soaked_rate, before_steaming_rate, steamed_rate, cooled_rate)
51
- @soaked_rate = soaked_rate
52
- @before_steaming_rate = before_steaming_rate
53
- @steamed_rate = steamed_rate
54
- @cooled_rate = cooled_rate
55
- end
56
-
57
-
58
- DEFAULT = new(0.30, 0.5, 0.40, 0.36)
59
- end
60
-
61
-
62
- def self.cooked(soaked_rate, before_steaming_rate, steamed_rate, cooled_rate)
63
- Cooked.new(soaked_rate, before_steaming_rate, steamed_rate, cooled_rate)
64
- end
65
- end
66
- end
67
- end
@@ -1,30 +0,0 @@
1
- module Toji
2
- module Recipe
3
- module RiceRate
4
- class Steamed
5
- include Base
6
-
7
- def initialize(soaked_rate, before_steaming_rate, steamed_rate, cooled_rate)
8
- @soaked_rate = soaked_rate
9
- @before_steaming_rate = before_steaming_rate
10
- @steamed_rate = steamed_rate
11
- @cooled_rate = cooled_rate
12
- end
13
-
14
- def before_steaming_rate
15
- @before_steaming_rate || begin
16
- @soaked_rate - 0.04
17
- end
18
- end
19
-
20
-
21
- DEFAULT = new(0.33, nil, 0.41, 0.33)
22
- end
23
-
24
-
25
- def self.steamed(soaked_rate, before_steaming_rate, steamed_rate, cooled_rate)
26
- Steamed.new(soaked_rate, before_steaming_rate, steamed_rate, cooled_rate)
27
- end
28
- end
29
- end
30
- end
@@ -1,274 +0,0 @@
1
- module Toji
2
- module Recipe
3
- class ThreeStepMashing
4
-
5
- attr_reader :steps
6
- attr_reader :yeast
7
-
8
- attr_accessor :moto_days
9
- attr_accessor :odori_days
10
-
11
- def initialize(steps, yeast_rate, moto_days: 1, odori_days: 1)
12
- @steps = steps
13
-
14
- @yeast_rate = yeast_rate
15
- weight_total = @steps.map(&:weight_total).sum
16
- @yeast = Ingredient::Yeast.new(weight_total, rate: yeast_rate)
17
-
18
- @moto_days = moto_days
19
- @odori_days = odori_days
20
- end
21
-
22
- def scale(rice_total, yeast_rate=@yeast_rate)
23
- rate = rice_total / @steps.map(&:rice_total).sum
24
- new_steps = @steps.map {|step|
25
- step * rate
26
- }
27
-
28
- self.class.new(new_steps, yeast_rate, moto_days: @moto_days, odori_days: @odori_days)
29
- end
30
-
31
- def round(ndigit=0, half: :up)
32
- new_steps = @steps.map {|step|
33
- step.round(ndigit, half: half)
34
- }
35
- self.class.new(new_steps, @yeast_rate, moto_days: @moto_days, odori_days: @odori_days)
36
- end
37
-
38
- # 内容量の累計
39
- def cumulative_weight_totals
40
- weight_total = @steps.map(&:weight_total)
41
-
42
- weight_total.map.with_index {|x,i|
43
- weight_total[0..i].inject(:+)
44
- }
45
- end
46
-
47
- # 総米の累計
48
- def cumulative_rice_totals
49
- rice_total = @steps.map(&:rice_total)
50
-
51
- rice_total.map.with_index {|x,i|
52
- rice_total[0..i].inject(&:+)
53
- }
54
- end
55
-
56
- # 酒母歩合の累計
57
- def cumulative_shubo_rates
58
- rice_total = @steps.map(&:rice_total)
59
- shubo = rice_total[0]
60
-
61
- rice_total.map.with_index {|x,i|
62
- shubo / rice_total[0..i].inject(&:+)
63
- }
64
- end
65
-
66
- # 酒母歩合
67
- #
68
- # 7%が標準である
69
- # 汲水歩合が大きい高温糖化酒母では6%程度である
70
- #
71
- # 出典: 酒造教本 P96
72
- def shubo_rate
73
- cumulative_shubo_rates.last || 0.0
74
- end
75
-
76
- # 白米比率
77
- #
78
- # 発酵型と白米比率
79
- # 発酵の型 酒母 添 仲 留 特徴
80
- # 湧き進め型 1 2 4 6 短期醪、辛口、軽快な酒質
81
- # 湧き抑え型 1 2 4 7 長期醪、甘口、おだやかな酒質
82
- #
83
- # 出典: 酒造教本 P95
84
- def rice_rates
85
- @steps.map {|step|
86
- step.rice_total / @steps[0].rice_total
87
- }
88
- end
89
-
90
- def to_h
91
- {
92
- steps: steps.map(&:to_h),
93
- cumulative_rice_totals: cumulative_rice_totals,
94
- cumulative_shubo_rates: cumulative_shubo_rates,
95
- shubo_rate: shubo_rate,
96
- rice_rates: rice_rates,
97
- }
98
- end
99
-
100
- def table_data
101
- headers = [""] + @steps.map(&:name) + [:total]
102
- keys = [:rice_total, :rice, :koji, :alcohol, :water, :lactic_acid]
103
-
104
- cells = [keys]
105
- cells += @steps.map {|step|
106
- [step.rice_total, step.rice, step.koji, step.alcohol, step.water, step.lactic_acid]
107
- }
108
- cells << keys.map {|key|
109
- @steps.map(&key).compact.sum
110
- }
111
-
112
- cells = cells.map {|cell|
113
- cell.map {|c|
114
- if Ingredient::Rice::Base===c
115
- c = c.raw
116
- end
117
-
118
- case c
119
- when NilClass
120
- ""
121
- when 0
122
- ""
123
- else
124
- c
125
- end
126
- }
127
- }
128
-
129
- {header: headers, rows: cells.transpose}
130
- end
131
-
132
- def table
133
- data = table_data
134
-
135
- Plotly::Plot.new(
136
- data: [{
137
- type: :table,
138
- header: {
139
- values: data[:header]
140
- },
141
- cells: {
142
- values: data[:rows].transpose
143
- },
144
- }],
145
- layout: {
146
- }
147
- )
148
- end
149
-
150
-
151
- # 乳酸は汲水100L当たり比重1.21の乳酸(90%乳酸と称される)を650〜720ml添加する。
152
- # ここでは間をとって685mlとする
153
- #
154
- # 出典: 酒造教本 P38
155
- TEMPLATES = {
156
- # 酒造教本による標準型仕込配合
157
- # 出典: 酒造教本 P97
158
- sokujo_textbook: new(
159
- [
160
- Step.new(
161
- name: :moto,
162
- rice: 45,
163
- koji: 20,
164
- water: 70,
165
- lactic_acid: 70*6.85/1000
166
- ),
167
- Step.new(
168
- name: :soe,
169
- rice: 100,
170
- koji: 40,
171
- water: 130
172
- ),
173
- Step.new(
174
- name: :naka,
175
- rice: 215,
176
- koji: 60,
177
- water: 330
178
- ),
179
- Step.new(
180
- name: :tome,
181
- rice: 360,
182
- koji: 80,
183
- water: 630
184
- ),
185
- Step.new(
186
- name: :yodan,
187
- rice: 80,
188
- water: 120
189
- ),
190
- ],
191
- YeastRate::RED_STAR,
192
- moto_days: 14,
193
- odori_days: 1,
194
- ),
195
- # 灘における仕込配合の平均値
196
- # 出典: http://www.nada-ken.com/main/jp/index_shi/234.html
197
- sokujo_nada: new(
198
- [
199
- Step.new(
200
- name: :moto,
201
- rice: 93,
202
- koji: 47,
203
- water: 170,
204
- lactic_acid: 170*6.85/1000
205
- ),
206
- Step.new(
207
- name: :soe,
208
- rice: 217,
209
- koji: 99,
210
- water: 270
211
- ),
212
- Step.new(
213
- name: :naka,
214
- rice: 423,
215
- koji: 143,
216
- water: 670
217
- ),
218
- Step.new(
219
- name: :tome,
220
- rice: 813,
221
- koji: 165,
222
- water: 1330
223
- ),
224
- Step.new(
225
- name: :alcohol,
226
- alcohol: 900
227
- ),
228
- ],
229
- YeastRate::RED_STAR,
230
- moto_days: 14,
231
- odori_days: 1,
232
- ),
233
- # 簡易酒母省略仕込
234
- # 出典: https://www.jstage.jst.go.jp/article/jbrewsocjapan1915/60/11/60_11_999/_article/-char/ja/
235
- simple_sokujo_himeno: new(
236
- [
237
- Step.new(
238
- name: :moto,
239
- rice: 0,
240
- koji: 70,
241
- water: 245,
242
- lactic_acid: 1.6
243
- ),
244
- Step.new(
245
- name: :soe,
246
- rice: 130,
247
- koji: 0,
248
- water: 0
249
- ),
250
- Step.new(
251
- name: :naka,
252
- rice: 300,
253
- koji: 100,
254
- water: 400
255
- ),
256
- Step.new(
257
- name: :tome,
258
- rice: 490,
259
- koji: 110,
260
- water: 800
261
- ),
262
- Step.new(
263
- name: :yodan,
264
- water: 255
265
- ),
266
- ],
267
- YeastRate::RED_STAR,
268
- moto_days: 1,
269
- odori_days: 2,
270
- ),
271
- }.freeze
272
- end
273
- end
274
- end