toji 2.8.0 → 2.13.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.
- checksums.yaml +4 -4
- data/example/calendar.ipynb +42 -51
- data/example/calendar.yaml +6 -6
- data/example/calendar_file.ipynb +36 -36
- data/example/example_core.rb +877 -205
- 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 -1
- data/lib/toji/calendar.rb +18 -18
- data/lib/toji/calendar/date_column.rb +7 -22
- 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 -83
- 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 +54 -39
- data/lib/toji/recipe/ab_expect.rb +2 -2
- data/lib/toji/recipe/action.rb +8 -0
- 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/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 +59 -40
- 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/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.rb +0 -13
- data/lib/toji/product/rice_event.rb +0 -28
- data/lib/toji/product/rice_event_group.rb +0 -19
@@ -0,0 +1,49 @@
|
|
1
|
+
module Toji
|
2
|
+
module Processing
|
3
|
+
module SoakedRice
|
4
|
+
# 室内温度
|
5
|
+
attr_reader :room_temp
|
6
|
+
|
7
|
+
# 外気温
|
8
|
+
attr_reader :outside_temp
|
9
|
+
|
10
|
+
# 白米の含水率
|
11
|
+
attr_reader :rice_water_content
|
12
|
+
|
13
|
+
# 洗米に用いる水の温度
|
14
|
+
attr_reader :washing_water_temp
|
15
|
+
|
16
|
+
# 浸漬に用いる水の温度
|
17
|
+
attr_reader :soaking_water_temp
|
18
|
+
|
19
|
+
# 親 (belongs_to: Toji::Processing::RiceProcessing)
|
20
|
+
attr_reader :processing
|
21
|
+
|
22
|
+
# 要素 (has_many: Toji::Processing::SoakedRiceElement)
|
23
|
+
attr_reader :elements
|
24
|
+
|
25
|
+
# 白米総重量
|
26
|
+
def weight
|
27
|
+
(elements || []).map(&:weight).sum
|
28
|
+
end
|
29
|
+
|
30
|
+
# 浸漬米総重量
|
31
|
+
def soaked
|
32
|
+
(elements || []).map(&:soaked).sum
|
33
|
+
end
|
34
|
+
|
35
|
+
# 浸漬米吸水率
|
36
|
+
def soaking_ratio
|
37
|
+
(soaked.to_f - weight.to_f) / weight.to_f
|
38
|
+
end
|
39
|
+
|
40
|
+
# 浸漬米吸水率の標準偏差
|
41
|
+
def soaking_ratio_sd
|
42
|
+
mean = soaking_ratio
|
43
|
+
samples = (elements || []).map(&:soaking_ratio)
|
44
|
+
length = samples.length.to_f
|
45
|
+
Math.sqrt(samples.map{|sample| (sample - mean) ** 2}.sum / length)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -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,93 +1,21 @@
|
|
1
|
-
require 'toji/product/
|
2
|
-
require 'toji/product/rice_event'
|
3
|
-
require 'toji/product/rice_event_group'
|
1
|
+
require 'toji/product/schedule_factory'
|
4
2
|
|
5
3
|
module Toji
|
6
4
|
module Product
|
7
|
-
attr_reader :
|
8
|
-
|
9
|
-
|
10
|
-
attr_accessor :base_date
|
5
|
+
attr_reader :name
|
6
|
+
attr_reader :recipe
|
7
|
+
attr_reader :base_date
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
date = date.next_day(step.koji_interval_days)
|
16
|
-
}
|
17
|
-
end
|
18
|
-
|
19
|
-
def kake_dates
|
20
|
-
date = base_date
|
21
|
-
recipe.steps.map {|step|
|
22
|
-
date = date.next_day(step.kake_interval_days)
|
23
|
-
}
|
24
|
-
end
|
25
|
-
|
26
|
-
def squeeze_date
|
27
|
-
base_date.next_day(recipe.squeeze_interval_days)
|
28
|
-
end
|
29
|
-
|
30
|
-
def koji_events
|
31
|
-
koji_dates.map.with_index {|date,i|
|
32
|
-
RiceEvent.new(
|
33
|
-
product: self,
|
34
|
-
type: :koji,
|
35
|
-
index: i,
|
36
|
-
group_index: koji_dates.find_index(date),
|
37
|
-
date: date,
|
38
|
-
weight: recipe.steps[i].koji,
|
39
|
-
)
|
40
|
-
}
|
41
|
-
end
|
42
|
-
|
43
|
-
def kake_events
|
44
|
-
kake_dates.map.with_index {|date,i|
|
45
|
-
RiceEvent.new(
|
46
|
-
product: self,
|
47
|
-
type: :kake,
|
48
|
-
index: i,
|
49
|
-
group_index: kake_dates.find_index(date),
|
50
|
-
date: date,
|
51
|
-
weight: recipe.steps[i].kake,
|
52
|
-
)
|
53
|
-
}
|
54
|
-
end
|
9
|
+
attr_reader :koji_schedules
|
10
|
+
attr_reader :kake_schedules
|
11
|
+
attr_reader :action_schedules
|
55
12
|
|
56
|
-
def
|
57
|
-
|
13
|
+
def rice_schedules
|
14
|
+
koji_schedules + kake_schedules
|
58
15
|
end
|
59
16
|
|
60
|
-
def
|
61
|
-
|
62
|
-
0<event.weight
|
63
|
-
}.group_by{|event|
|
64
|
-
event.group_key
|
65
|
-
}.map {|group_key,events|
|
66
|
-
RiceEventGroup.new(events)
|
67
|
-
}
|
68
|
-
end
|
69
|
-
|
70
|
-
def kake_event_groups
|
71
|
-
kake_events.select{|event|
|
72
|
-
0<event.weight
|
73
|
-
}.group_by{|event|
|
74
|
-
event.group_key
|
75
|
-
}.map {|group_key,events|
|
76
|
-
RiceEventGroup.new(events)
|
77
|
-
}
|
78
|
-
end
|
79
|
-
|
80
|
-
def rice_event_groups
|
81
|
-
koji_event_groups + kake_event_groups
|
82
|
-
end
|
83
|
-
|
84
|
-
def events
|
85
|
-
events = []
|
86
|
-
|
87
|
-
events += rice_event_groups
|
88
|
-
events << Event.new(squeeze_date, :squeeze)
|
89
|
-
|
90
|
-
events
|
17
|
+
def schedules
|
18
|
+
rice_schedules + action_schedules
|
91
19
|
end
|
92
20
|
end
|
93
21
|
end
|
@@ -0,0 +1,74 @@
|
|
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.each.with_index.inject([]) {|result, (step, i)|
|
19
|
+
step.kojis&.each {|koji|
|
20
|
+
result << {
|
21
|
+
step_index: i,
|
22
|
+
date: base_date.next_day(koji.interval_days),
|
23
|
+
koji: koji,
|
24
|
+
}
|
25
|
+
}
|
26
|
+
result
|
27
|
+
}.select {|schedule|
|
28
|
+
0<schedule[:koji]&.weight.to_f
|
29
|
+
}.group_by {|schedule|
|
30
|
+
[schedule[:date], schedule[:koji].group_key]
|
31
|
+
}.map {|(date, group_key), schedules|
|
32
|
+
create_koji_schedule(
|
33
|
+
date: date,
|
34
|
+
step_indexes: schedules.map {|schedule| schedule[:step_index]}.sort,
|
35
|
+
kojis: schedules.map{|schedule| schedule[:koji]},
|
36
|
+
)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def kake_schedules
|
41
|
+
recipe.steps.each.with_index.inject([]) {|result, (step, i)|
|
42
|
+
step.kakes&.each {|kake|
|
43
|
+
result << {
|
44
|
+
step_index: i,
|
45
|
+
date: base_date.next_day(kake.interval_days),
|
46
|
+
kake: kake,
|
47
|
+
}
|
48
|
+
}
|
49
|
+
result
|
50
|
+
}.select {|schedule|
|
51
|
+
0<schedule[:kake]&.weight.to_f
|
52
|
+
}.group_by {|schedule|
|
53
|
+
[schedule[:date], schedule[:kake].group_key]
|
54
|
+
}.map {|(date, group_key), schedules|
|
55
|
+
create_kake_schedule(
|
56
|
+
date: date,
|
57
|
+
step_indexes: schedules.map {|schedule| schedule[:step_index]}.sort,
|
58
|
+
kakes: schedules.map{|schedule| schedule[:kake]},
|
59
|
+
)
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def action_schedules
|
64
|
+
recipe.actions.map.with_index {|action, i|
|
65
|
+
create_action_schedule(
|
66
|
+
date: base_date.next_day(action.interval_days),
|
67
|
+
action_index: i,
|
68
|
+
action: action,
|
69
|
+
)
|
70
|
+
}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
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,39 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
module BaseState
|
4
|
+
REQUIRED_KEYS = [
|
5
|
+
:time,
|
6
|
+
:elapsed_time,
|
7
|
+
:day,
|
8
|
+
:day_label,
|
9
|
+
:display_time,
|
10
|
+
:mark,
|
11
|
+
].freeze
|
12
|
+
|
13
|
+
attr_accessor :progress
|
14
|
+
|
15
|
+
attr_accessor :time
|
16
|
+
attr_accessor :mark
|
17
|
+
|
18
|
+
def elapsed_time
|
19
|
+
time - progress.base_time
|
20
|
+
end
|
21
|
+
|
22
|
+
def elapsed_time_with_offset
|
23
|
+
elapsed_time + progress.day_offset
|
24
|
+
end
|
25
|
+
|
26
|
+
def day
|
27
|
+
((elapsed_time_with_offset.to_f + 1) / DAY).ceil
|
28
|
+
end
|
29
|
+
|
30
|
+
def day_label
|
31
|
+
progress.day_labels[day - 1]
|
32
|
+
end
|
33
|
+
|
34
|
+
def display_time(format="%m/%d %H:%M")
|
35
|
+
time.strftime(format)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
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
|