toji 2.2.0 → 2.3.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 (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)