toji 1.6.8 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,35 @@
1
+ module Toji
2
+ module Ingredient
3
+ class RiceRate
4
+ # 浸漬米吸水率
5
+ attr_reader :soaked_rate
6
+
7
+ # 蒸し前浸漬米吸水率
8
+ # 炊飯の場合は水を追加
9
+ # 蒸しの場合は一晩経って蒸発した分を削減
10
+ attr_reader :before_steaming_rate
11
+
12
+ # 蒸米吸水率
13
+ attr_reader :steamed_rate
14
+
15
+ # 放冷後蒸米吸水率
16
+ attr_reader :cooled_rate
17
+
18
+ def initialize(soaked_rate, before_steaming_rate, steamed_rate, cooled_rate)
19
+ @soaked_rate = soaked_rate
20
+ @before_steaming_rate = before_steaming_rate
21
+ @steamed_rate = steamed_rate
22
+ @cooled_rate = cooled_rate
23
+ end
24
+
25
+ def before_steaming_rate
26
+ @before_steaming_rate || begin
27
+ @soaked_rate - 0.04
28
+ end
29
+ end
30
+
31
+
32
+ DEFAULT = new(0.33, nil, 0.41, 0.33)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,65 @@
1
+ require 'toji/product/event'
2
+
3
+ module Toji
4
+ module Product
5
+ attr_reader :reduce_key
6
+ attr_accessor :name
7
+ attr_accessor :recipe
8
+ attr_accessor :start_date
9
+
10
+ def koji_dates
11
+ date = start_date
12
+ recipe.steps.map {|step|
13
+ date = date.next_day(step.koji_interval_days)
14
+ }
15
+ end
16
+
17
+ def kake_dates
18
+ date = start_date
19
+ recipe.steps.map {|step|
20
+ date = date.next_day(step.kake_interval_days)
21
+ }
22
+ end
23
+
24
+ def events
25
+ events = []
26
+
27
+ koji_dates.length.times {|i|
28
+ events << Event.new(self, :koji, i)
29
+ }
30
+
31
+ kake_dates.length
32
+ .times.map {|i|
33
+ Event.new(self, :kake, i)
34
+ }
35
+ .delete_if {|e|
36
+ 4<=e.index && e.weight==0
37
+ }
38
+ .each {|e|
39
+ events << e
40
+ }
41
+
42
+ events
43
+ end
44
+
45
+ def events_group
46
+ events.group_by{|event|
47
+ event.group_key
48
+ }.map {|group_key,events|
49
+ breakdown = events.map {|event|
50
+ {index: event.index, weight: event.weight}
51
+ }
52
+ if 1<breakdown.length
53
+ breakdown = breakdown.select{|event| 0<event[:weight]}
54
+ end
55
+
56
+ {
57
+ date: events.first.date,
58
+ type: events.first.type,
59
+ weight: events.map(&:weight).sum,
60
+ breakdown: breakdown,
61
+ }
62
+ }
63
+ end
64
+ end
65
+ end
@@ -1,6 +1,6 @@
1
1
  module Toji
2
- module Schedule
3
- class ProductEvent
2
+ module Product
3
+ class Event
4
4
  attr_reader :product
5
5
  attr_reader :type
6
6
  attr_reader :index
@@ -30,14 +30,14 @@ module Toji
30
30
 
31
31
  def group_key
32
32
  a = []
33
- a << (product.id || product.name)
33
+ a << product.reduce_key
34
34
  a << type
35
35
  a << group_index
36
36
  a.map(&:to_s).join(":")
37
37
  end
38
38
 
39
39
  def weight
40
- @product.recipe.steps[@index].send(@type).raw
40
+ @product.recipe.steps[@index].send(@type)
41
41
  end
42
42
 
43
43
  def to_h
@@ -1,11 +1,126 @@
1
- require 'toji/recipe/ingredient'
2
- require 'toji/recipe/rice_rate'
3
- require 'toji/recipe/koji_rate'
4
- require 'toji/recipe/yeast_rate'
5
1
  require 'toji/recipe/step'
6
- require 'toji/recipe/three_step_mashing'
7
2
 
8
3
  module Toji
9
4
  module Recipe
5
+ attr_accessor :steps
6
+
7
+ def scale(rice_total)
8
+ rate = rice_total / steps.map(&:rice_total).sum
9
+ new_steps = steps.map {|step|
10
+ step * rate
11
+ }
12
+
13
+ self.class.new.tap {|o|
14
+ o.steps = new_steps
15
+ }
16
+ end
17
+
18
+ def round(ndigit=0, half: :up)
19
+ new_steps = steps.map {|step|
20
+ step.round(ndigit, half: half)
21
+ }
22
+
23
+ self.class.new.tap {|o|
24
+ o.steps = new_steps
25
+ }
26
+ end
27
+
28
+ # 内容量の累計
29
+ def cumulative_weight_totals
30
+ weight_total = steps.map(&:weight_total)
31
+
32
+ weight_total.map.with_index {|x,i|
33
+ weight_total[0..i].inject(:+)
34
+ }
35
+ end
36
+
37
+ # 総米の累計
38
+ def cumulative_rice_totals
39
+ rice_total = steps.map(&:rice_total)
40
+
41
+ rice_total.map.with_index {|x,i|
42
+ rice_total[0..i].inject(&:+)
43
+ }
44
+ end
45
+
46
+ # 酒母歩合の累計
47
+ def cumulative_shubo_rates
48
+ rice_total = steps.map(&:rice_total)
49
+ shubo = rice_total.first
50
+
51
+ rice_total.map.with_index {|x,i|
52
+ shubo / rice_total[0..i].inject(&:+)
53
+ }
54
+ end
55
+
56
+ # 酒母歩合
57
+ #
58
+ # 7%が標準である
59
+ # 汲水歩合が大きい高温糖化酒母では6%程度である
60
+ #
61
+ # 出典: 酒造教本 P96
62
+ def shubo_rate
63
+ cumulative_shubo_rates.last || 0.0
64
+ end
65
+
66
+ # 白米比率
67
+ #
68
+ # 発酵型と白米比率
69
+ # 発酵の型 酒母 添 仲 留 特徴
70
+ # 湧き進め型 1 2 4 6 短期醪、辛口、軽快な酒質
71
+ # 湧き抑え型 1 2 4 7 長期醪、甘口、おだやかな酒質
72
+ #
73
+ # 出典: 酒造教本 P95
74
+ def rice_rates
75
+ steps.map {|step|
76
+ step.rice_total / steps.first.rice_total
77
+ }
78
+ end
79
+
80
+ def table_data
81
+ headers = [""] + @steps.map(&:name) + [:total]
82
+ keys = [:rice_total, :kake, :koji, :alcohol, :water, :lactic_acid]
83
+
84
+ cells = [keys]
85
+ cells += @steps.map {|step|
86
+ [step.rice_total, step.kake, step.koji, step.alcohol, step.water, step.lactic_acid]
87
+ }
88
+ cells << keys.map {|key|
89
+ @steps.map(&key).compact.sum
90
+ }
91
+
92
+ cells = cells.map {|cell|
93
+ cell.map {|c|
94
+ case c
95
+ when NilClass
96
+ ""
97
+ when 0
98
+ ""
99
+ else
100
+ c
101
+ end
102
+ }
103
+ }
104
+
105
+ {header: headers, rows: cells.transpose}
106
+ end
107
+
108
+ def table
109
+ data = table_data
110
+
111
+ Plotly::Plot.new(
112
+ data: [{
113
+ type: :table,
114
+ header: {
115
+ values: data[:header]
116
+ },
117
+ cells: {
118
+ values: data[:rows].transpose
119
+ },
120
+ }],
121
+ layout: {
122
+ }
123
+ )
124
+ end
10
125
  end
11
126
  end
@@ -1,30 +1,19 @@
1
1
  module Toji
2
2
  module Recipe
3
- class Step
4
- attr_reader :name
5
- attr_reader :rice
6
- attr_reader :koji
7
- attr_reader :water
8
- attr_reader :lactic_acid
9
- attr_reader :alcohol
10
-
11
- def initialize(name:, rice: 0, koji: 0, water: 0, lactic_acid: 0, alcohol: 0)
12
- @name = name
13
- @rice = Ingredient::Rice::Expected.create(rice)
14
- @koji = Ingredient::Koji::Expected.create(koji)
15
- @water = water.to_f
16
- @lactic_acid = lactic_acid.to_f
17
- @alcohol = alcohol.to_f
18
- end
3
+ module Step
4
+ attr_accessor :name
5
+ attr_accessor :kake
6
+ attr_accessor :koji
7
+ attr_accessor :water
8
+ attr_accessor :lactic_acid
9
+ attr_accessor :alcohol
10
+ attr_accessor :yeast
11
+ attr_accessor :koji_interval_days
12
+ attr_accessor :kake_interval_days
19
13
 
20
14
  # 総米
21
15
  def rice_total
22
- @rice.raw + @koji.raw
23
- end
24
-
25
- # 総重量
26
- def weight_total
27
- @rice.cooled + @koji.dekoji + @water + @lactic_acid + @alcohol
16
+ kake + koji
28
17
  end
29
18
 
30
19
  # 麹歩合
@@ -33,7 +22,7 @@ module Toji
33
22
  # なお、留め仕込みまでの麹歩合が20%を下回ると蒸米の溶解糖化に影響が出るので注意がいる
34
23
  # 出典: 酒造教本 P95
35
24
  def koji_rate
36
- ret = @koji.raw / rice_total
25
+ ret = koji / rice_total
37
26
  ret.nan? ? 0.0 : ret
38
27
  end
39
28
 
@@ -47,7 +36,7 @@ module Toji
47
36
  #
48
37
  # 出典: 酒造教本 P96
49
38
  def water_rate
50
- ret = @water / rice_total
39
+ ret = water / rice_total
51
40
  ret.nan? ? 0.0 : ret
52
41
  end
53
42
 
@@ -56,26 +45,32 @@ module Toji
56
45
  acid_ndigit = ndigit + 3
57
46
  end
58
47
 
59
- self.class.new(
60
- name: @name,
61
- rice: @rice.round(ndigit, half: half),
62
- koji: @koji.round(ndigit, half: half),
63
- water: @water.round(ndigit, half: half),
64
- lactic_acid: @lactic_acid.round(acid_ndigit, half: half),
65
- alcohol: @alcohol.round(ndigit, half: half)
66
- )
48
+ self.class.new.tap {|o|
49
+ o.name = name
50
+ o.kake = kake.round(ndigit, half: half)
51
+ o.koji = koji.round(ndigit, half: half)
52
+ o.water = water.round(ndigit, half: half)
53
+ o.lactic_acid = lactic_acid.round(acid_ndigit, half: half)
54
+ o.alcohol = alcohol.round(ndigit, half: half)
55
+ o.yeast = yeast.round(ndigit, half: half)
56
+ o.koji_interval_days = koji_interval_days
57
+ o.kake_interval_days = kake_interval_days
58
+ }
67
59
  end
68
60
 
69
61
  def +(other)
70
62
  if Step===other
71
- self.class.new(
72
- name: nil,
73
- rice: @rice + other.rice,
74
- koji: @koji + other.koji,
75
- water: @water + other.water,
76
- lactic_acid: @lactic_acid + other.lactic_acid,
77
- alcohol: @alcohol + other.alcohol
78
- )
63
+ self.class.new.tap {|o|
64
+ o.name = nil
65
+ o.kake = kake + other.kake
66
+ o.koji = koji + other.koji
67
+ o.water = water + other.water
68
+ o.lactic_acid = lactic_acid + other.lactic_acid
69
+ o.alcohol = alcohol + other.alcohol
70
+ o.yeast = yeast + other.yeast
71
+ o.koji_interval_days = koji_interval_days
72
+ o.kake_interval_days = kake_interval_days
73
+ }
79
74
  else
80
75
  x, y = other.coerce(self)
81
76
  x + y
@@ -84,30 +79,22 @@ module Toji
84
79
 
85
80
  def *(other)
86
81
  if Integer===other || Float===other
87
- self.class.new(
88
- name: @name,
89
- rice: @rice * other,
90
- koji: @koji * other,
91
- water: @water * other,
92
- lactic_acid: @lactic_acid * other,
93
- alcohol: @alcohol * other
94
- )
82
+ self.class.new.tap {|o|
83
+ o.name = name
84
+ o.kake = kake * other
85
+ o.koji = koji * other
86
+ o.water = water * other
87
+ o.lactic_acid = lactic_acid * other
88
+ o.alcohol = alcohol * other
89
+ o.yeast = yeast * other
90
+ o.koji_interval_days = koji_interval_days
91
+ o.kake_interval_days = kake_interval_days
92
+ }
95
93
  else
96
94
  x, y = other.coerce(self)
97
95
  x * y
98
96
  end
99
97
  end
100
-
101
- def to_h
102
- {
103
- name: name,
104
- rice: rice.raw,
105
- koji: koji.raw,
106
- water: water,
107
- lactic_acid: lactic_acid,
108
- alcohol: alcohol,
109
- }
110
- end
111
98
  end
112
99
  end
113
100
  end
@@ -1,3 +1,3 @@
1
1
  module Toji
2
- VERSION = "1.6.8"
2
+ VERSION = "2.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toji
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.8
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshida Tetsuya
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-18 00:00:00.000000000 Z
11
+ date: 2020-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -109,6 +109,11 @@ files:
109
109
  - Rakefile
110
110
  - bin/console
111
111
  - bin/setup
112
+ - example/calendar.ipynb
113
+ - example/calendar.yaml
114
+ - example/calendar_file.ipynb
115
+ - example/example_core.rb
116
+ - example/kake_recipe.rb
112
117
  - example/koji_making.ipynb
113
118
  - example/koji_making.rb
114
119
  - example/koji_making.yaml
@@ -117,14 +122,10 @@ files:
117
122
  - example/moromi.ipynb
118
123
  - example/moromi.rb
119
124
  - example/moromi.yaml
120
- - example/rice_recipe.rb
121
- - example/schedule.ipynb
122
- - example/schedule.yaml
123
- - example/schedule_file.ipynb
125
+ - example/recipe.rb
124
126
  - example/shubo.ipynb
125
127
  - example/shubo.rb
126
128
  - example/shubo.yaml
127
- - example/three_step_mashing_recipe.rb
128
129
  - lib/toji.rb
129
130
  - lib/toji/brew.rb
130
131
  - lib/toji/brew/base.rb
@@ -138,38 +139,31 @@ files:
138
139
  - lib/toji/brew/moromi.rb
139
140
  - lib/toji/brew/shubo.rb
140
141
  - lib/toji/brew/state.rb
141
- - lib/toji/brew/state_accessor.rb
142
- - lib/toji/brew/state_record.rb
142
+ - lib/toji/brew/state_wrapper.rb
143
+ - lib/toji/calendar.rb
144
+ - lib/toji/calendar/date_column.rb
145
+ - lib/toji/calendar/date_row.rb
146
+ - lib/toji/ingredient.rb
147
+ - lib/toji/ingredient/kake.rb
148
+ - lib/toji/ingredient/kake/actual.rb
149
+ - lib/toji/ingredient/kake/base.rb
150
+ - lib/toji/ingredient/kake/expected.rb
151
+ - lib/toji/ingredient/koji.rb
152
+ - lib/toji/ingredient/koji/actual.rb
153
+ - lib/toji/ingredient/koji/actual_fermentable.rb
154
+ - lib/toji/ingredient/koji/base.rb
155
+ - lib/toji/ingredient/koji/expected.rb
156
+ - lib/toji/ingredient/koji/expected_fermentable.rb
157
+ - lib/toji/ingredient/koji_rate.rb
158
+ - lib/toji/ingredient/rice.rb
159
+ - lib/toji/ingredient/rice/actual_steamable.rb
160
+ - lib/toji/ingredient/rice/base.rb
161
+ - lib/toji/ingredient/rice/expected_steamable.rb
162
+ - lib/toji/ingredient/rice_rate.rb
163
+ - lib/toji/product.rb
164
+ - lib/toji/product/event.rb
143
165
  - lib/toji/recipe.rb
144
- - lib/toji/recipe/ingredient.rb
145
- - lib/toji/recipe/ingredient/koji.rb
146
- - lib/toji/recipe/ingredient/koji/actual.rb
147
- - lib/toji/recipe/ingredient/koji/actual_fermentable.rb
148
- - lib/toji/recipe/ingredient/koji/base.rb
149
- - lib/toji/recipe/ingredient/koji/expected.rb
150
- - lib/toji/recipe/ingredient/koji/expected_fermentable.rb
151
- - lib/toji/recipe/ingredient/rice.rb
152
- - lib/toji/recipe/ingredient/rice/actual.rb
153
- - lib/toji/recipe/ingredient/rice/actual_steamable.rb
154
- - lib/toji/recipe/ingredient/rice/base.rb
155
- - lib/toji/recipe/ingredient/rice/expected.rb
156
- - lib/toji/recipe/ingredient/rice/expected_steamable.rb
157
- - lib/toji/recipe/ingredient/yeast.rb
158
- - lib/toji/recipe/koji_rate.rb
159
- - lib/toji/recipe/rice_rate.rb
160
- - lib/toji/recipe/rice_rate/base.rb
161
- - lib/toji/recipe/rice_rate/cooked.rb
162
- - lib/toji/recipe/rice_rate/steamed.rb
163
166
  - lib/toji/recipe/step.rb
164
- - lib/toji/recipe/three_step_mashing.rb
165
- - lib/toji/recipe/yeast_rate.rb
166
- - lib/toji/schedule.rb
167
- - lib/toji/schedule/calendar.rb
168
- - lib/toji/schedule/date_column.rb
169
- - lib/toji/schedule/date_interval_enumerator.rb
170
- - lib/toji/schedule/date_row.rb
171
- - lib/toji/schedule/product.rb
172
- - lib/toji/schedule/product_event.rb
173
167
  - lib/toji/version.rb
174
168
  - toji.gemspec
175
169
  homepage: https://github.com/yoshida-eth0/ruby-toji
@@ -194,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
188
  - !ruby/object:Gem::Version
195
189
  version: '0'
196
190
  requirements: []
197
- rubygems_version: 3.0.3
191
+ rubygems_version: 3.1.2
198
192
  signing_key:
199
193
  specification_version: 4
200
194
  summary: Management tools for brewing japanese sake.