toji 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/example/calendar.ipynb +281 -21
  3. data/example/calendar_file.ipynb +37 -37
  4. data/example/example_core.rb +27 -9
  5. data/example/{kake_recipe.rb → kake_ingredient.rb} +0 -1
  6. data/example/{koji_recipe.rb → koji_ingredient.rb} +1 -2
  7. data/example/koji_making.ipynb +9 -9
  8. data/example/koji_making.yaml +1 -0
  9. data/example/koji_making_multi.ipynb +22 -57
  10. data/example/moromi.ipynb +17 -17
  11. data/example/shubo.ipynb +12 -12
  12. data/example/shubo.yaml +2 -1
  13. data/lib/toji/brew.rb +4 -2
  14. data/lib/toji/brew/base.rb +6 -26
  15. data/lib/toji/brew/builder.rb +49 -21
  16. data/lib/toji/brew/graph/bmd.rb +1 -1
  17. data/lib/toji/brew/graph/multi_progress.rb +0 -121
  18. data/lib/toji/brew/graph/progress.rb +16 -51
  19. data/lib/toji/brew/koji.rb +2 -1
  20. data/lib/toji/brew/moromi.rb +2 -1
  21. data/lib/toji/brew/shubo.rb +2 -1
  22. data/lib/toji/brew/state.rb +1 -1
  23. data/lib/toji/brew/{state_wrapper.rb → wrapped_state.rb} +6 -5
  24. data/lib/toji/ingredient/kake.rb +2 -2
  25. data/lib/toji/ingredient/kake/actual.rb +6 -7
  26. data/lib/toji/ingredient/kake/base.rb +1 -1
  27. data/lib/toji/ingredient/kake/expected.rb +0 -1
  28. data/lib/toji/ingredient/koji.rb +2 -2
  29. data/lib/toji/ingredient/koji/actual.rb +8 -9
  30. data/lib/toji/ingredient/koji/base.rb +1 -1
  31. data/lib/toji/ingredient/koji/expected.rb +0 -1
  32. data/lib/toji/ingredient/rice/actual_steamable.rb +4 -4
  33. data/lib/toji/ingredient/rice/base.rb +0 -1
  34. data/lib/toji/ingredient/rice/expected_steamable.rb +1 -3
  35. data/lib/toji/ingredient/rice_rate.rb +2 -14
  36. data/lib/toji/recipe.rb +2 -11
  37. data/lib/toji/recipe/step.rb +9 -11
  38. data/lib/toji/version.rb +1 -1
  39. metadata +5 -5
@@ -1,6 +1,7 @@
1
1
  date_line: 0
2
2
  states:
3
- - elapsed_time: 0
3
+ - time: 2019-01-16
4
+ elapsed_time: 0
4
5
  mark: 水麹
5
6
  temps: 12.0
6
7
  acid: 13.0
@@ -1,12 +1,14 @@
1
1
  module Toji
2
2
  module Brew
3
- HOUR = 60 * 60
3
+ SECOND = 1
4
+ MINUTE = 60 * SECOND
5
+ HOUR = 60 * MINUTE
4
6
  DAY = 24 * HOUR
5
7
  end
6
8
  end
7
9
 
8
10
  require 'toji/brew/base'
9
- require 'toji/brew/state_wrapper'
11
+ require 'toji/brew/wrapped_state'
10
12
  require 'toji/brew/state'
11
13
  require 'toji/brew/builder'
12
14
  require 'toji/brew/graph'
@@ -1,6 +1,6 @@
1
1
  module Toji
2
2
  module Brew
3
- class Base
3
+ module Base
4
4
  include Enumerable
5
5
 
6
6
  REQUIRED_KEYS = [
@@ -29,18 +29,12 @@ module Toji
29
29
  :note,
30
30
  ].freeze
31
31
 
32
- attr_accessor :states
32
+ attr_accessor :wrapped_states
33
33
  attr_accessor :day_offset
34
- attr_accessor :min_time
35
-
36
- def initialize
37
- @states = []
38
- @day_offset = 0
39
- @min_time = 0
40
- end
34
+ attr_accessor :base_time
41
35
 
42
36
  def days
43
- ((@states.last.elapsed_time_with_offset.to_f + 1) / DAY).ceil
37
+ ((wrapped_states.last.elapsed_time_with_offset.to_f + 1) / DAY).ceil
44
38
  end
45
39
 
46
40
  def day_labels
@@ -52,30 +46,16 @@ module Toji
52
46
  end
53
47
 
54
48
  def each(&block)
55
- @states.each(&block)
49
+ wrapped_states.each(&block)
56
50
  end
57
51
 
58
52
  def has_keys
59
53
  result = REQUIRED_KEYS.dup
60
54
 
61
55
  result += OPTIONAL_KEYS.select {|k|
62
- @states.find {|s| s.send(k).present?}
56
+ wrapped_states.find {|s| s.send(k).present?}
63
57
  }
64
58
  end
65
-
66
- def to_h
67
- {
68
- states: map(&:to_h),
69
- has_keys: has_keys,
70
- day_offset: day_offset,
71
- days: days,
72
- day_labels: day_labels,
73
- }
74
- end
75
-
76
- def self.builder
77
- Builder.new(self)
78
- end
79
59
  end
80
60
  end
81
61
  end
@@ -7,6 +7,9 @@ module Toji
7
7
  @states = []
8
8
  @date_line = 0
9
9
  @prefix_day_labels = nil
10
+ @base_time = nil
11
+ @time_interpolation = false
12
+ @elapsed_time_interpolation = false
10
13
  end
11
14
 
12
15
  def <<(state)
@@ -17,8 +20,8 @@ module Toji
17
20
  end
18
21
  alias_method :add, :<<
19
22
 
20
- def date_line(val)
21
- @date_line = val
23
+ def date_line(val, unit=SECOND)
24
+ @date_line = (val * unit).to_i
22
25
  self
23
26
  end
24
27
 
@@ -27,39 +30,64 @@ module Toji
27
30
  self
28
31
  end
29
32
 
33
+ def time_interpolation(base_time)
34
+ @base_time = base_time&.to_time
35
+ @time_interpolation = true
36
+ #@elapsed_time_interpolation = false
37
+ self
38
+ end
39
+
40
+ def elapsed_time_interpolation
41
+ #@base_time = nil
42
+ #@time_interpolation = false
43
+ @elapsed_time_interpolation = true
44
+ self
45
+ end
46
+
30
47
  def build
31
48
  brew = @cls.new
32
49
 
33
- min_time = @states.map(&:time).compact.sort.first
34
- wrappers = @states.map{|r| StateWrapper.new(r.elapsed_time, r, brew)}
50
+ wrapped_states = @states.map{|s| WrappedState.new(s, brew)}
51
+
52
+ # time interpolation
53
+ if @time_interpolation
54
+ base_time = @base_time
55
+
56
+ base_state = wrapped_states.select{|w| w.time && w.elapsed_time}.first
57
+ if base_state
58
+ base_time = base_state.time - base_state.elapsed_time
59
+ end
60
+
61
+ wrapped_states.each {|w|
62
+ if w.elapsed_time
63
+ w.time = base_time + w.elapsed_time
64
+ end
65
+ }
66
+ end
35
67
 
36
- # time
37
- if min_time
38
- wrappers.each {|w|
39
- if w.state.time
40
- w.elapsed_time = (w.state.time - min_time).to_i
41
- w.time = w.state.time
42
- else
43
- #w.elapsed_time = w.state.elapsed_time
44
- w.time = min_time + w.state.elapsed_time
68
+ # elapsed_time interpolation
69
+ if @elapsed_time_interpolation
70
+ base_time = wrapped_states.map(&:time).sort.first
71
+ wrapped_states.each {|w|
72
+ if w.time
73
+ w.elapsed_time = (w.time - base_time).to_i
45
74
  end
46
75
  }
47
76
  end
48
- min_time = wrappers.first&.time
49
77
 
50
- wrappers = wrappers.sort{|a,b| a.elapsed_time<=>b.elapsed_time}
78
+ wrapped_states = wrapped_states.sort_by(&:elapsed_time)
79
+ base_time = wrapped_states.first&.time
51
80
 
52
81
  # day_offset
53
- t = wrappers.first&.time
54
82
  day_offset = 0
55
- if t
56
- day_offset = t - Time.mktime(t.year, t.month, t.day)
83
+ if base_time
84
+ day_offset = base_time - Time.mktime(base_time.year, base_time.month, base_time.day)
57
85
  end
58
- day_offset = (((24 - @date_line) * HOUR) + day_offset) % DAY
86
+ day_offset = (DAY - @date_line + day_offset) % DAY
59
87
 
60
- brew.states = wrappers
88
+ brew.wrapped_states = wrapped_states
61
89
  brew.day_offset = day_offset
62
- brew.min_time = min_time
90
+ brew.base_time = base_time
63
91
  if Moromi===brew
64
92
  brew.prefix_day_labels = @prefix_day_labels
65
93
  end
@@ -16,7 +16,7 @@ module Toji
16
16
  result = []
17
17
 
18
18
  @actuals.each {|moromi, name|
19
- states = moromi.states.select{|s| s.moromi_day && s.bmd}
19
+ states = moromi.wrapped_states.select{|s| s.moromi_day && s.bmd}
20
20
 
21
21
  xs = states.map(&:moromi_day).map{|d| d*DAY}
22
22
  ys = states.map(&:bmd)
@@ -69,127 +69,6 @@ module Toji
69
69
  }
70
70
  )
71
71
  end
72
-
73
- def state_group_order(group_by)
74
- result = {}
75
-
76
- @progresses.map{|progress|
77
- progress.state_group_by(group_by)
78
- }.map{|group|
79
- group.map{|key,states|
80
- [key, states.first.elapsed_time_with_offset]
81
- }.to_h
82
- }.each {|group|
83
- result.merge!(group) {|key,self_val,other_val|
84
- [self_val, other_val].min
85
- }
86
- }
87
-
88
- result.sort_by(&:last).map(&:first)
89
- end
90
-
91
- def state_group_count(group_by)
92
- result = {}
93
-
94
- @progresses.map{|progress|
95
- progress.state_group_count(group_by)
96
- }.each {|group|
97
- result.merge!(group) {|key,self_val,other_val|
98
- [self_val, other_val].max
99
- }
100
- }
101
-
102
- state_group_order(group_by).map {|val|
103
- [val, result[val]]
104
- }.to_h
105
- end
106
-
107
- def table_data(group_by=nil, keys=nil)
108
- case group_by
109
- when :elapsed_time, :elapsed_time_with_offset, nil
110
- table_data_group_by_elapsed_time(keys)
111
- else
112
- table_data_group_by(group_by, keys)
113
- end
114
- end
115
-
116
- def table_data_group_by(group_by, keys=nil)
117
- header = []
118
- cells = []
119
-
120
- group_count = state_group_count(group_by)
121
-
122
- header << ["", group_by]
123
- cells << group_count.inject([]) {|result,(group,num)|
124
- if 0<num
125
- result << group
126
- (num-1).times {
127
- result << ""
128
- }
129
- end
130
- result
131
- }
132
-
133
- @progresses.each {|progress|
134
- data = progress.table_data(keys, group_by, group_count)
135
- header += data[:header].map.with_index{|h,i|
136
- name = i==0 ? progress.name : ""
137
- [name, h]
138
- }
139
- cells += data[:rows].transpose
140
- }
141
-
142
- {header: header, rows: cells.transpose}
143
- end
144
-
145
- def table_data_group_by_elapsed_time(keys=nil, date_format="%m/%d %H:%M")
146
- header = []
147
- cells = []
148
-
149
- elapsed_times = state_group_count(:elapsed_time_with_offset)
150
-
151
- header << ["", :elapsed_time]
152
- utc_offset = Time.at(0).utc_offset
153
-
154
- cells << elapsed_times.inject([]) {|result,(elapsed_time,num)|
155
- if 0<num
156
- result << Time.at(elapsed_time - utc_offset).strftime(date_format)
157
- (num-1).times {
158
- result << ""
159
- }
160
- end
161
- result
162
- }
163
-
164
- @progresses.each {|progress|
165
- data = progress.table_data(keys, :elapsed_time_with_offset, elapsed_times)
166
- header += data[:header].map.with_index{|h,i|
167
- name = i==0 ? progress.name : ""
168
- [name, h]
169
- }
170
- cells += data[:rows].transpose
171
- }
172
-
173
- {header: header, rows: cells.transpose}
174
- end
175
-
176
- def table(group_by=nil, keys=nil)
177
- data = table_data(group_by, keys)
178
-
179
- Plotly::Plot.new(
180
- data: [{
181
- type: :table,
182
- header: {
183
- values: data[:header]
184
- },
185
- cells: {
186
- values: data[:rows].transpose
187
- },
188
- }],
189
- layout: {
190
- }
191
- )
192
- end
193
72
  end
194
73
  end
195
74
  end
@@ -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<@brew.states.length && 0<@brew.day_offset
78
+ if 0<@brew.wrapped_states.length && 0<@brew.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<@brew.states.length && @brew.states.last.time.strftime("%T")!="00:00:00"
88
- # t = @brew.states.last.elapsed_time_with_offset
87
+ #if 0<@brew.wrapped_states.length && @brew.wrapped_states.last.time.strftime("%T")!="00:00:00"
88
+ # t = @brew.wrapped_states.last.elapsed_time_with_offset
89
89
  # t -= (t % DAY) - DAY
90
90
  #
91
91
  # result = result.map{|h|
@@ -117,28 +117,7 @@ module Toji
117
117
  }
118
118
  end
119
119
 
120
- def state_group_by(group_by)
121
- group = {}
122
- prev = nil
123
-
124
- @brew.each {|state|
125
- val = state.send(group_by) || prev
126
- prev = val
127
-
128
- group[val] ||= []
129
- group[val] << state
130
- }
131
-
132
- group
133
- end
134
-
135
- def state_group_count(group_by)
136
- state_group_by(group_by).map{|val,states|
137
- [val, states.length]
138
- }.to_h
139
- end
140
-
141
- def table_data(keys=nil, group_by=nil, group_count=nil)
120
+ def table_data(keys=nil)
142
121
  if !keys
143
122
  keys = @brew.has_keys
144
123
  keys.delete(:elapsed_time)
@@ -151,33 +130,19 @@ module Toji
151
130
  keys &= @brew.has_keys
152
131
  end
153
132
 
154
- if group_by && group_count
155
- brew_hash = state_group_by(group_by)
156
- else
157
- group_count = state_group_count(:itself)
158
- brew_hash = state_group_by(:itself)
159
- end
160
-
161
133
  rows = []
162
- group_count.each {|group_value,num|
163
- states = brew_hash[group_value] || []
164
- num ||= states.length
165
-
166
- num.times {|i|
167
- state = states[i]
168
-
169
- rows << keys.map {|k|
170
- v = state&.send(k)
171
- if Array===v
172
- v.map(&:to_s).join(", ")
173
- elsif Float===v
174
- v.round(3)
175
- elsif v
176
- v
177
- else
178
- ""
179
- end
180
- }
134
+ @brew.each {|state|
135
+ rows << keys.map {|k|
136
+ v = state&.send(k)
137
+ if Array===v
138
+ v.map(&:to_s).join(", ")
139
+ elsif Float===v
140
+ v.round(3).to_s
141
+ elsif v
142
+ v.to_s
143
+ else
144
+ ""
145
+ end
181
146
  }
182
147
  }
183
148
 
@@ -1,6 +1,7 @@
1
1
  module Toji
2
2
  module Brew
3
- class Koji < Base
3
+ module Koji
4
+ include Base
4
5
 
5
6
  def progress(name: nil, dash: :solid, enable_annotations: true)
6
7
  Graph::Progress.new(self, name: name, dash: dash, enable_annotations: enable_annotations)
@@ -1,6 +1,7 @@
1
1
  module Toji
2
2
  module Brew
3
- class Moromi < Base
3
+ module Moromi
4
+ include Base
4
5
 
5
6
  attr_accessor :prefix_day_labels
6
7
 
@@ -1,6 +1,7 @@
1
1
  module Toji
2
2
  module Brew
3
- class Shubo < Base
3
+ module Shubo
4
+ include Base
4
5
 
5
6
  def progress(name: nil, dash: :solid, enable_annotations: true)
6
7
  Graph::Progress.new(self, name: name, dash: dash, enable_annotations: enable_annotations)