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
@@ -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.