toji 2.12.0 → 2.16.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 +1039 -234
- 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 +12 -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 +51 -4
- data/lib/toji/ingredient/tanekoji.rb +29 -0
- data/lib/toji/ingredient/water.rb +18 -0
- data/lib/toji/ingredient/yeast.rb +21 -0
- data/lib/toji/processing.rb +18 -0
- data/lib/toji/{event → processing}/base.rb +1 -3
- 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 +80 -0
- data/lib/toji/progress.rb +23 -0
- data/lib/toji/progress/base_progress.rb +37 -0
- data/lib/toji/progress/base_state.rb +36 -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 +6 -6
- 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} +10 -6
- 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 +16 -0
- data/lib/toji/progress/state.rb +22 -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 +51 -39
- data/lib/toji/recipe/ab_expect.rb +2 -2
- data/lib/toji/recipe/action.rb +2 -2
- data/lib/toji/recipe/step.rb +106 -71
- data/lib/toji/schedule.rb +5 -0
- data/lib/toji/schedule/action_schedule.rb +9 -0
- data/lib/toji/schedule/base.rb +9 -0
- 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 +61 -47
- 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
@@ -0,0 +1,18 @@
|
|
1
|
+
module Toji
|
2
|
+
module Processing
|
3
|
+
module SoakedRiceElement
|
4
|
+
# 白米重量
|
5
|
+
attr_reader :weight
|
6
|
+
|
7
|
+
# 浸漬時間
|
8
|
+
attr_reader :soaking_time
|
9
|
+
|
10
|
+
# 浸漬米重量
|
11
|
+
attr_reader :soaked
|
12
|
+
|
13
|
+
def soaking_ratio
|
14
|
+
(soaked.to_f - weight.to_f) / weight.to_f
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Toji
|
2
|
+
module Processing
|
3
|
+
module SteamedRice
|
4
|
+
# 親 (belongs_to: Toji::Processing::RiceProcessing)
|
5
|
+
attr_reader :processing
|
6
|
+
|
7
|
+
# 要素 (has_many: Toji::Processing::SteamedRiceElement)
|
8
|
+
attr_reader :elements
|
9
|
+
|
10
|
+
# 蒸米総重量
|
11
|
+
def weight
|
12
|
+
(elements || []).map(&:weight).sum
|
13
|
+
end
|
14
|
+
|
15
|
+
# 蒸米歩合
|
16
|
+
def steaming_ratio
|
17
|
+
raw_weight = processing.soaked_rice.weight.to_f
|
18
|
+
(weight.to_f - raw_weight) / raw_weight
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/toji/product.rb
CHANGED
@@ -1,42 +1,21 @@
|
|
1
|
-
require 'toji/product/
|
1
|
+
require 'toji/product/schedule_factory'
|
2
2
|
|
3
3
|
module Toji
|
4
4
|
module Product
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# @dynamic name
|
6
|
+
# @dynamic recipe
|
7
|
+
# @dynamic base_date
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
# @dynamic koji_schedules
|
10
|
+
# @dynamic kake_schedules
|
11
|
+
# @dynamic action_schedules
|
12
12
|
|
13
|
-
def
|
14
|
-
|
15
|
-
recipe.steps.map {|step|
|
16
|
-
date = date.next_day(step.koji_interval_days)
|
17
|
-
}
|
13
|
+
def rice_schedules
|
14
|
+
koji_schedules + kake_schedules
|
18
15
|
end
|
19
16
|
|
20
|
-
def
|
21
|
-
|
22
|
-
recipe.steps.map {|step|
|
23
|
-
date = date.next_day(step.kake_interval_days)
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
def action_dates
|
28
|
-
date = base_date
|
29
|
-
recipe.actions.map {|action|
|
30
|
-
date = date.next_day(action.interval_days)
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
def rice_events
|
35
|
-
koji_events + kake_events
|
36
|
-
end
|
37
|
-
|
38
|
-
def events
|
39
|
-
rice_events + action_events
|
17
|
+
def schedules
|
18
|
+
rice_schedules + action_schedules
|
40
19
|
end
|
41
20
|
end
|
42
21
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Toji
|
2
|
+
module Product
|
3
|
+
module ScheduleFactory
|
4
|
+
|
5
|
+
def create_koji_schedule(date:, step_indexes:, kojis:)
|
6
|
+
raise Error, "implement required: create_koji_schedule"
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_kake_schedule(date:, step_indexes:, kakes:)
|
10
|
+
raise Error, "implement required: create_kake_schedule"
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_action_schedule(date:, action_index:, action:)
|
14
|
+
raise Error, "implement required: create_action_schedule"
|
15
|
+
end
|
16
|
+
|
17
|
+
def koji_schedules
|
18
|
+
recipe.steps.inject([]) {|result, step|
|
19
|
+
step.kojis&.each {|koji|
|
20
|
+
result << {
|
21
|
+
step_index: {
|
22
|
+
index: step.index,
|
23
|
+
subindex: step.subindex,
|
24
|
+
},
|
25
|
+
date: base_date.next_day(koji.interval_days),
|
26
|
+
koji: koji,
|
27
|
+
}
|
28
|
+
}
|
29
|
+
result
|
30
|
+
}.select {|schedule|
|
31
|
+
0<schedule[:koji]&.weight.to_f
|
32
|
+
}.group_by {|schedule|
|
33
|
+
[schedule[:date], schedule[:koji].group_key]
|
34
|
+
}.map {|(date, _group_key), schedules|
|
35
|
+
create_koji_schedule(
|
36
|
+
date: date,
|
37
|
+
step_indexes: schedules.map {|schedule| schedule[:step_index]}.sort_by {|x| [x[:index], x[:subindex]]},
|
38
|
+
kojis: schedules.map{|schedule| schedule[:koji]},
|
39
|
+
)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def kake_schedules
|
44
|
+
recipe.steps.inject([]) {|result, step|
|
45
|
+
step.kakes&.each {|kake|
|
46
|
+
result << {
|
47
|
+
step_index: {
|
48
|
+
index: step.index,
|
49
|
+
subindex: step.subindex,
|
50
|
+
},
|
51
|
+
date: base_date.next_day(kake.interval_days),
|
52
|
+
kake: kake,
|
53
|
+
}
|
54
|
+
}
|
55
|
+
result
|
56
|
+
}.select {|schedule|
|
57
|
+
0<schedule[:kake]&.weight.to_f
|
58
|
+
}.group_by {|schedule|
|
59
|
+
[schedule[:date], schedule[:kake].group_key, schedule[:step_index]]
|
60
|
+
}.map {|(date, _group_key, _step_index), schedules|
|
61
|
+
create_kake_schedule(
|
62
|
+
date: date,
|
63
|
+
step_indexes: schedules.map {|schedule| schedule[:step_index]}.sort_by {|x| [x[:index], x[:subindex]]},
|
64
|
+
kakes: schedules.map{|schedule| schedule[:kake]},
|
65
|
+
)
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def action_schedules
|
70
|
+
recipe.actions.map.with_index {|action, i|
|
71
|
+
create_action_schedule(
|
72
|
+
date: base_date.next_day(action.interval_days),
|
73
|
+
action_index: i,
|
74
|
+
action: action,
|
75
|
+
)
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
SECOND = 1
|
4
|
+
MINUTE = 60 * SECOND
|
5
|
+
HOUR = 60 * MINUTE
|
6
|
+
DAY = 24 * HOUR
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'toji/progress/state'
|
11
|
+
require 'toji/progress/base_state'
|
12
|
+
require 'toji/progress/koji_state'
|
13
|
+
require 'toji/progress/moto_state'
|
14
|
+
require 'toji/progress/moromi_state'
|
15
|
+
|
16
|
+
require 'toji/progress/progress'
|
17
|
+
require 'toji/progress/base_progress'
|
18
|
+
require 'toji/progress/koji_progress'
|
19
|
+
require 'toji/progress/moto_progress'
|
20
|
+
require 'toji/progress/moromi_progress'
|
21
|
+
|
22
|
+
require 'toji/progress/builder'
|
23
|
+
require 'toji/progress/graph'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module BaseProgress
|
4
|
+
include Progress
|
5
|
+
|
6
|
+
def base_time
|
7
|
+
states&.first&.time&.to_time
|
8
|
+
end
|
9
|
+
|
10
|
+
def day_offset
|
11
|
+
t = base_time
|
12
|
+
if t
|
13
|
+
offset = (t - Time.mktime(t.year, t.month, t.day)).to_i
|
14
|
+
(DAY - date_line + offset) % DAY
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def days
|
19
|
+
((states&.last&.elapsed_time_with_offset&.to_f + 1) / DAY).ceil
|
20
|
+
end
|
21
|
+
|
22
|
+
def day_labels
|
23
|
+
days.times.map(&:succ).map(&:to_s)
|
24
|
+
end
|
25
|
+
|
26
|
+
def all_keys
|
27
|
+
BaseState::REQUIRED_KEYS
|
28
|
+
end
|
29
|
+
|
30
|
+
def has_keys
|
31
|
+
all_keys.select {|k|
|
32
|
+
states.find {|s| s.send(k).present?}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module BaseState
|
4
|
+
include State
|
5
|
+
|
6
|
+
REQUIRED_KEYS = [
|
7
|
+
:time,
|
8
|
+
:elapsed_time,
|
9
|
+
:day,
|
10
|
+
:day_label,
|
11
|
+
:display_time,
|
12
|
+
:mark,
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
def elapsed_time
|
16
|
+
time - progress.base_time
|
17
|
+
end
|
18
|
+
|
19
|
+
def elapsed_time_with_offset
|
20
|
+
elapsed_time + progress.day_offset
|
21
|
+
end
|
22
|
+
|
23
|
+
def day
|
24
|
+
((elapsed_time_with_offset.to_f + 1) / DAY).ceil
|
25
|
+
end
|
26
|
+
|
27
|
+
def day_label
|
28
|
+
progress.day_labels[day - 1]
|
29
|
+
end
|
30
|
+
|
31
|
+
def display_time(format="%m/%d %H:%M")
|
32
|
+
time.strftime(format)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
class Builder
|
4
|
+
|
5
|
+
def initialize(progress_cls, state_cls)
|
6
|
+
@progress_cls = progress_cls
|
7
|
+
@state_cls = state_cls
|
8
|
+
@states = []
|
9
|
+
@date_line = 0
|
10
|
+
@prefix_day_labels = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def <<(state)
|
14
|
+
@states += [state].flatten.map {|state|
|
15
|
+
if State===state
|
16
|
+
state
|
17
|
+
else
|
18
|
+
@state_cls.create(state)
|
19
|
+
end
|
20
|
+
}
|
21
|
+
self
|
22
|
+
end
|
23
|
+
alias_method :add, :<<
|
24
|
+
|
25
|
+
def date_line(val, unit=SECOND)
|
26
|
+
@date_line = (val * unit).to_i
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def prefix_day_labels(val)
|
31
|
+
@prefix_day_labels = val
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def build
|
36
|
+
progress = @progress_cls.new
|
37
|
+
|
38
|
+
states = @states.map{|s|
|
39
|
+
s.progress = progress
|
40
|
+
s
|
41
|
+
}.sort_by(&:time)
|
42
|
+
|
43
|
+
progress.states = states
|
44
|
+
progress.date_line = @date_line
|
45
|
+
if progress.respond_to?(:prefix_day_labels=)
|
46
|
+
progress.prefix_day_labels = @prefix_day_labels
|
47
|
+
end
|
48
|
+
|
49
|
+
progress
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Toji
|
2
|
-
module
|
2
|
+
module Progress
|
3
3
|
module Graph
|
4
4
|
class Ab
|
5
5
|
def initialize
|
@@ -34,7 +34,7 @@ module Toji
|
|
34
34
|
result = []
|
35
35
|
|
36
36
|
@actuals.each {|moromi, name|
|
37
|
-
states = moromi.
|
37
|
+
states = moromi.states.select{|s| s.alcohol && s.baume}
|
38
38
|
|
39
39
|
xs = states.map(&:alcohol)
|
40
40
|
ys = states.map(&:baume)
|
@@ -57,14 +57,14 @@ module Toji
|
|
57
57
|
|
58
58
|
def min_baume
|
59
59
|
@actuals.map {|moromi, name|
|
60
|
-
moromi.
|
61
|
-
}.compact.min || 0
|
60
|
+
moromi.states.map(&:baume).compact.min
|
61
|
+
}.compact.min || 0.0
|
62
62
|
end
|
63
63
|
|
64
64
|
def max_baume
|
65
65
|
@actuals.map {|moromi, name|
|
66
|
-
moromi.
|
67
|
-
}.compact.max || 0
|
66
|
+
moromi.states.map(&:baume).compact.max
|
67
|
+
}.compact.max || 0.0
|
68
68
|
end
|
69
69
|
|
70
70
|
def plot
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Toji
|
2
|
-
module
|
2
|
+
module Progress
|
3
3
|
module Graph
|
4
4
|
class Bmd
|
5
5
|
|
@@ -16,7 +16,7 @@ module Toji
|
|
16
16
|
result = []
|
17
17
|
|
18
18
|
@actuals.each {|moromi, name|
|
19
|
-
states = moromi.
|
19
|
+
states = moromi.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)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Toji
|
2
|
-
module
|
2
|
+
module Progress
|
3
3
|
module Graph
|
4
|
-
class
|
4
|
+
class MultiProgressNote
|
5
5
|
|
6
6
|
LINE_DASHES = [
|
7
7
|
:solid,
|
@@ -23,15 +23,15 @@ module Toji
|
|
23
23
|
end
|
24
24
|
|
25
25
|
case source
|
26
|
-
when
|
26
|
+
when ProgressNote
|
27
27
|
progress = source.dup
|
28
28
|
progress.name = name
|
29
29
|
progress.dash = dash
|
30
30
|
progress.enable_annotations = enable_annotations
|
31
|
-
when
|
32
|
-
progress = source.
|
31
|
+
when Progress
|
32
|
+
progress = source.progress_note(name: name, dash: dash, enable_annotations: enable_annotations)
|
33
33
|
else
|
34
|
-
raise Error, "ArgumentError: Progress or
|
34
|
+
raise Error, "ArgumentError: Toji::Progress::Graph::ProgressNote or Toji::Progress::Progress required"
|
35
35
|
end
|
36
36
|
|
37
37
|
@progresses << progress
|
@@ -52,17 +52,17 @@ module Toji
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def plot(keys=nil)
|
55
|
-
|
56
|
-
|
57
|
-
index =
|
58
|
-
day_labels =
|
55
|
+
progresses = @progresses.map(&:progress)
|
56
|
+
max_days = progresses.map(&:days).max
|
57
|
+
index = progresses.index{|progress| progress.days==max_days}
|
58
|
+
day_labels = progresses[index].day_labels
|
59
59
|
|
60
60
|
Plotly::Plot.new(
|
61
61
|
data: plot_data(keys),
|
62
62
|
layout: {
|
63
63
|
xaxis: {
|
64
64
|
dtick: DAY,
|
65
|
-
tickvals:
|
65
|
+
tickvals: max_days.times.map{|d| d*DAY},
|
66
66
|
ticktext: day_labels
|
67
67
|
},
|
68
68
|
annotations: annotations,
|