toji 0.1.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 (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +39 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/example/koji_recipe.rb +34 -0
  11. data/example/make_koji.rb +18 -0
  12. data/example/rice_recipe.rb +28 -0
  13. data/example/three_step_mashing_recipe.rb +65 -0
  14. data/lib/toji.rb +12 -0
  15. data/lib/toji/graph.rb +6 -0
  16. data/lib/toji/graph/ab.rb +75 -0
  17. data/lib/toji/ingredient.rb +8 -0
  18. data/lib/toji/ingredient/koji.rb +19 -0
  19. data/lib/toji/ingredient/koji/actual.rb +21 -0
  20. data/lib/toji/ingredient/koji/actual_fermentable.rb +15 -0
  21. data/lib/toji/ingredient/koji/base.rb +26 -0
  22. data/lib/toji/ingredient/koji/expected.rb +51 -0
  23. data/lib/toji/ingredient/koji/expected_fermentable.rb +15 -0
  24. data/lib/toji/ingredient/rice.rb +19 -0
  25. data/lib/toji/ingredient/rice/actual.rb +18 -0
  26. data/lib/toji/ingredient/rice/actual_steamable.rb +27 -0
  27. data/lib/toji/ingredient/rice/base.rb +40 -0
  28. data/lib/toji/ingredient/rice/expected.rb +46 -0
  29. data/lib/toji/ingredient/rice/expected_steamable.rb +29 -0
  30. data/lib/toji/ingredient/yeast.rb +9 -0
  31. data/lib/toji/ingredient/yeast/base.rb +21 -0
  32. data/lib/toji/ingredient/yeast/red_star.rb +30 -0
  33. data/lib/toji/progress.rb +11 -0
  34. data/lib/toji/progress/job.rb +165 -0
  35. data/lib/toji/progress/job_accessor.rb +13 -0
  36. data/lib/toji/progress/jobs.rb +142 -0
  37. data/lib/toji/progress/make_koji.rb +100 -0
  38. data/lib/toji/progress/moromi.rb +276 -0
  39. data/lib/toji/progress/shubo.rb +158 -0
  40. data/lib/toji/recipe.rb +9 -0
  41. data/lib/toji/recipe/koji_rate.rb +16 -0
  42. data/lib/toji/recipe/rice_rate.rb +10 -0
  43. data/lib/toji/recipe/rice_rate/base.rb +21 -0
  44. data/lib/toji/recipe/rice_rate/cooked.rb +61 -0
  45. data/lib/toji/recipe/rice_rate/steamed.rb +42 -0
  46. data/lib/toji/recipe/step.rb +65 -0
  47. data/lib/toji/recipe/three_step_mashing.rb +87 -0
  48. data/lib/toji/version.rb +3 -0
  49. data/toji.gemspec +36 -0
  50. metadata +178 -0
@@ -0,0 +1,26 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Koji
4
+ module Base
5
+ include Rice::Base
6
+
7
+ # 種麹
8
+ #
9
+ # 総破精麹を造るには、種麹の量を麹米100kgあたり種麹100gとする
10
+ # 突き破精麹を造るには、種麹の量を麹米100kgあたり種麹80gとする
11
+ #
12
+ # 出典: 酒造教本 P66
13
+ attr_reader :tanekoji_rate
14
+ attr_reader :tanekoji
15
+
16
+ # 出麹歩合
17
+ #
18
+ # 出麹歩合17〜19%のものが麹菌の繁殖のほどよい麹である
19
+ #
20
+ # 出典: 酒造教本 P67
21
+ attr_reader :dekoji_rate
22
+ attr_reader :dekoji
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Koji
4
+ class Expected
5
+ include Base
6
+ include Rice::ExpectedSteamable
7
+ include ExpectedFermentable
8
+
9
+ def initialize(raw, rice_rate: Recipe::RiceRate::Cooked::DEFAULT, koji_rate: Recipe::KojiRate::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
+
18
+ @koji_rate = koji_rate
19
+ @tanekoji_rate = koji_rate.tanekoji_rate
20
+ @dekoji_rate = koji_rate.dekoji_rate
21
+ end
22
+
23
+ def self.create(x)
24
+ if self===x
25
+ x
26
+ else
27
+ new(x)
28
+ end
29
+ end
30
+
31
+ def +(other)
32
+ if Base===other
33
+ Actual.new(raw + other.raw, soaked + other.soaked, steaming_water + other.steaming_water, steamed + other.steamed, cooled + other.cooled, tanekoji + other.tanekoji, dekoji + other.dekoji)
34
+ else
35
+ x, y = other.coerce(self)
36
+ x + y
37
+ end
38
+ end
39
+
40
+ def *(other)
41
+ if Integer===other || Float===other
42
+ Expected.new(@raw * other, rice_rate: @rice_rate, koji_rate: @koji_rate)
43
+ else
44
+ x, y = other.coerce(self)
45
+ x * y
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,15 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Koji
4
+ module ExpectedFermentable
5
+ def tanekoji
6
+ @raw * @tanekoji_rate
7
+ end
8
+
9
+ def dekoji
10
+ @raw + @raw * @dekoji_rate
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ require 'toji/ingredient/rice/base'
2
+ require 'toji/ingredient/rice/expected_steamable'
3
+ require 'toji/ingredient/rice/expected'
4
+ require 'toji/ingredient/rice/actual_steamable'
5
+ require 'toji/ingredient/rice/actual'
6
+
7
+ module Toji
8
+ module Ingredient
9
+ module Rice
10
+ def self.expected(raw, rice_rate: Recipe::RiceRate::Cooked::DEFAULT)
11
+ Expected.new(raw, rice_rate: rice_rate)
12
+ end
13
+
14
+ def self.actual(raw, soaked, steaming_water, steamed, cooled)
15
+ Actual.new(raw, soaked, steaming_water, steamed, cooled)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Rice
4
+ class ActualRice
5
+ include Base
6
+ include ActualSteamable
7
+
8
+ def initialize(raw, soaked, steaming_water, steamed, cooled)
9
+ @raw = raw
10
+ @soaked = soaked
11
+ @steaming_water = steaming_water
12
+ @steamed = steamed
13
+ @cooled = cooled
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Rice
4
+ module ActualSteamable
5
+ def soaked_rate
6
+ soaking_water / raw
7
+ end
8
+
9
+ def soaking_water
10
+ soaked - raw
11
+ end
12
+
13
+ def before_steaming_rate
14
+ # TODO
15
+ end
16
+
17
+ def steamed_rate
18
+ (steamed - raw) / raw
19
+ end
20
+
21
+ def cooled_rate
22
+ (cooled - raw) / raw
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Rice
4
+ module Base
5
+ # 白米
6
+ attr_reader :raw
7
+
8
+ # 浸漬米吸水率
9
+ #
10
+ # 標準的な白米吸水率は掛米で30〜35%、麹米で33%前後で許容範囲はかなり狭い
11
+ #
12
+ # 出典: 酒造教本 P38
13
+ attr_reader :soaked_rate
14
+ attr_reader :soaking_water
15
+ attr_reader :soaked
16
+
17
+ # 蒸米吸水率
18
+ #
19
+ # 蒸しにより通常甑置き前の浸漬白米の重量よりさらに12〜13%吸水する
20
+ # 蒸しにより吸水の増加が13%を超える場合は、蒸米の表面が柔らかくべとつく蒸米になりやすい
21
+ # 蒸米吸水率は麹米及び酒母米で41〜43%、掛米は39〜40%で、吟醸造りの場合は数%低い
22
+ #
23
+ # 出典: 酒造教本 P48
24
+ attr_reader :steamed_rate
25
+ attr_reader :steaming_water
26
+ attr_reader :steamed
27
+
28
+ # 放冷
29
+ #
30
+ # 冷却法で若干異なるが蒸米の冷却により掛米で白米重量の10%、麹米で8%程度の水が失われる
31
+ # 出典: 酒造教本 P49
32
+ #
33
+ # 麹を造るのに適した蒸米は、引込時の吸水率が33%を理想とし、許容幅はプラスマイナス1%である
34
+ # 出典: 酒造教本 P59
35
+ attr_reader :cooled_rate
36
+ attr_reader :cooled
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Rice
4
+ class Expected
5
+ include Base
6
+ include ExpectedSteamable
7
+
8
+ def initialize(raw, rice_rate: Recipe::RiceRate::Cooked::DEFAULT)
9
+ @raw = raw.to_f
10
+
11
+ @rice_rate = rice_rate
12
+ @soaked_rate = rice_rate.soaked_rate
13
+ @before_steaming_rate = rice_rate.before_steaming_rate
14
+ @steamed_rate = rice_rate.steamed_rate
15
+ @cooled_rate = rice_rate.cooled_rate
16
+ end
17
+
18
+ def +(other)
19
+ if Base===other
20
+ Actual.new(raw + other.raw, soaked + other.soaked, steaming_water + other.steaming_water, steamed + other.steamed, cooled + other.cooled)
21
+ else
22
+ x, y = other.coerce(self)
23
+ x + y
24
+ end
25
+ end
26
+
27
+ def *(other)
28
+ if Integer===other || Float===other
29
+ self.class.new(@raw * other, rice_rate: @rice_rate)
30
+ else
31
+ x, y = other.coerce(self)
32
+ x * y
33
+ end
34
+ end
35
+
36
+ def self.create(x)
37
+ if self===x
38
+ x
39
+ else
40
+ new(x)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Rice
4
+ module ExpectedSteamable
5
+ def soaking_water
6
+ @raw * @soaked_rate
7
+ end
8
+
9
+ def soaked
10
+ @raw + @raw * @soaked_rate
11
+ end
12
+
13
+ def steaming_water
14
+ if @before_steaming_rate
15
+ @raw * (@before_steaming_rate - @soaked_rate)
16
+ end
17
+ end
18
+
19
+ def steamed
20
+ @raw + @raw * @steamed_rate
21
+ end
22
+
23
+ def cooled
24
+ @raw + @raw * @cooled_rate
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ require 'toji/ingredient/yeast/base'
2
+ require 'toji/ingredient/yeast/red_star'
3
+
4
+ module Toji
5
+ module Ingredient
6
+ module Yeast
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Yeast
4
+ module Base
5
+ # 1リットル醸造のために必要な酵母の量
6
+ attr_reader :yeast_rate
7
+
8
+ # 乾燥酵母を戻すのに必要な水の量
9
+ attr_reader :water_rate
10
+
11
+ def yeast
12
+ @total * yeast_rate / 1000.0
13
+ end
14
+
15
+ def water
16
+ yeast * water_rate
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,30 @@
1
+ module Toji
2
+ module Ingredient
3
+ module Yeast
4
+ # RedStar酵母
5
+ #
6
+ # 容量 5g
7
+ # 醸造可能量 20〜23L
8
+ #
9
+ # ドライイーストは、生イーストの保存性を高めるために、その水分を大部分除いたものです。
10
+ # 使用時にはイーストの10倍以上の30-35℃の無菌のお湯(ミネラルウオーターや湯冷まし)で20-25分程度なじませてください。
11
+ # これにより水分を再吸収させると同 時に発酵力を回復させ、生イーストの状態にもどします。
12
+ # このときの温湯の温度が、イーストの発酵力に影響します
13
+ class RedStar
14
+ include Base
15
+
16
+ def initialize(total)
17
+ @total = total
18
+ end
19
+
20
+ def yeast_rate
21
+ 5.0 / 20.0
22
+ end
23
+
24
+ def water_rate
25
+ 10.0
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ require 'toji/progress/job'
2
+ require 'toji/progress/jobs'
3
+ require 'toji/progress/job_accessor'
4
+ require 'toji/progress/make_koji'
5
+ require 'toji/progress/shubo'
6
+ require 'toji/progress/moromi'
7
+
8
+ module Toji
9
+ module Progress
10
+ end
11
+ end
@@ -0,0 +1,165 @@
1
+ module Toji
2
+ module Progress
3
+ class Job
4
+ HOUR = 60 * 60
5
+ DAY = 24 * HOUR
6
+
7
+ WARM_DAKI = 1
8
+ WARM_ANKA = 1<<1
9
+ WARM_MAT = 1<<2
10
+
11
+ attr_accessor :jobs
12
+
13
+ attr_accessor :time
14
+ attr_accessor :elapsed_time
15
+ attr_accessor :id
16
+ attr_accessor :before_temp
17
+ attr_accessor :after_temp
18
+
19
+ attr_accessor :preset_temp
20
+ attr_accessor :room_temp
21
+ attr_accessor :room_psychrometry
22
+
23
+ attr_accessor :baume
24
+ attr_accessor :nihonshudo
25
+ attr_accessor :acid
26
+ attr_accessor :amino_acid
27
+ attr_accessor :alcohol
28
+
29
+ attr_accessor :warming
30
+ attr_accessor :note
31
+
32
+ def initialize(
33
+ time: nil, elapsed_time: nil, id: nil, before_temp: nil, after_temp: nil,
34
+ preset_temp: nil, room_temp: nil, room_psychrometry: nil,
35
+ baume: nil, nihonshudo: nil, acid: nil, amino_acid: nil, alcohol: nil,
36
+ warming: nil, note: nil)
37
+ @time = time
38
+ @elapsed_time = elapsed_time
39
+ @id = id
40
+ @before_temp = before_temp
41
+ @after_temp = after_temp
42
+
43
+ @preset_temp = preset_temp
44
+ @room_temp = room_temp
45
+ @room_psychrometry = room_psychrometry
46
+
47
+ @baume = baume
48
+ @nihonshudo = nihonshudo
49
+ @acid = acid
50
+ @amino_acid = amino_acid
51
+ @alcohol = alcohol
52
+
53
+ @warming = warming
54
+ @note = note
55
+ end
56
+
57
+ def temps
58
+ result = []
59
+
60
+ if @before_temp
61
+ result << @before_temp
62
+ end
63
+
64
+ if @after_temp
65
+ result << @after_temp
66
+ end
67
+
68
+ result
69
+ end
70
+
71
+ def baume
72
+ if @baume
73
+ @baume
74
+ elsif @nihonshudo
75
+ @nihonshudo * -0.1
76
+ end
77
+ end
78
+
79
+ def nihonshudo
80
+ if @nihonshudo
81
+ @nihonshudo
82
+ elsif @baume
83
+ @baume * -10
84
+ else
85
+ nil
86
+ end
87
+ end
88
+
89
+ def baume_display
90
+ if @baume || @nihonshudo
91
+ b = baume
92
+ if b<3.0
93
+ nihonshudo
94
+ else
95
+ b
96
+ end
97
+ end
98
+ end
99
+
100
+ def moromi_time
101
+ tome = jobs[:tome]
102
+ if tome
103
+ time = elapsed_time - tome.elapsed_time
104
+ if 0<time
105
+ return time
106
+ end
107
+ end
108
+ nil
109
+ end
110
+
111
+ def moromi_day
112
+ moromi_t = moromi_time
113
+ if moromi_t
114
+ (moromi_t.to_f / Job::DAY).floor + 1
115
+ end
116
+ end
117
+
118
+ def bmd
119
+ _moromi_day = moromi_day
120
+ _baume = baume
121
+
122
+ if _moromi_day && _baume
123
+ _moromi_day * _baume
124
+ end
125
+ end
126
+
127
+ def warmings
128
+ result = []
129
+ if @warming & WARM_DAKI
130
+ result << :daki
131
+ end
132
+ if @warming & WARM_ANKA
133
+ result << :anka
134
+ end
135
+ if @warming & WARM_MAT
136
+ result << :mat
137
+ end
138
+ result
139
+ end
140
+
141
+ def to_h
142
+ {
143
+ time: time,
144
+ elapsed_time: elapsed_time,
145
+ id: id,
146
+ preset_temp: preset_temp,
147
+ before_temp: before_temp,
148
+ after_temp: after_temp,
149
+ temps: temps,
150
+ room_temp: room_temp,
151
+ room_psychrometry: room_psychrometry,
152
+ baume: baume,
153
+ nihonshudo: nihonshudo,
154
+ acid: acid,
155
+ amino_acid: amino_acid,
156
+ alcohol: alcohol,
157
+ warmings: warmings,
158
+ moromi_day: moromi_day,
159
+ bmd: bmd,
160
+ note: note,
161
+ }
162
+ end
163
+ end
164
+ end
165
+ end