gravitheque 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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