toji 2.12.0 → 2.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/example/calendar.ipynb +42 -51
- data/example/calendar.yaml +6 -6
- data/example/calendar_file.ipynb +35 -35
- data/example/example_core.rb +850 -230
- data/example/kake_ingredient.rb +21 -15
- data/example/koji_ingredient.rb +31 -21
- data/example/{koji_making.ipynb → koji_progress.ipynb} +14 -14
- data/example/{koji_making.rb → koji_progress.rb} +3 -2
- data/example/{koji_making.yaml → koji_progress.yaml} +8 -9
- data/example/{koji_making_multi.ipynb → koji_progress_multi.ipynb} +21 -22
- data/example/{moromi.ipynb → moromi_progress.ipynb} +22 -22
- data/example/{moromi.rb → moromi_progress.rb} +3 -2
- data/example/{moromi.yaml → moromi_progress.yaml} +0 -0
- data/example/moto_progress.ipynb +121 -0
- data/example/{moto.rb → moto_progress.rb} +3 -2
- data/example/{moto.yaml → moto_progress.yaml} +14 -15
- data/example/recipe.rb +44 -32
- data/lib/toji.rb +4 -2
- data/lib/toji/calendar.rb +12 -12
- data/lib/toji/calendar/date_column.rb +8 -8
- data/lib/toji/calendar/date_row.rb +6 -6
- data/lib/toji/ingredient.rb +6 -2
- data/lib/toji/ingredient/alcohol.rb +14 -0
- data/lib/toji/ingredient/base.rb +11 -0
- data/lib/toji/ingredient/kake.rb +3 -9
- data/lib/toji/ingredient/koji.rb +19 -10
- data/lib/toji/ingredient/lactic_acid.rb +14 -0
- data/lib/toji/ingredient/rice.rb +50 -4
- data/lib/toji/ingredient/tanekoji.rb +29 -0
- data/lib/toji/ingredient/water.rb +18 -0
- data/lib/toji/ingredient/yeast.rb +20 -0
- data/lib/toji/processing.rb +18 -0
- data/lib/toji/processing/base.rb +7 -0
- data/lib/toji/processing/cooled_rice.rb +22 -0
- data/lib/toji/processing/cooled_rice_element.rb +8 -0
- data/lib/toji/processing/dekoji.rb +22 -0
- data/lib/toji/processing/dekoji_element.rb +8 -0
- data/lib/toji/processing/kake_processing.rb +7 -0
- data/lib/toji/processing/koji_processing.rb +10 -0
- data/lib/toji/processing/rice_processing.rb +19 -0
- data/lib/toji/processing/soaked_rice.rb +49 -0
- data/lib/toji/processing/soaked_rice_element.rb +18 -0
- data/lib/toji/processing/steamed_rice.rb +22 -0
- data/lib/toji/processing/steamed_rice_element.rb +8 -0
- data/lib/toji/product.rb +11 -32
- data/lib/toji/product/schedule_factory.rb +74 -0
- data/lib/toji/progress.rb +23 -0
- data/lib/toji/progress/base_progress.rb +37 -0
- data/lib/toji/progress/base_state.rb +39 -0
- data/lib/toji/progress/builder.rb +53 -0
- data/lib/toji/progress/graph.rb +11 -0
- data/lib/toji/{brew → progress}/graph/ab.rb +4 -4
- data/lib/toji/{brew → progress}/graph/bmd.rb +2 -2
- data/lib/toji/{brew/graph/multi_progress.rb → progress/graph/multi_progress_note.rb} +11 -11
- data/lib/toji/{brew/graph/progress.rb → progress/graph/progress_note.rb} +20 -18
- data/lib/toji/progress/koji_progress.rb +15 -0
- data/lib/toji/progress/koji_state.rb +23 -0
- data/lib/toji/{brew/moromi.rb → progress/moromi_progress.rb} +9 -5
- data/lib/toji/progress/moromi_state.rb +77 -0
- data/lib/toji/progress/moto_progress.rb +15 -0
- data/lib/toji/progress/moto_state.rb +31 -0
- data/lib/toji/progress/progress.rb +15 -0
- data/lib/toji/progress/state.rb +9 -0
- data/lib/toji/progress/state/baume_to_nihonshudo.rb +21 -0
- data/lib/toji/progress/state/nihonshudo_to_baume.rb +21 -0
- data/lib/toji/recipe.rb +53 -39
- data/lib/toji/recipe/ab_expect.rb +2 -2
- data/lib/toji/recipe/action.rb +2 -2
- data/lib/toji/recipe/step.rb +97 -71
- data/lib/toji/schedule.rb +5 -0
- data/lib/toji/schedule/action_schedule.rb +9 -0
- data/lib/toji/{event → schedule}/base.rb +1 -1
- data/lib/toji/schedule/kake_schedule.rb +11 -0
- data/lib/toji/schedule/koji_schedule.rb +11 -0
- data/lib/toji/schedule/rice_schedule.rb +16 -0
- data/lib/toji/utils.rb +43 -0
- data/lib/toji/version.rb +1 -1
- metadata +58 -44
- data/lib/toji/brew.rb +0 -18
- data/lib/toji/brew/base.rb +0 -55
- data/lib/toji/brew/builder.rb +0 -98
- data/lib/toji/brew/graph.rb +0 -11
- data/lib/toji/brew/koji.rb +0 -11
- data/lib/toji/brew/moto.rb +0 -11
- data/lib/toji/brew/state.rb +0 -122
- data/lib/toji/brew/wrapped_state.rb +0 -109
- data/lib/toji/event.rb +0 -5
- data/lib/toji/event/action_event.rb +0 -12
- data/lib/toji/event/kake_event.rb +0 -13
- data/lib/toji/event/koji_event.rb +0 -19
- data/lib/toji/event/rice_event.rb +0 -34
- data/lib/toji/ingredient/kake/actual.rb +0 -26
- data/lib/toji/ingredient/kake/base.rb +0 -18
- data/lib/toji/ingredient/kake/expected.rb +0 -40
- data/lib/toji/ingredient/koji/actual.rb +0 -29
- data/lib/toji/ingredient/koji/actual_fermentable.rb +0 -15
- data/lib/toji/ingredient/koji/base.rb +0 -35
- data/lib/toji/ingredient/koji/expected.rb +0 -45
- data/lib/toji/ingredient/koji/expected_fermentable.rb +0 -15
- data/lib/toji/ingredient/koji_rate.rb +0 -16
- data/lib/toji/ingredient/rice/actual_steamable.rb +0 -27
- data/lib/toji/ingredient/rice/base.rb +0 -40
- data/lib/toji/ingredient/rice/expected_steamable.rb +0 -27
- data/lib/toji/ingredient/rice_rate.rb +0 -23
- data/lib/toji/product/event_factory.rb +0 -70
@@ -1,7 +1,7 @@
|
|
1
1
|
module Toji
|
2
|
-
module
|
2
|
+
module Progress
|
3
3
|
module Graph
|
4
|
-
class
|
4
|
+
class ProgressNote
|
5
5
|
|
6
6
|
PLOT_KEYS = [:temps, :preset_temp, :room_temp, :room_psychrometry, :baume, :acid, :amino_acid, :alcohol, :bmd].freeze
|
7
7
|
|
@@ -26,13 +26,13 @@ module Toji
|
|
26
26
|
:dashdot,
|
27
27
|
].freeze
|
28
28
|
|
29
|
-
attr_reader :
|
29
|
+
attr_reader :progress
|
30
30
|
attr_accessor :name
|
31
31
|
attr_accessor :dash
|
32
32
|
attr_accessor :enable_annotations
|
33
33
|
|
34
|
-
def initialize(
|
35
|
-
@
|
34
|
+
def initialize(progress, name: nil, dash: :solid, enable_annotations: true)
|
35
|
+
@progress = progress
|
36
36
|
@name = name
|
37
37
|
@dash = dash
|
38
38
|
@enable_annotations = enable_annotations
|
@@ -40,7 +40,7 @@ module Toji
|
|
40
40
|
|
41
41
|
def plot_data(keys=nil, use_name=false)
|
42
42
|
if !keys
|
43
|
-
keys = @
|
43
|
+
keys = @progress.has_keys
|
44
44
|
end
|
45
45
|
|
46
46
|
name = ""
|
@@ -56,7 +56,7 @@ module Toji
|
|
56
56
|
xs = []
|
57
57
|
ys = []
|
58
58
|
text = []
|
59
|
-
@
|
59
|
+
@progress.states.each {|s|
|
60
60
|
val = s.send(key)
|
61
61
|
if val
|
62
62
|
[val].flatten.each_with_index {|v,i|
|
@@ -75,7 +75,7 @@ module Toji
|
|
75
75
|
result << {x: xs, y: ys, text: text, name: "#{name}#{key}", line: {dash: @dash, shape: line_shape}, marker: {color: PLOT_COLORS[key]}}
|
76
76
|
}
|
77
77
|
|
78
|
-
if 0<@
|
78
|
+
if 0<@progress.states.length && 0<@progress.day_offset
|
79
79
|
result = result.map{|h|
|
80
80
|
h[:x].unshift(0)
|
81
81
|
h[:y].unshift(nil)
|
@@ -84,8 +84,8 @@ module Toji
|
|
84
84
|
}
|
85
85
|
end
|
86
86
|
|
87
|
-
#if 0<@
|
88
|
-
# t = @
|
87
|
+
#if 0<@progress.states.length && @progress.states.last.time.strftime("%T")!="00:00:00"
|
88
|
+
# t = @progress.states.last.elapsed_time_with_offset
|
89
89
|
# t -= (t % DAY) - DAY
|
90
90
|
#
|
91
91
|
# result = result.map{|h|
|
@@ -102,7 +102,7 @@ module Toji
|
|
102
102
|
def annotations
|
103
103
|
return [] if !@enable_annotations
|
104
104
|
|
105
|
-
@
|
105
|
+
@progress.states.select{|s| s.mark}.map {|s|
|
106
106
|
{
|
107
107
|
x: s.elapsed_time_with_offset,
|
108
108
|
y: s.temps.first || 0,
|
@@ -119,19 +119,21 @@ module Toji
|
|
119
119
|
|
120
120
|
def table_data(keys=nil)
|
121
121
|
if !keys
|
122
|
-
keys = @
|
122
|
+
keys = @progress.has_keys
|
123
123
|
keys.delete(:elapsed_time)
|
124
124
|
keys.delete(:time)
|
125
125
|
keys.delete(:day)
|
126
126
|
keys.delete(:moromi_day)
|
127
|
-
keys.
|
128
|
-
|
127
|
+
if keys.include?(:display_baume)
|
128
|
+
keys.delete(:baume)
|
129
|
+
keys.delete(:nihonshudo)
|
130
|
+
end
|
129
131
|
else
|
130
|
-
keys &= @
|
132
|
+
keys &= @progress.has_keys
|
131
133
|
end
|
132
134
|
|
133
135
|
rows = []
|
134
|
-
@
|
136
|
+
@progress.states.each {|state|
|
135
137
|
rows << keys.map {|k|
|
136
138
|
v = state&.send(k)
|
137
139
|
if Array===v
|
@@ -155,8 +157,8 @@ module Toji
|
|
155
157
|
layout: {
|
156
158
|
xaxis: {
|
157
159
|
dtick: DAY,
|
158
|
-
tickvals: @
|
159
|
-
ticktext: @
|
160
|
+
tickvals: @progress.days.times.map{|d| d*DAY},
|
161
|
+
ticktext: @progress.day_labels
|
160
162
|
},
|
161
163
|
annotations: annotations,
|
162
164
|
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module KojiProgress
|
4
|
+
include BaseProgress
|
5
|
+
|
6
|
+
def all_keys
|
7
|
+
KojiState::REQUIRED_KEYS + KojiState::OPTIONAL_KEYS
|
8
|
+
end
|
9
|
+
|
10
|
+
def progress_note(name: nil, dash: :solid, enable_annotations: true)
|
11
|
+
Graph::ProgressNote.new(self, name: name, dash: dash, enable_annotations: enable_annotations)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module KojiState
|
4
|
+
include BaseState
|
5
|
+
|
6
|
+
OPTIONAL_KEYS = [
|
7
|
+
:temps,
|
8
|
+
:preset_temp,
|
9
|
+
:room_temp,
|
10
|
+
:room_psychrometry,
|
11
|
+
|
12
|
+
:note,
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
attr_accessor :temps
|
16
|
+
attr_accessor :preset_temp
|
17
|
+
attr_accessor :room_temp
|
18
|
+
attr_accessor :room_psychrometry
|
19
|
+
|
20
|
+
attr_accessor :note
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Toji
|
2
|
-
module
|
3
|
-
module
|
4
|
-
include
|
2
|
+
module Progress
|
3
|
+
module MoromiProgress
|
4
|
+
include BaseProgress
|
5
5
|
|
6
6
|
attr_accessor :prefix_day_labels
|
7
7
|
|
@@ -28,8 +28,12 @@ module Toji
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
|
31
|
+
def all_keys
|
32
|
+
MoromiState::REQUIRED_KEYS + MoromiState::OPTIONAL_KEYS
|
33
|
+
end
|
34
|
+
|
35
|
+
def progress_note(name: nil, dash: :solid, enable_annotations: true)
|
36
|
+
Graph::ProgressNote.new(self, name: name, dash: dash, enable_annotations: enable_annotations)
|
33
37
|
end
|
34
38
|
|
35
39
|
def bmd
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module MoromiState
|
4
|
+
include BaseState
|
5
|
+
|
6
|
+
OPTIONAL_KEYS = [
|
7
|
+
:moromi_day,
|
8
|
+
:temps,
|
9
|
+
:preset_temp,
|
10
|
+
:room_temp,
|
11
|
+
:room_psychrometry,
|
12
|
+
|
13
|
+
:baume,
|
14
|
+
:nihonshudo,
|
15
|
+
:display_baume,
|
16
|
+
:acid,
|
17
|
+
:amino_acid,
|
18
|
+
:alcohol,
|
19
|
+
:bmd,
|
20
|
+
|
21
|
+
:warmings,
|
22
|
+
:note,
|
23
|
+
].freeze
|
24
|
+
|
25
|
+
attr_accessor :temps
|
26
|
+
attr_accessor :preset_temp
|
27
|
+
attr_accessor :room_temp
|
28
|
+
attr_accessor :room_psychrometry
|
29
|
+
|
30
|
+
attr_accessor :baume
|
31
|
+
attr_accessor :nihonshudo
|
32
|
+
attr_accessor :acid
|
33
|
+
attr_accessor :amino_acid
|
34
|
+
attr_accessor :alcohol
|
35
|
+
|
36
|
+
attr_accessor :warmings
|
37
|
+
attr_accessor :note
|
38
|
+
|
39
|
+
def moromi_day
|
40
|
+
_tome_day = progress.moromi_tome_day
|
41
|
+
_now_day = day
|
42
|
+
|
43
|
+
if _tome_day && _tome_day < _now_day
|
44
|
+
_now_day - _tome_day + 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def display_baume
|
49
|
+
_baume = baume
|
50
|
+
if _baume
|
51
|
+
if _baume<3.0
|
52
|
+
nihonshudo
|
53
|
+
else
|
54
|
+
_baume
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def bmd
|
60
|
+
_moromi_day = moromi_day
|
61
|
+
_baume = baume
|
62
|
+
|
63
|
+
if _moromi_day && _baume
|
64
|
+
_moromi_day * _baume
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def expected_alcohol(target_alc, target_nihonshudo, coef)
|
69
|
+
_baume = baume
|
70
|
+
|
71
|
+
if _baume
|
72
|
+
target_alc - (_baume - target_nihonshudo * -0.1) * coef
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module MotoProgress
|
4
|
+
include BaseProgress
|
5
|
+
|
6
|
+
def all_keys
|
7
|
+
MotoState::REQUIRED_KEYS + MotoState::OPTIONAL_KEYS
|
8
|
+
end
|
9
|
+
|
10
|
+
def progress_note(name: nil, dash: :solid, enable_annotations: true)
|
11
|
+
Graph::ProgressNote.new(self, name: name, dash: dash, enable_annotations: enable_annotations)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module MotoState
|
4
|
+
include BaseState
|
5
|
+
|
6
|
+
OPTIONAL_KEYS = [
|
7
|
+
:temps,
|
8
|
+
:preset_temp,
|
9
|
+
:room_temp,
|
10
|
+
:room_psychrometry,
|
11
|
+
|
12
|
+
:baume,
|
13
|
+
:acid,
|
14
|
+
|
15
|
+
:warmings,
|
16
|
+
:note,
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
attr_accessor :temps
|
20
|
+
attr_accessor :preset_temp
|
21
|
+
attr_accessor :room_temp
|
22
|
+
attr_accessor :room_psychrometry
|
23
|
+
|
24
|
+
attr_accessor :baume
|
25
|
+
attr_accessor :acid
|
26
|
+
|
27
|
+
attr_accessor :warmings
|
28
|
+
attr_accessor :note
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module State
|
4
|
+
module BaumeToNihonshudo
|
5
|
+
def nihonshudo
|
6
|
+
if self.baume
|
7
|
+
self.baume * -10
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def nihonshudo=(val)
|
12
|
+
if val
|
13
|
+
self.baume = val.to_f / -10.0
|
14
|
+
else
|
15
|
+
self.baume = nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module State
|
4
|
+
module NihonshudoToBaume
|
5
|
+
def baume
|
6
|
+
if self.nihonshudo
|
7
|
+
self.nihonshudo / -10.0
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def baume=(val)
|
12
|
+
if val
|
13
|
+
self.nihonshudo = val.to_f * -10
|
14
|
+
else
|
15
|
+
self.nihonshudo = nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/toji/recipe.rb
CHANGED
@@ -4,42 +4,44 @@ require 'toji/recipe/ab_expect'
|
|
4
4
|
|
5
5
|
module Toji
|
6
6
|
module Recipe
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
attr_reader :steps
|
8
|
+
attr_reader :actions
|
9
|
+
attr_reader :has_moto
|
10
|
+
attr_reader :has_moromi
|
11
|
+
attr_reader :ab_coef
|
12
|
+
attr_reader :ab_expects
|
13
|
+
|
14
|
+
def scale_rice_total(rice_total)
|
15
|
+
ratio = rice_total / steps.map(&:rice_total).sum
|
16
|
+
scale(ratio)
|
17
|
+
end
|
18
|
+
|
19
|
+
def scale!(ratio)
|
20
|
+
steps.each {|step|
|
21
|
+
step.scale!(ratio)
|
18
22
|
}
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def scale(ratio)
|
27
|
+
Utils.check_dup(self)
|
28
|
+
|
29
|
+
dst = self.dup
|
30
|
+
dst.scale!(ratio)
|
31
|
+
end
|
19
32
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
o.has_moto = has_moto
|
24
|
-
o.has_moromi = has_moromi
|
25
|
-
o.ab_coef = ab_coef
|
26
|
-
o.ab_expects = ab_expects.deep_dup
|
33
|
+
def round!(ndigit=0, mini_ndigit=nil, half: :up)
|
34
|
+
steps.each {|step|
|
35
|
+
step.round!(ndigit, mini_ndigit, half: half)
|
27
36
|
}
|
37
|
+
self
|
28
38
|
end
|
29
39
|
|
30
40
|
def round(ndigit=0, mini_ndigit=nil, half: :up)
|
31
|
-
|
32
|
-
step.round(ndigit, mini_ndigit, half: half)
|
33
|
-
}
|
41
|
+
Utils.check_dup(self)
|
34
42
|
|
35
|
-
self.
|
36
|
-
|
37
|
-
o.actions = actions.deep_dup
|
38
|
-
o.has_moto = has_moto
|
39
|
-
o.has_moromi = has_moromi
|
40
|
-
o.ab_coef = ab_coef
|
41
|
-
o.ab_expects = ab_expects.deep_dup
|
42
|
-
}
|
43
|
+
dst = self.dup
|
44
|
+
dst.round!(ndigit, mini_ndigit, half: half)
|
43
45
|
end
|
44
46
|
|
45
47
|
# 総米の累計
|
@@ -52,7 +54,7 @@ module Toji
|
|
52
54
|
end
|
53
55
|
|
54
56
|
# 酒母歩合の累計
|
55
|
-
def
|
57
|
+
def cumulative_moto_ratios
|
56
58
|
rice_total = steps.map(&:rice_total)
|
57
59
|
moto = rice_total.first
|
58
60
|
|
@@ -67,8 +69,8 @@ module Toji
|
|
67
69
|
# 汲水歩合が大きい高温糖化酒母では6%程度である
|
68
70
|
#
|
69
71
|
# 出典: 酒造教本 P96
|
70
|
-
def
|
71
|
-
|
72
|
+
def moto_ratio
|
73
|
+
cumulative_moto_ratios.last || 0.0
|
72
74
|
end
|
73
75
|
|
74
76
|
# 白米比率
|
@@ -79,22 +81,34 @@ module Toji
|
|
79
81
|
# 湧き抑え型 1 2 4 7 長期醪、甘口、おだやかな酒質
|
80
82
|
#
|
81
83
|
# 出典: 酒造教本 P95
|
82
|
-
def
|
84
|
+
def rice_ratios
|
83
85
|
steps.map {|step|
|
84
86
|
step.rice_total / steps.first.rice_total
|
85
87
|
}
|
86
88
|
end
|
87
89
|
|
88
90
|
def table_data
|
89
|
-
headers = [""] + steps.map.with_index{|s,i| :"
|
90
|
-
keys = [:rice_total, :
|
91
|
+
headers = [""] + steps.map.with_index{|s,i| :"Step#{i}"} + [:total]
|
92
|
+
keys = [["RiceTotal", :rice_total], ["Kake", :kakes], ["Koji", :kojis], ["Alcohol", :alcohols], ["Water", :waters], ["LacticAcid", :lactic_acids]]
|
91
93
|
|
92
|
-
cells = [keys]
|
94
|
+
cells = [keys.map(&:first)]
|
93
95
|
cells += steps.map {|step|
|
94
|
-
|
96
|
+
keys.map(&:last).map {|key|
|
97
|
+
vals = step.send(key)
|
98
|
+
if Numeric===vals
|
99
|
+
vals
|
100
|
+
else
|
101
|
+
vals.compact.map(&:weight).sum
|
102
|
+
end
|
103
|
+
}
|
95
104
|
}
|
96
|
-
cells << keys.map {|key|
|
97
|
-
steps.map(&key)
|
105
|
+
cells << keys.map(&:last).map {|key|
|
106
|
+
vals = steps.map(&key)
|
107
|
+
if Numeric===vals[0]
|
108
|
+
vals.sum
|
109
|
+
else
|
110
|
+
vals.flatten.compact.map(&:weight).sum
|
111
|
+
end
|
98
112
|
}
|
99
113
|
|
100
114
|
cells = cells.map {|cell|
|