gravitheque 0.3.0 → 0.4.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.
@@ -4,64 +4,87 @@ require "conversions/volume"
4
4
 
5
5
  module Calculate
6
6
 
7
- # Calculate hop utilization.
7
+ # Calculates hop utilization.
8
+ # Supported extract units are `:brix`, `:plato` and `:specific_gravity`. Default: `:plato`
8
9
  #
9
10
  # @example
10
- # Calculate.hop_utilization 12, 20
11
- # Calculate.hop_utilization 16.3, 45, :brix
12
- # Calculate.hop_utilization 1.089, 60, :specific_gravity
11
+ # Calculate.hop_utilization({ at: 20, extract: 12 })
12
+ # Calculate.hop_utilization({ at: 20, extract: 12 }, :brix)
13
+ # Calculate.hop_utilization({ at: 20, extract: 12 }, :specific_gravity)
13
14
  #
14
- # @param [Float] extract degrees Plato of wort being pitched
15
- # @param [Float] at boil time remaining when hop addition is made
16
- # @param [Symbol] unit used to change default settings for `extract`
15
+ # @param [Hash] data the extract level and time added
16
+ # @param [Symbol] unit the unit used to measure extract
17
17
  # @return [Float] hop utilization
18
- def self.hop_utilization extract, at, unit = :plato
19
- unless unit == :specific_gravity
20
- extract = case unit
21
- when :brix then Convert.brix_to_specific_gravity extract
22
- when :plato then Convert.plato_to_specific_gravity extract
23
- else raise ArgumentError, "#{unit} is not recognized as a unit of extract"
18
+ def self.hop_utilization data, units = :plato
19
+ unless units == :specific_gravity
20
+ data[:extract] = case units
21
+ when :brix then Convert.brix_to_specific_gravity data[:extract]
22
+ when :plato then Convert.plato_to_specific_gravity data[:extract]
23
+ else raise ArgumentError, "#{units} is an unknown unit of extract. Use :brix, :plato or :specific_gravity"
24
24
  end
25
25
  end
26
26
 
27
- ((hop_extract_adjustment extract, :specific_gravity) *
28
- ((hop_boil_time_adjustment at) / 4.15)).round 2
27
+ ((hop_extract_adjustment data[:extract], :specific_gravity) *
28
+ ((hop_boil_time_adjustment data[:at]) / 4.15)).round 2
29
29
  end
30
30
 
31
- # Calculate IBUs for hop addition.
31
+ # Calculates IBUs for hop addition.
32
+ # Supported extract units are `:brix`, `:plato` and `:specific_gravity`. Default: `:plato`
33
+ # Supported mass units are `:grams` and `:ounces`. Default: `:grams`
34
+ # Supported volume units are `:gallons` and `:liters`. Default: `:liters`
32
35
  #
33
36
  # @example
34
- # Calculate.ibus({ :extract => 15, :at => 60, :alpha => 6.5, :mass => 56, :volume => 20 })
35
- # Calculate.ibus({ :extract => 18.5, :at => 60, :alpha => 6.5, :mass => 56, :volume => 20 }, { :extract => :brix })
36
- # Calculate.ibus({ :extract => 1.055, :at => 60, :alpha => 6.5, :mass => 2, :volume => 5 }, { :extract => :specific_gravity, :mass => :ounces, :volume => :gallons })
37
+ # Calculate.ibus({
38
+ # alpha: 12.4,
39
+ # at: 90,
40
+ # extract: 15,
41
+ # mass: 56,
42
+ # volume: 20
43
+ # })
37
44
  #
38
- # @param [Hash] data data required to calculate IBUs; `:extract`, `:alpha`, `:at`, `:mass`, `:volume`
39
- # @param [Hash] options used to change default settings for `extract`, `volume` and `mass`
45
+ # Calculate.ibus({
46
+ # alpha: 6.5,
47
+ # at: 60,
48
+ # extract: 18.5,
49
+ # mass: 30,
50
+ # volume: 40
51
+ # }, { extract: :brix })
52
+ #
53
+ # Calculate.ibus({
54
+ # alpha: 8,
55
+ # at: 30,
56
+ # extract: 1.055,
57
+ # mass: 3,
58
+ # volume: 5
59
+ # }, { extract: :specific_gravity, mass: :ounces, volume: :gallons })
60
+ #
61
+ # @param [Hash] data data required to calculate IBUs; `extract`, `alpha`, `at`, `mass`, `volume`
62
+ # @param [Hash] units used to change default units for `extract`, `volume` and `mass`
40
63
  # @return [Fixnum] IBUs from hop addition
41
- def self.ibus data, options = {}
42
- options.merge!(:extract => :plato) unless options[:extract]
43
- options.merge!(:mass => :grams) unless options[:mass]
44
- options.merge!(:volume => :liters) unless options[:volume]
64
+ def self.ibus data, units = {}
65
+ units.merge!(extract: :plato) unless units[:extract]
66
+ units.merge!(mass: :grams) unless units[:mass]
67
+ units.merge!(volume: :liters) unless units[:volume]
45
68
 
46
- unless options[:extract] == :specific_gravity
47
- data[:extract] = case options[:extract]
69
+ unless units[:extract] == :specific_gravity
70
+ data[:extract] = case units[:extract]
48
71
  when :brix then Convert.brix_to_specific_gravity data[:extract]
49
72
  when :plato then Convert.plato_to_specific_gravity data[:extract]
50
- else raise ArgumentError, "#{options[:extract]} is not recognized as a unit of extract"
73
+ else raise ArgumentError, "#{units[:extract]} is an unknown unit of extract. Use :brix, :plato or :specific_gravity"
51
74
  end
52
75
  end
53
76
 
54
- unless options[:mass] == :grams
55
- data[:mass] = case options[:mass]
77
+ unless units[:mass] == :grams
78
+ data[:mass] = case units[:mass]
56
79
  when :ounces then Convert.ounces_to_grams data[:mass]
57
- else raise ArgumentError, "#{options[:mass]} is not recognized as a unit of mass"
80
+ else raise ArgumentError, "#{units[:mass]} is an unknown unit of mass. Use :grams or :ounces"
58
81
  end
59
82
  end
60
83
 
61
- unless options[:volume] == :liters
62
- data[:volume] = case options[:volume]
84
+ unless units[:volume] == :liters
85
+ data[:volume] = case units[:volume]
63
86
  when :gallons then Convert.gallons_to_liters data[:volume]
64
- else raise ArgumentError, "#{options[:volume]} is not recognized as a unit of volume"
87
+ else raise ArgumentError, "#{units[:volume]} is an unknown unit of volume. Use :gallons or :liters"
65
88
  end
66
89
  end
67
90
 
@@ -70,66 +93,113 @@ module Calculate
70
93
  data[:mass] * 1000 / (data[:volume] * 4.15)).round
71
94
  end
72
95
 
73
- # Calculate hop mass required to achieve specific IBUs.
96
+ # Calculates hop mass required to achieve specific IBUs.
97
+ # Supported extract units are `:brix`, `:plato` and `:specific_gravity`. Default: `:plato`
98
+ # Supported volume units are `:gallons` and `:liters`. Default: `:liters`
74
99
  #
75
100
  # @example
76
- # Calculate.hop_mass_required({ :ibu => 50, :extract => 12, :at => 30, :alpha => 10, :volume => 20 })
77
- # Calculate.hop_mass_required({ :ibu => 15, :extract => 14.5, :at => 15, :alpha => 3.2, :volume => 20 }, { :extract => :brix })
78
- # Calculate.hop_mass_required({ :ibu => 100, :extract => 1.05, :at => 90, :alpha => 12.4, :volume => 10 }, { :extract => :specific_gravity, :volume => :gallons })
79
- #
80
- # @param [Hash] data data required to calculate hop mass required; `:extract`, `:alpha`, `:at`, `:volume`, `:ibus`
81
- # @param [Hash] options used to change default settings for `extract` and `volume`
82
- # @return [Fixnum] hop mass required to achieve specific IBUs
83
- def self.hop_mass_required data, options = {}
84
- options.merge!(:extract => :plato) unless options[:extract]
85
- options.merge!(:volume => :liters) unless options[:volume]
86
-
87
- unless options[:extract] == :specific_gravity
88
- data[:extract] = case options[:extract]
101
+ # Calculate.hop_mass_required({
102
+ # alpha: 13.5,
103
+ # at: 60,
104
+ # extract: 16,
105
+ # ibus: 25,
106
+ # volume: 20
107
+ # })
108
+ #
109
+ # Calculate.hop_mass_required({
110
+ # alpha: 3.2,
111
+ # at: 15,
112
+ # extract: 14.5,
113
+ # ibus: 15,
114
+ # volume: 20
115
+ # }, { extract: :brix })
116
+ #
117
+ # Calculate.hop_mass_required({
118
+ # alpha: 12.4,
119
+ # at: 90,
120
+ # extract: 1.05,
121
+ # ibus: 100,
122
+ # volume: 10
123
+ # }, { extract: :specific_gravity, volume: :gallons })
124
+ #
125
+ # @param [Hash] data data required to calculate hop mass required; `extract`, `ibus`, `alpha`, `at`, `volume`
126
+ # @param [Hash] units used to change default units for `extract` and `volume`
127
+ # @return [Float] hop mass required to achieve specific IBUs
128
+ def self.hop_mass_required data, units = {}
129
+ units.merge!(extract: :plato) unless units[:extract]
130
+ units.merge!(mass: :grams) unless units[:mass]
131
+ units.merge!(volume: :liters) unless units[:volume]
132
+
133
+ unless units[:extract] == :specific_gravity
134
+ data[:extract] = case units[:extract]
89
135
  when :brix then Convert.brix_to_specific_gravity data[:extract]
90
136
  when :plato then Convert.plato_to_specific_gravity data[:extract]
91
- else raise ArgumentError, "#{options[:extract]} is not recognized as a unit of extract"
137
+ else raise ArgumentError, "#{units[:extract]} is an unknown unit of extract. Use :brix, :plato or :specific_gravity"
92
138
  end
93
139
  end
94
140
 
95
- unless options[:volume] == :liters
96
- data[:volume] = case options[:volume]
141
+ unless units[:volume] == :liters
142
+ data[:volume] = case units[:volume]
97
143
  when :gallons then Convert.gallons_to_liters data[:volume]
98
- else raise ArgumentError, "#{options[:volume]} is not recognized as a unit of volume"
144
+ else raise ArgumentError, "#{units[:volume]} is an unknown unit of volume. Use :gallons or :liters"
99
145
  end
100
146
  end
101
147
 
102
- ((data[:volume] * data[:ibus]) /
103
- (hop_utilization(data[:extract], data[:at], :specific_gravity) *
104
- data[:alpha] * 10)).round
148
+ mass = ((data[:volume] * data[:ibus]) /
149
+ (hop_utilization({extract: data[:extract], at: data[:at]}, :specific_gravity) *
150
+ data[:alpha] * 10))
151
+
152
+ units[:mass] == :grams ? mass.round : Convert.grams_to_ounces(mass).round(1)
105
153
  end
106
154
 
107
155
  # Calculate milliliters of HopShot required to achieve specific IBUs.
156
+ # Supported extract units are `:brix`, `:plato` and `:specific_gravity`. Default: `:plato`
157
+ # Supported volume units are `:gallons` and `:liters`. Default: `:liters`
108
158
  #
109
159
  # @example
110
- # Calculate.hopshot_required({ :ibus => 40, :extract => 18, :at => 60, :volume => 20 })
111
- # Calculate.hopshot_required({ :ibus => 40, :extract => 14.5, :at => 60, :volume => 20 }, { :extract => :brix })
112
- # Calculate.hopshot_required({ :ibus => 40, :extract => 1.085, :at => 60, :volume => 10.5 }, { :extract => :specific_gravity, :volume => :gallons })
113
- #
114
- # @param [Hash] data data required to calculate HopShot required; `:extract`, `:at`, `:volume`, `:ibus`
115
- # @param [Hash] options used to change default settings for `extract` and `volume`
116
- # @return [Fixnum] HopShot required to achieve specific IBUs
117
- def self.hopshot_required data, options = {}
118
- options.merge!(:extract => :plato) unless options[:extract]
119
- options.merge!(:volume => :liters) unless options[:volume]
120
-
121
- unless options[:extract] == :specific_gravity
122
- data[:extract] = case options[:extract]
160
+ # Calculate.hopshot_required({
161
+ # alpha: 13.5,
162
+ # at: 60,
163
+ # extract: 16,
164
+ # ibus: 25,
165
+ # volume: 20
166
+ # })
167
+ #
168
+ # Calculate.hopshot_required({
169
+ # alpha: 3.2,
170
+ # at: 15,
171
+ # extract: 14.5,
172
+ # ibus: 15,
173
+ # volume: 20
174
+ # }, { extract: :brix })
175
+ #
176
+ # Calculate.hopshot_required({
177
+ # alpha: 12.4,
178
+ # at: 90,
179
+ # extract: 1.05,
180
+ # ibus: 100,
181
+ # volume: 10
182
+ # }, { extract: :specific_gravity, volume: :gallons })
183
+ #
184
+ # @param [Hash] data data required to calculate hop mass required; `extract`, `ibus`, `at`, `volume`
185
+ # @param [Hash] units used to change default units for `extract` and `volume`
186
+ # @return [Float] milliliters of HopShot required to achieve specific IBUs
187
+ def self.hopshot_required data, units = {}
188
+ units.merge!(extract: :plato) unless units[:extract]
189
+ units.merge!(volume: :liters) unless units[:volume]
190
+
191
+ unless units[:extract] == :specific_gravity
192
+ data[:extract] = case units[:extract]
123
193
  when :brix then Convert.brix_to_specific_gravity data[:extract]
124
194
  when :plato then Convert.plato_to_specific_gravity data[:extract]
125
- else raise ArgumentError, "#{options[:extract]} is not recognized as a unit of extract"
195
+ else raise ArgumentError, "#{units[:extract]} is an unknown unit of extract. Use :brix, :plato or :specific_gravity"
126
196
  end
127
197
  end
128
198
 
129
- unless options[:volume] == :liters
130
- data[:volume] = case options[:volume]
199
+ unless units[:volume] == :liters
200
+ data[:volume] = case units[:volume]
131
201
  when :gallons then Convert.gallons_to_liters data[:volume]
132
- else raise ArgumentError, "#{options[:volume]} is not recognized as a unit of volume"
202
+ else raise ArgumentError, "#{units[:volume]} is an unknown unit of volume. Use :liters or :gallons"
133
203
  end
134
204
  end
135
205
 
@@ -172,12 +242,12 @@ module Calculate
172
242
  #
173
243
  # @param [Float] extract extract level when hop addition is made
174
244
  # @return [Float] extract adjustment
175
- def self.hop_extract_adjustment extract, unit = :plato
176
- unless unit == :specific_gravity
177
- extract = case unit
245
+ def self.hop_extract_adjustment extract, units = :plato
246
+ unless units == :specific_gravity
247
+ extract = case units
178
248
  when :brix then Convert.brix_to_specific_gravity extract
179
249
  when :plato then Convert.plato_to_specific_gravity extract
180
- else raise ArgumentError, "#{unit} is not recognized as a unit of extract"
250
+ else raise ArgumentError, "#{units} is an unknown unit of extract. Use :brix, :plato or :specific_gravity"
181
251
  end
182
252
  end
183
253
 
@@ -1,40 +1,69 @@
1
1
  module Calculate
2
2
 
3
- # Calculate temperature of strike water for dough in.
3
+ # Calculates temperature of strike water for dough in.
4
+ # Supported units are `:metric` and `:us`. Default: `:metric`
4
5
  #
5
6
  # @example
6
- # Calculate.strike_temperature 1.5, 20, 68
7
- # Calculate.strike_temperature 1.5, 70, 154, :us
7
+ # Calculate.strike_temperature({
8
+ # ratio: 1.5,
9
+ # initial: 20,
10
+ # target: 75
11
+ # })
8
12
  #
9
- # @param [Float] ratio water to grain ratio; e.g. 1.5 liters per kilogram
10
- # @param [Fixnum] initial temperature of grains
11
- # @param [Fixnum] target mash temperature
12
- # @param [Symbol] units change units of measure to U.S. customary
13
+ # Calculate.strike_temperature({
14
+ # ratio: 1.25,
15
+ # initial: 65,
16
+ # target: 154
17
+ # }, :us)
18
+ #
19
+ # Calculate.strike_temperature({
20
+ # ratio: 1.5,
21
+ # initial: 60,
22
+ # target: 150,
23
+ # loss: 1.015
24
+ # }, :us)
25
+ #
26
+ # @param [Hash] data data required to calculate hop mass required; `ratio`, `initial`, `target`
27
+ # @param [Symbol] units the unit used to measure temperature
13
28
  # @return [Fixnum] strike water temperature
14
- def self.strike_temperature ratio, initial, target, units = :metric
29
+ def self.strike_temperature data, units = :metric
15
30
  constant = case units
16
31
  when :metric then 0.41
17
32
  when :us then 0.2
18
- else raise ArgumentError, "Units must be one of :metric or :us"
33
+ else raise ArgumentError, "#{units} is an unknown unit of measures. Use :metric or :us"
19
34
  end
20
35
 
21
- ((constant / ratio) * (target - initial) + target).round
36
+ data.merge!(loss: 1) unless data[:loss]
37
+
38
+ (((constant / data[:ratio]) *
39
+ (data[:target] - data[:initial]) +
40
+ data[:target]) * data[:loss]).round
22
41
  end
23
42
 
24
- # Calculate volume of boiling infusion water needed to increase mash temperature.
43
+ # Calculates volume of boiling infusion water needed to increase mash temperature.
44
+ # Supported units are `:metric` and `:us`. Default: `:metric`
25
45
  #
26
46
  # @example
27
- # Calculate.infusion_volume 1.5, 20, 68, 3.6, 4.3
28
- # Calculate.infusion_volume 1.5, 70, 154, 8, 9.6, :us
47
+ # Calculate.infusion_volume({
48
+ # ratio: 1,
49
+ # initial: 40,
50
+ # target: 60,
51
+ # mass: 3.6,
52
+ # volume: 3.6
53
+ # })
54
+ #
55
+ # Calculate.infusion_volume({
56
+ # ratio: 1,
57
+ # initial: 104,
58
+ # target: 140,
59
+ # mass: 8,
60
+ # volume: 8
61
+ # }, :us)
29
62
  #
30
- # @param [Float] ratio water to grain ratio; e.g. 1.5 liters per kilogram
31
- # @param [Fixnum] initial temperature of mash
32
- # @param [Fixnum] target mash temperature
33
- # @param [Float] mass weight of grain in the mash
34
- # @param [Float] volume amount of water already in the mash
35
- # @param [Symbol] units change units of measure to U.S. customary
63
+ # @param [Hash] data data required to calculate infusion volume; `ratio`, `initial`, `target`, `mass`, `volume`
64
+ # @param [Symbol] units the unit used for measurements
36
65
  # @return [Fixnum] infusion water volume
37
- def self.infusion_volume ratio, initial, target, mass, volume, units = :metric
66
+ def self.infusion_volume data, units = :metric
38
67
  case units
39
68
  when :metric
40
69
  boiling = 100
@@ -42,10 +71,12 @@ module Calculate
42
71
  when :us
43
72
  boiling = 212
44
73
  constant = 0.2
45
- else raise ArgumentError, "Units must be one of :metric or :us"
74
+ else raise ArgumentError, "#{units} is an unknown unit of measures. Use :metric or :us"
46
75
  end
47
76
 
48
- ((target - initial) * ((constant * mass) + volume) / (boiling - target)).round 1
77
+ ((data[:target] - data[:initial]) *
78
+ ((constant * data[:mass]) + data[:volume]) /
79
+ (boiling - data[:target])).round 1
49
80
  end
50
81
 
51
- end
82
+ end
@@ -3,42 +3,66 @@ require "conversions/volume"
3
3
 
4
4
  module Calculate
5
5
 
6
- # Calculate the number of yeast cells needed to properly ferment a batch.
6
+ # Calculates the number of yeast cells needed to properly ferment a batch.
7
+ # Supported extract units are `:brix`, `:plato` and `:specific_gravity`. Default: `:plato`
8
+ # Supported beers types are `:ale`, `:hybrid` and `:lager`. Default: `:ale`
9
+ # Supported volume units are `:gallons` and `:liters`. Default: `:liters`
7
10
  #
8
11
  # @example
9
- # Calculate.yeast_cells_needed 12, 20
10
- # Calculate.yeast_cells_needed 12, 20, { :type => :lager }
11
- # Calculate.yeast_cells_needed 12, 50, { :volume => :gallons }
12
- # Calculate.yeast_cells_needed 1.048, 20, { :extract => :specific_gravity }
13
- # Calculate.yeast_cells_needed 1.065, 10.5, { :extract => :specific_gravity, :type => :hybrid, :volume => :gallons }
12
+ # Calculate.yeast_cells_required({
13
+ # extract: 16.5,
14
+ # volume: 19
15
+ # })
14
16
  #
15
- # @param [Float] extract degrees Plato of wort being pitched
17
+ # Calculate.yeast_cells_required({
18
+ # extract: 15.75,
19
+ # volume: 5.25
20
+ # }, { volume: :gallons })
21
+ #
22
+ # Calculate.yeast_cells_required({
23
+ # extract: 1.055,
24
+ # volume: 55
25
+ # }, { extract: :specific_gravity })
26
+ #
27
+ # Calculate.yeast_cells_required({
28
+ # extract: 18,
29
+ # volume: 20,
30
+ # type: :hybrid
31
+ # })
32
+ #
33
+ # Calculate.yeast_cells_required({
34
+ # extract: 21.5,
35
+ # volume: 10.5,
36
+ # type: :lager
37
+ # }, { volume: :gallons, extract: :brix })
38
+ #
39
+ # @param [Hash] data data required to calculate yeast cells required; `extract`, `volume`, `type`
16
40
  # @param [Float] volume liters of wort being pitched
17
41
  # @param [Hash] options used to change default settings for `extract`, `volume` and `type`
18
42
  # @return [Fixnum] yeast cells needed to ferment the batch
19
- def self.yeast_cells_required extract, volume, options = {}
20
- options.merge!(:volume => :liters) unless options[:volume]
21
- options.merge!(:extract => :plato) unless options[:extract]
22
- options.merge!(:type => :ale) unless options[:type]
43
+ def self.yeast_cells_required data, units = {}
44
+ data.merge!(:type => :ale) unless data[:type]
45
+ units.merge!(:extract => :plato) unless units[:extract]
46
+ units.merge!(:volume => :liters) unless units[:volume]
23
47
 
24
- cells_per_milliliter = case options[:type]
48
+ cells_per_milliliter = case data[:type]
25
49
  when :ale then 750_000
26
50
  when :hybrid then 1_125_000
27
51
  when :lager then 1_500_000
28
- else raise ArgumentError, "#{options[:type]} is not recognized as a beer type"
52
+ else raise ArgumentError, "#{data[:type]} is an unknown type of beer. Use :ale, :hybrid or :lager"
29
53
  end
30
54
 
31
- volume = case options[:volume]
32
- when :liters then volume
33
- when :gallons then Convert.gallons_to_liters volume
34
- else raise ArgumentError, "#{options[:volume]} is not recognized as measure of volume"
55
+ volume = case units[:volume]
56
+ when :liters then data[:volume]
57
+ when :gallons then Convert.gallons_to_liters data[:volume]
58
+ else raise ArgumentError, "#{units[:volume]} is an unknown unit of volume. Use :gallons or :liters"
35
59
  end
36
60
 
37
- extract = case options[:extract]
38
- when :plato then extract
39
- when :brix then Convert.specific_gravity_to_plato(Convert.brix_to_specific_gravity extract)
40
- when :specific_gravity then Convert.specific_gravity_to_plato extract
41
- else raise ArgumentError, "#{options[:extract]} is not recognized as measure of extract"
61
+ extract = case units[:extract]
62
+ when :plato then data[:extract]
63
+ when :brix then Convert.specific_gravity_to_plato(Convert.brix_to_specific_gravity data[:extract])
64
+ when :specific_gravity then Convert.specific_gravity_to_plato data[:extract]
65
+ else raise ArgumentError, "#{units[:extract]} is an unknown unit of extract. Use :brix, :plato or :specific_gravity"
42
66
  end
43
67
 
44
68
  (cells_per_milliliter * (volume * 1000) * extract).round