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.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/example/calendar.ipynb +42 -51
  3. data/example/calendar.yaml +6 -6
  4. data/example/calendar_file.ipynb +36 -36
  5. data/example/example_core.rb +877 -205
  6. data/example/kake_ingredient.rb +21 -15
  7. data/example/koji_ingredient.rb +31 -21
  8. data/example/{koji_making.ipynb → koji_progress.ipynb} +14 -14
  9. data/example/{koji_making.rb → koji_progress.rb} +3 -2
  10. data/example/{koji_making.yaml → koji_progress.yaml} +8 -9
  11. data/example/{koji_making_multi.ipynb → koji_progress_multi.ipynb} +21 -22
  12. data/example/{moromi.ipynb → moromi_progress.ipynb} +22 -22
  13. data/example/{moromi.rb → moromi_progress.rb} +3 -2
  14. data/example/{moromi.yaml → moromi_progress.yaml} +0 -0
  15. data/example/moto_progress.ipynb +121 -0
  16. data/example/{moto.rb → moto_progress.rb} +3 -2
  17. data/example/{moto.yaml → moto_progress.yaml} +14 -15
  18. data/example/recipe.rb +44 -32
  19. data/lib/toji.rb +4 -1
  20. data/lib/toji/calendar.rb +18 -18
  21. data/lib/toji/calendar/date_column.rb +7 -22
  22. data/lib/toji/calendar/date_row.rb +6 -6
  23. data/lib/toji/ingredient.rb +6 -2
  24. data/lib/toji/ingredient/alcohol.rb +14 -0
  25. data/lib/toji/ingredient/base.rb +11 -0
  26. data/lib/toji/ingredient/kake.rb +3 -9
  27. data/lib/toji/ingredient/koji.rb +19 -10
  28. data/lib/toji/ingredient/lactic_acid.rb +14 -0
  29. data/lib/toji/ingredient/rice.rb +50 -4
  30. data/lib/toji/ingredient/tanekoji.rb +29 -0
  31. data/lib/toji/ingredient/water.rb +18 -0
  32. data/lib/toji/ingredient/yeast.rb +20 -0
  33. data/lib/toji/processing.rb +18 -0
  34. data/lib/toji/processing/base.rb +7 -0
  35. data/lib/toji/processing/cooled_rice.rb +22 -0
  36. data/lib/toji/processing/cooled_rice_element.rb +8 -0
  37. data/lib/toji/processing/dekoji.rb +22 -0
  38. data/lib/toji/processing/dekoji_element.rb +8 -0
  39. data/lib/toji/processing/kake_processing.rb +7 -0
  40. data/lib/toji/processing/koji_processing.rb +10 -0
  41. data/lib/toji/processing/rice_processing.rb +19 -0
  42. data/lib/toji/processing/soaked_rice.rb +49 -0
  43. data/lib/toji/processing/soaked_rice_element.rb +18 -0
  44. data/lib/toji/processing/steamed_rice.rb +22 -0
  45. data/lib/toji/processing/steamed_rice_element.rb +8 -0
  46. data/lib/toji/product.rb +11 -83
  47. data/lib/toji/product/schedule_factory.rb +74 -0
  48. data/lib/toji/progress.rb +23 -0
  49. data/lib/toji/progress/base_progress.rb +37 -0
  50. data/lib/toji/progress/base_state.rb +39 -0
  51. data/lib/toji/progress/builder.rb +53 -0
  52. data/lib/toji/progress/graph.rb +11 -0
  53. data/lib/toji/{brew → progress}/graph/ab.rb +4 -4
  54. data/lib/toji/{brew → progress}/graph/bmd.rb +2 -2
  55. data/lib/toji/{brew/graph/multi_progress.rb → progress/graph/multi_progress_note.rb} +11 -11
  56. data/lib/toji/{brew/graph/progress.rb → progress/graph/progress_note.rb} +20 -18
  57. data/lib/toji/progress/koji_progress.rb +15 -0
  58. data/lib/toji/progress/koji_state.rb +23 -0
  59. data/lib/toji/{brew/moromi.rb → progress/moromi_progress.rb} +9 -5
  60. data/lib/toji/progress/moromi_state.rb +77 -0
  61. data/lib/toji/progress/moto_progress.rb +15 -0
  62. data/lib/toji/progress/moto_state.rb +31 -0
  63. data/lib/toji/progress/progress.rb +15 -0
  64. data/lib/toji/progress/state.rb +9 -0
  65. data/lib/toji/progress/state/baume_to_nihonshudo.rb +21 -0
  66. data/lib/toji/progress/state/nihonshudo_to_baume.rb +21 -0
  67. data/lib/toji/recipe.rb +54 -39
  68. data/lib/toji/recipe/ab_expect.rb +2 -2
  69. data/lib/toji/recipe/action.rb +8 -0
  70. data/lib/toji/recipe/step.rb +97 -71
  71. data/lib/toji/schedule.rb +5 -0
  72. data/lib/toji/schedule/action_schedule.rb +9 -0
  73. data/lib/toji/schedule/base.rb +9 -0
  74. data/lib/toji/schedule/kake_schedule.rb +11 -0
  75. data/lib/toji/schedule/koji_schedule.rb +11 -0
  76. data/lib/toji/schedule/rice_schedule.rb +16 -0
  77. data/lib/toji/utils.rb +43 -0
  78. data/lib/toji/version.rb +1 -1
  79. metadata +59 -40
  80. data/lib/toji/brew.rb +0 -18
  81. data/lib/toji/brew/base.rb +0 -55
  82. data/lib/toji/brew/builder.rb +0 -98
  83. data/lib/toji/brew/graph.rb +0 -11
  84. data/lib/toji/brew/koji.rb +0 -11
  85. data/lib/toji/brew/moto.rb +0 -11
  86. data/lib/toji/brew/state.rb +0 -122
  87. data/lib/toji/brew/wrapped_state.rb +0 -109
  88. data/lib/toji/ingredient/kake/actual.rb +0 -26
  89. data/lib/toji/ingredient/kake/base.rb +0 -18
  90. data/lib/toji/ingredient/kake/expected.rb +0 -40
  91. data/lib/toji/ingredient/koji/actual.rb +0 -29
  92. data/lib/toji/ingredient/koji/actual_fermentable.rb +0 -15
  93. data/lib/toji/ingredient/koji/base.rb +0 -35
  94. data/lib/toji/ingredient/koji/expected.rb +0 -45
  95. data/lib/toji/ingredient/koji/expected_fermentable.rb +0 -15
  96. data/lib/toji/ingredient/koji_rate.rb +0 -16
  97. data/lib/toji/ingredient/rice/actual_steamable.rb +0 -27
  98. data/lib/toji/ingredient/rice/base.rb +0 -40
  99. data/lib/toji/ingredient/rice/expected_steamable.rb +0 -27
  100. data/lib/toji/ingredient/rice_rate.rb +0 -23
  101. data/lib/toji/product/event.rb +0 -13
  102. data/lib/toji/product/rice_event.rb +0 -28
  103. 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
@@ -0,0 +1,8 @@
1
+ module Toji
2
+ module Processing
3
+ module SteamedRiceElement
4
+ # 蒸米重量
5
+ attr_reader :weight
6
+ end
7
+ end
8
+ end
@@ -1,93 +1,21 @@
1
- require 'toji/product/event'
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 :reduce_key
8
- attr_accessor :name
9
- attr_accessor :recipe
10
- attr_accessor :base_date
5
+ attr_reader :name
6
+ attr_reader :recipe
7
+ attr_reader :base_date
11
8
 
12
- def koji_dates
13
- date = base_date
14
- recipe.steps.map {|step|
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 rice_events
57
- koji_events + kake_events
13
+ def rice_schedules
14
+ koji_schedules + kake_schedules
58
15
  end
59
16
 
60
- def koji_event_groups
61
- koji_events.select{|event|
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
@@ -0,0 +1,11 @@
1
+ require 'toji/progress/graph/progress_note'
2
+ require 'toji/progress/graph/multi_progress_note'
3
+ require 'toji/progress/graph/bmd'
4
+ require 'toji/progress/graph/ab'
5
+
6
+ module Toji
7
+ module Progress
8
+ module Graph
9
+ end
10
+ end
11
+ end