toji 2.12.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 (106) 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 +35 -35
  5. data/example/example_core.rb +850 -230
  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 -2
  20. data/lib/toji/calendar.rb +12 -12
  21. data/lib/toji/calendar/date_column.rb +8 -8
  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 -32
  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 +53 -39
  68. data/lib/toji/recipe/ab_expect.rb +2 -2
  69. data/lib/toji/recipe/action.rb +2 -2
  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/{event → schedule}/base.rb +1 -1
  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 +58 -44
  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/event.rb +0 -5
  89. data/lib/toji/event/action_event.rb +0 -12
  90. data/lib/toji/event/kake_event.rb +0 -13
  91. data/lib/toji/event/koji_event.rb +0 -19
  92. data/lib/toji/event/rice_event.rb +0 -34
  93. data/lib/toji/ingredient/kake/actual.rb +0 -26
  94. data/lib/toji/ingredient/kake/base.rb +0 -18
  95. data/lib/toji/ingredient/kake/expected.rb +0 -40
  96. data/lib/toji/ingredient/koji/actual.rb +0 -29
  97. data/lib/toji/ingredient/koji/actual_fermentable.rb +0 -15
  98. data/lib/toji/ingredient/koji/base.rb +0 -35
  99. data/lib/toji/ingredient/koji/expected.rb +0 -45
  100. data/lib/toji/ingredient/koji/expected_fermentable.rb +0 -15
  101. data/lib/toji/ingredient/koji_rate.rb +0 -16
  102. data/lib/toji/ingredient/rice/actual_steamable.rb +0 -27
  103. data/lib/toji/ingredient/rice/base.rb +0 -40
  104. data/lib/toji/ingredient/rice/expected_steamable.rb +0 -27
  105. data/lib/toji/ingredient/rice_rate.rb +0 -23
  106. 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
@@ -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,42 +1,21 @@
1
- require 'toji/product/event_factory'
1
+ require 'toji/product/schedule_factory'
2
2
 
3
3
  module Toji
4
4
  module Product
5
- attr_accessor :name
6
- attr_accessor :recipe
7
- attr_accessor :base_date
5
+ attr_reader :name
6
+ attr_reader :recipe
7
+ attr_reader :base_date
8
8
 
9
- attr_accessor :koji_events
10
- attr_accessor :kake_events
11
- attr_accessor :action_events
9
+ attr_reader :koji_schedules
10
+ attr_reader :kake_schedules
11
+ attr_reader :action_schedules
12
12
 
13
- def koji_dates
14
- date = base_date
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 kake_dates
21
- date = base_date
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,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
@@ -1,5 +1,5 @@
1
1
  module Toji
2
- module Brew
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.wrapped_states.select{|s| s.alcohol && s.baume}
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,13 +57,13 @@ module Toji
57
57
 
58
58
  def min_baume
59
59
  @actuals.map {|moromi, name|
60
- moromi.wrapped_states.map(&:baume).compact.min
60
+ moromi.states.map(&:baume).compact.min
61
61
  }.compact.min || 0
62
62
  end
63
63
 
64
64
  def max_baume
65
65
  @actuals.map {|moromi, name|
66
- moromi.wrapped_states.map(&:baume).compact.max
66
+ moromi.states.map(&:baume).compact.max
67
67
  }.compact.max || 0
68
68
  end
69
69
 
@@ -1,5 +1,5 @@
1
1
  module Toji
2
- module Brew
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.wrapped_states.select{|s| s.moromi_day && s.bmd}
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 Brew
2
+ module Progress
3
3
  module Graph
4
- class MultiProgress
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 Progress
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 Base
32
- progress = source.progress(name: name, dash: dash, enable_annotations: enable_annotations)
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 Base required"
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
- brews = @progresses.map(&:brew)
56
- max_brew_days = brews.map(&:days).max
57
- index = brews.index{|brew| brew.days==max_brew_days}
58
- day_labels = brews[index].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: max_brew_days.times.map{|d| d*DAY},
65
+ tickvals: max_days.times.map{|d| d*DAY},
66
66
  ticktext: day_labels
67
67
  },
68
68
  annotations: annotations,