gravitheque 0.1.0 → 0.2.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.
- data/.gitignore +2 -0
- data/Gemfile +9 -2
- data/Guardfile +4 -0
- data/README.md +65 -6
- data/gravitheque.gemspec +1 -1
- data/lib/calculators/hops.rb +187 -0
- data/lib/calculators/yeast.rb +47 -0
- data/lib/conversions/extract.rb +2 -0
- data/test/calculators/test_hops.rb +238 -0
- data/test/calculators/test_yeast.rb +78 -0
- data/test/conversions/test_extract.rb +6 -0
- data/test/test_helper.rb +15 -0
- metadata +10 -4
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
source :rubygems
|
2
2
|
|
3
3
|
group :development do
|
4
|
-
gem "growl"
|
5
4
|
gem "guard-minitest"
|
5
|
+
gem "guard-yard"
|
6
6
|
end
|
7
7
|
|
8
8
|
group :documentation do
|
@@ -11,4 +11,11 @@ group :documentation do
|
|
11
11
|
gem "yard"
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
group :mac do
|
15
|
+
gem "growl"
|
16
|
+
gem "rb-fsevent"
|
17
|
+
end
|
18
|
+
|
19
|
+
group :test do
|
20
|
+
gem "simplecov"
|
21
|
+
end
|
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,45 @@
|
|
1
1
|
# Gravitheque [](http://travis-ci.org/johnmuhl/gravitheque)
|
2
2
|
|
3
|
+
**This is still a work in progress; as such neither the library nor web
|
4
|
+
application are particularly useful right now.**
|
5
|
+
|
3
6
|
A collection of [open source][oss] tools for brewers. It can be used as
|
4
7
|
a [web application][web], interactively through IRB or as a [library][lib] to
|
5
|
-
build your own brewing application. For use as a library refer the full
|
8
|
+
build your own brewing application. For use as a library refer to the full
|
6
9
|
[documentation][doc].
|
7
10
|
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
```bash
|
14
|
+
gem install gravitheque
|
15
|
+
```
|
16
|
+
|
17
|
+
To use the Gravitheque library nothing more than a compatible Ruby 1.9.3
|
18
|
+
implementation is required. It may work on older and newer versions but only by
|
19
|
+
coincidence; refer to the [build logs][trv] to see which Rubies are supported.
|
20
|
+
|
21
|
+
### Development
|
22
|
+
|
23
|
+
```bash
|
24
|
+
git clone git://github.com/johnmuhl/gravitheque.git
|
25
|
+
cd gravitheque
|
26
|
+
bin/test
|
27
|
+
```
|
28
|
+
|
29
|
+
Handy (non-essential) development dependencies can be installed with Bundler.
|
30
|
+
|
31
|
+
```bash
|
32
|
+
bundle install
|
33
|
+
# if you're on Linux or Windows
|
34
|
+
# bundle install --without mac
|
35
|
+
```
|
36
|
+
|
37
|
+
Now use [Guard][grd] to run tests and update documentation automatically.
|
38
|
+
|
39
|
+
```bash
|
40
|
+
guard start --clear
|
41
|
+
```
|
42
|
+
|
8
43
|
## Calculators
|
9
44
|
|
10
45
|
### Alcohol
|
@@ -39,16 +74,38 @@ Calculate.calories_per_serving 1.055, 1.012, :specific_gravity
|
|
39
74
|
Calculate.calories_per_serving 16.4, 8.2, :brix
|
40
75
|
```
|
41
76
|
|
77
|
+
### Hops
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
require "calculators/hops"
|
81
|
+
|
82
|
+
Calculate.hop_utilization 15, 45
|
83
|
+
Calculate.hop_utilization 1.055, 60, :specific_gravity
|
84
|
+
Calculate.hop_utilization 12, 15, :brix
|
85
|
+
|
86
|
+
Calculate.hop_mass_required({ :ibus => 50, :extract => 12, :at => 30, :alpha => 10, :volume => 20 })
|
87
|
+
Calculate.hop_mass_required({ :ibus => 15, :extract => 14.5, :at => 15, :alpha => 3.2, :volume => 20 }, { :extract => :brix })
|
88
|
+
Calculate.hop_mass_required({ :ibus => 100, :extract => 1.05, :at => 90, :alpha => 12.4, :volume => 10 }, { :extract => :specific_gravity, :volume => :gallons })
|
89
|
+
|
90
|
+
Calculate.hopshot_required({ :ibus => 40, :extract => 18, :at => 60, :volume => 20 })
|
91
|
+
Calculate.hopshot_required({ :ibus => 40, :extract => 14.5, :at => 60, :volume => 20 }, { :extract => :brix })
|
92
|
+
Calculate.hopshot_required({ :ibus => 40, :extract => 1.085, :at => 60, :volume => 10.5 }, { :extract => :specific_gravity, :volume => :gallons })
|
93
|
+
|
94
|
+
Calculate.ibus({ :extract => 15, :at => 60, :alpha => 6.5, :mass => 56, :volume => 20 })
|
95
|
+
Calculate.ibus({ :extract => 18.5, :at => 60, :alpha => 6.5, :mass => 56, :volume => 20 }, { :extract => :brix })
|
96
|
+
Calculate.ibus({ :extract => 1.055, :at => 60, :alpha => 6.5, :mass => 2, :volume => 5 }, { :extract => :specific_gravity, :mass => :ounces, :volume => :gallons })
|
97
|
+
```
|
98
|
+
|
42
99
|
### Yeast
|
43
100
|
|
44
101
|
```ruby
|
45
102
|
require "calculators/yeast"
|
46
103
|
|
47
|
-
Calculate.yeast_cells_required 16.5,
|
48
|
-
Calculate.yeast_cells_required 15.75,
|
104
|
+
Calculate.yeast_cells_required 16.5, 19
|
105
|
+
Calculate.yeast_cells_required 15.75, 5.25, { :volume => :gallons }
|
49
106
|
Calculate.yeast_cells_required 1.055, 55, { :extract => :specific_gravity }
|
50
|
-
Calculate.yeast_cells_required 18,
|
51
|
-
Calculate.yeast_cells_required 21.5,
|
107
|
+
Calculate.yeast_cells_required 18, 20, { :type => :hybrid }
|
108
|
+
Calculate.yeast_cells_required 21.5, 10.5, { :volume => :gallons, :extract => :brix, :type => :lager }
|
52
109
|
```
|
53
110
|
|
54
111
|
## Conversions
|
@@ -106,6 +163,8 @@ Convert.quarts_to_liters 11
|
|
106
163
|
```
|
107
164
|
|
108
165
|
[doc]: http://rubydoc.info/gems/gravitheque
|
166
|
+
[grd]: https://github.com/guard/guard
|
109
167
|
[lib]: http://rubygems.org/gems/gravitheque
|
110
|
-
[oss]: https://github.com/johnmuhl/gravitheque
|
168
|
+
[oss]: https://github.com/johnmuhl/gravitheque
|
169
|
+
[trv]: http://travis-ci.org/johnmuhl/gravitheque
|
111
170
|
[web]: http://gravitheque.herokuapp.com/
|
data/gravitheque.gemspec
CHANGED
@@ -0,0 +1,187 @@
|
|
1
|
+
require "conversions/extract"
|
2
|
+
require "conversions/mass"
|
3
|
+
require "conversions/volume"
|
4
|
+
|
5
|
+
module Calculate
|
6
|
+
|
7
|
+
# Calculate hop utilization.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# Calculate.hop_utilization 12, 20
|
11
|
+
# Calculate.hop_utilization 16.3, 45, :brix
|
12
|
+
# Calculate.hop_utilization 1.089, 60, :specific_gravity
|
13
|
+
#
|
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`
|
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"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
((hop_extract_adjustment extract, :specific_gravity) *
|
28
|
+
((hop_boil_time_adjustment at) / 4.15)).round 2
|
29
|
+
end
|
30
|
+
|
31
|
+
# Calculate IBUs for hop addition.
|
32
|
+
#
|
33
|
+
# @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
|
+
#
|
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`
|
40
|
+
# @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]
|
45
|
+
|
46
|
+
unless options[:extract] == :specific_gravity
|
47
|
+
data[:extract] = case options[:extract]
|
48
|
+
when :brix then Convert.brix_to_specific_gravity data[:extract]
|
49
|
+
when :plato then Convert.plato_to_specific_gravity data[:extract]
|
50
|
+
else raise ArgumentError, "#{options[:extract]} is not recognized as a unit of extract"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
unless options[:mass] == :grams
|
55
|
+
data[:mass] = case options[:mass]
|
56
|
+
when :ounces then Convert.ounces_to_grams data[:mass]
|
57
|
+
else raise ArgumentError, "#{options[:mass]} is not recognized as a unit of mass"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
unless options[:volume] == :liters
|
62
|
+
data[:volume] = case options[:volume]
|
63
|
+
when :gallons then Convert.gallons_to_liters data[:volume]
|
64
|
+
else raise ArgumentError, "#{options[:volume]} is not recognized as a unit of volume"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
(hop_extract_adjustment(data[:extract], :specific_gravity) *
|
69
|
+
hop_boil_time_adjustment(data[:at]) * (data[:alpha] / 100) *
|
70
|
+
data[:mass] * 1000 / (data[:volume] * 4.15)).round
|
71
|
+
end
|
72
|
+
|
73
|
+
# Calculate hop mass required to achieve specific IBUs.
|
74
|
+
#
|
75
|
+
# @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]
|
89
|
+
when :brix then Convert.brix_to_specific_gravity data[:extract]
|
90
|
+
when :plato then Convert.plato_to_specific_gravity data[:extract]
|
91
|
+
else raise ArgumentError, "#{options[:extract]} is not recognized as a unit of extract"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
unless options[:volume] == :liters
|
96
|
+
data[:volume] = case options[:volume]
|
97
|
+
when :gallons then Convert.gallons_to_liters data[:volume]
|
98
|
+
else raise ArgumentError, "#{options[:volume]} is not recognized as a unit of volume"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
((data[:volume] * data[:ibus]) /
|
103
|
+
(hop_utilization(data[:extract], data[:at], :specific_gravity) *
|
104
|
+
data[:alpha] * 10)).round
|
105
|
+
end
|
106
|
+
|
107
|
+
# Calculate milliliters of HopShot required to achieve specific IBUs.
|
108
|
+
#
|
109
|
+
# @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]
|
123
|
+
when :brix then Convert.brix_to_specific_gravity data[:extract]
|
124
|
+
when :plato then Convert.plato_to_specific_gravity data[:extract]
|
125
|
+
else raise ArgumentError, "#{options[:extract]} is not recognized as a unit of extract"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
unless options[:volume] == :liters
|
130
|
+
data[:volume] = case options[:volume]
|
131
|
+
when :gallons then Convert.gallons_to_liters data[:volume]
|
132
|
+
else raise ArgumentError, "#{options[:volume]} is not recognized as a unit of volume"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
unadjusted_amount = (data[:ibus] / 10.0) * (data[:volume] / 19.0)
|
137
|
+
hopshot_required = unadjusted_amount
|
138
|
+
|
139
|
+
if data[:extract] >= 1.08 && data[:extract] < 1.1
|
140
|
+
hopshot_required = unadjusted_amount + (unadjusted_amount * 0.1)
|
141
|
+
elsif data[:extract] >= 1.1 && data[:extract] < 1.15
|
142
|
+
hopshot_required = unadjusted_amount + (unadjusted_amount * 0.2)
|
143
|
+
elsif data[:extract] >= 1.15
|
144
|
+
hopshot_required = unadjusted_amount + (unadjusted_amount * 0.3)
|
145
|
+
end
|
146
|
+
|
147
|
+
if data[:at] >= 90
|
148
|
+
hopshot_required = hopshot_required - (unadjusted_amount * 0.1)
|
149
|
+
end
|
150
|
+
|
151
|
+
hopshot_required.round 1
|
152
|
+
end
|
153
|
+
|
154
|
+
# Calculate hop boil time adjustment.
|
155
|
+
#
|
156
|
+
# @example
|
157
|
+
# Calculate.hop_boil_time_adjustment 60
|
158
|
+
# Calculate.hop_boil_time_adjustment 15
|
159
|
+
#
|
160
|
+
# @param [Fixnum] at boil time remaining when hop addition is made
|
161
|
+
# @return [Float] boil time adjustment
|
162
|
+
def self.hop_boil_time_adjustment at
|
163
|
+
(1 - Math.exp(-0.04 * at)).round 2
|
164
|
+
end
|
165
|
+
|
166
|
+
# Calculate hop extract adjustment.
|
167
|
+
#
|
168
|
+
# @example
|
169
|
+
# Calculate.hop_extract_adjustment 12
|
170
|
+
# Calculate.hop_extract_adjustment 14.2, :brix
|
171
|
+
# Calculate.hop_extract_adjustment 1.065, :specific_gravity
|
172
|
+
#
|
173
|
+
# @param [Float] extract extract level when hop addition is made
|
174
|
+
# @return [Float] extract adjustment
|
175
|
+
def self.hop_extract_adjustment extract, unit = :plato
|
176
|
+
unless unit == :specific_gravity
|
177
|
+
extract = case unit
|
178
|
+
when :brix then Convert.brix_to_specific_gravity extract
|
179
|
+
when :plato then Convert.plato_to_specific_gravity extract
|
180
|
+
else raise ArgumentError, "#{unit} is not recognized as a unit of extract"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
(1.65 * 0.000125 ** (extract - 1)).round 2
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "conversions/extract"
|
2
|
+
require "conversions/volume"
|
3
|
+
|
4
|
+
module Calculate
|
5
|
+
|
6
|
+
# Calculate the number of yeast cells needed to properly ferment a batch.
|
7
|
+
#
|
8
|
+
# @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 }
|
14
|
+
#
|
15
|
+
# @param [Float] extract degrees Plato of wort being pitched
|
16
|
+
# @param [Float] volume liters of wort being pitched
|
17
|
+
# @param [Hash] options used to change default settings for `extract`, `volume` and `type`
|
18
|
+
# @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]
|
23
|
+
|
24
|
+
cells_per_milliliter = case options[:type]
|
25
|
+
when :ale then 750_000
|
26
|
+
when :hybrid then 1_125_000
|
27
|
+
when :lager then 1_500_000
|
28
|
+
else raise ArgumentError, "#{options[:type]} is not recognized as a beer type"
|
29
|
+
end
|
30
|
+
|
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"
|
35
|
+
end
|
36
|
+
|
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"
|
42
|
+
end
|
43
|
+
|
44
|
+
(cells_per_milliliter * (volume * 1000) * extract).round
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/conversions/extract.rb
CHANGED
@@ -0,0 +1,238 @@
|
|
1
|
+
require "./test/test_helper"
|
2
|
+
require "calculators/hops"
|
3
|
+
|
4
|
+
describe Calculate do
|
5
|
+
|
6
|
+
it "must calculate the boil time adjustment" do
|
7
|
+
(Calculate.hop_boil_time_adjustment 60).must_equal 0.91
|
8
|
+
end
|
9
|
+
|
10
|
+
it "must calculate the extract adjustment from Plato" do
|
11
|
+
(Calculate.hop_extract_adjustment 14).must_equal 0.99
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must calculate the extract adjustment from Brix" do
|
15
|
+
(Calculate.hop_extract_adjustment 16, :brix).must_equal 0.91
|
16
|
+
end
|
17
|
+
|
18
|
+
it "must calculate the extract adjustment from specific gravity" do
|
19
|
+
(Calculate.hop_extract_adjustment 1.055, :specific_gravity).must_equal 1.01
|
20
|
+
end
|
21
|
+
|
22
|
+
it "must calculate hop utilization from Plato" do
|
23
|
+
(Calculate.hop_utilization 15, 60).must_equal 0.21
|
24
|
+
end
|
25
|
+
|
26
|
+
it "must calculate hop utilization from Brix" do
|
27
|
+
(Calculate.hop_utilization 12, 30, :brix).must_equal 0.18
|
28
|
+
end
|
29
|
+
|
30
|
+
it "must calculate hop utilization from specific gravity" do
|
31
|
+
(Calculate.hop_utilization 1.065, 10, :specific_gravity).must_equal 0.07
|
32
|
+
end
|
33
|
+
|
34
|
+
it "must calculate IBUs from hop addition using Plato" do
|
35
|
+
Calculate.ibus({
|
36
|
+
extract: 12.3,
|
37
|
+
at: 60,
|
38
|
+
alpha: 5.0,
|
39
|
+
mass: 56,
|
40
|
+
volume: 19
|
41
|
+
}).must_equal 34
|
42
|
+
end
|
43
|
+
|
44
|
+
it "must calculate IBUs from hop addition using ounces" do
|
45
|
+
Calculate.ibus({
|
46
|
+
extract: 12.3,
|
47
|
+
at: 60,
|
48
|
+
alpha: 5.0,
|
49
|
+
mass: 2,
|
50
|
+
volume: 19
|
51
|
+
}, { :mass => :ounces }).must_equal 34
|
52
|
+
end
|
53
|
+
|
54
|
+
it "must calculate IBUs from hop addition using gallons" do
|
55
|
+
Calculate.ibus({
|
56
|
+
extract: 12.3,
|
57
|
+
at: 60,
|
58
|
+
alpha: 5.0,
|
59
|
+
mass: 56,
|
60
|
+
volume: 5
|
61
|
+
}, { :volume => :gallons }).must_equal 34
|
62
|
+
end
|
63
|
+
|
64
|
+
it "must calculate IBUs from hop addition using Brix" do
|
65
|
+
Calculate.ibus({
|
66
|
+
extract: 12.2,
|
67
|
+
at: 60,
|
68
|
+
alpha: 5.0,
|
69
|
+
mass: 56,
|
70
|
+
volume: 19
|
71
|
+
}, { :extract => :brix }).must_equal 34
|
72
|
+
end
|
73
|
+
|
74
|
+
it "must calculate IBUs from hop addition using specific gravity" do
|
75
|
+
Calculate.ibus({
|
76
|
+
extract: 1.05,
|
77
|
+
at: 60,
|
78
|
+
alpha: 5.0,
|
79
|
+
mass: 56,
|
80
|
+
volume: 19
|
81
|
+
}, { :extract => :specific_gravity }).must_equal 34
|
82
|
+
end
|
83
|
+
|
84
|
+
it "must calculate hop mass required for a specific IBU contribution using specific gravity" do
|
85
|
+
Calculate.hop_mass_required({
|
86
|
+
extract: 1.05,
|
87
|
+
at: 60,
|
88
|
+
alpha: 5.0,
|
89
|
+
ibus: 34,
|
90
|
+
volume: 19
|
91
|
+
}, { :extract => :specific_gravity }).must_equal 56
|
92
|
+
end
|
93
|
+
|
94
|
+
it "must calculate hop mass required for a specific IBU contribution using Plato" do
|
95
|
+
Calculate.hop_mass_required({
|
96
|
+
extract: 12.3,
|
97
|
+
at: 60,
|
98
|
+
alpha: 5.0,
|
99
|
+
ibus: 34,
|
100
|
+
volume: 19
|
101
|
+
}).must_equal 56
|
102
|
+
end
|
103
|
+
|
104
|
+
it "must calculate hop mass required for a specific IBU contribution using Brix" do
|
105
|
+
Calculate.hop_mass_required({
|
106
|
+
extract: 12.2,
|
107
|
+
at: 60,
|
108
|
+
alpha: 5.0,
|
109
|
+
ibus: 34,
|
110
|
+
volume: 19
|
111
|
+
}, { :extract => :brix }).must_equal 56
|
112
|
+
end
|
113
|
+
|
114
|
+
it "must calculate hop mass required for a specific IBU contribution using gallons" do
|
115
|
+
Calculate.hop_mass_required({
|
116
|
+
extract: 12.3,
|
117
|
+
at: 60,
|
118
|
+
alpha: 5.0,
|
119
|
+
ibus: 34,
|
120
|
+
volume: 5
|
121
|
+
}, { :volume => :gallons }).must_equal 56
|
122
|
+
end
|
123
|
+
|
124
|
+
it "must calculate milliliters of HopShot required for a specific IBU contribution using specific gravity" do
|
125
|
+
Calculate.hopshot_required({
|
126
|
+
ibus: 35,
|
127
|
+
at: 60,
|
128
|
+
volume: 19,
|
129
|
+
extract: 1.045
|
130
|
+
}, { :extract => :specific_gravity }).must_equal 3.5
|
131
|
+
|
132
|
+
Calculate.hopshot_required({
|
133
|
+
ibus: 80,
|
134
|
+
at: 60,
|
135
|
+
volume: 38,
|
136
|
+
extract: 1.085
|
137
|
+
}, { :extract => :specific_gravity }).must_equal 17.6
|
138
|
+
|
139
|
+
Calculate.hopshot_required({
|
140
|
+
ibus: 80,
|
141
|
+
at: 60,
|
142
|
+
volume: 38,
|
143
|
+
extract: 1.1
|
144
|
+
}, { :extract => :specific_gravity }).must_equal 19.2
|
145
|
+
|
146
|
+
Calculate.hopshot_required({
|
147
|
+
ibus: 60,
|
148
|
+
at: 90,
|
149
|
+
volume: 19,
|
150
|
+
extract: 1.15
|
151
|
+
}, { :extract => :specific_gravity }).must_equal 7.2
|
152
|
+
end
|
153
|
+
|
154
|
+
it "must calculate milliliters of HopShot required for a specific IBU contribution using Plato" do
|
155
|
+
Calculate.hopshot_required({
|
156
|
+
ibus: 35,
|
157
|
+
at: 60,
|
158
|
+
volume: 19,
|
159
|
+
extract: 12.3
|
160
|
+
}).must_equal 3.5
|
161
|
+
|
162
|
+
Calculate.hopshot_required({
|
163
|
+
ibus: 80,
|
164
|
+
at: 60,
|
165
|
+
volume: 38,
|
166
|
+
extract: 20.4
|
167
|
+
}).must_equal 17.6
|
168
|
+
|
169
|
+
Calculate.hopshot_required({
|
170
|
+
ibus: 80,
|
171
|
+
at: 60,
|
172
|
+
volume: 38,
|
173
|
+
extract: 23.7
|
174
|
+
}).must_equal 19.2
|
175
|
+
|
176
|
+
Calculate.hopshot_required({
|
177
|
+
ibus: 60,
|
178
|
+
at: 90,
|
179
|
+
volume: 19,
|
180
|
+
extract: 34.2
|
181
|
+
}).must_equal 7.2
|
182
|
+
end
|
183
|
+
|
184
|
+
it "must calculate milliliters of HopShot required for a specific IBU contribution using Brix" do
|
185
|
+
Calculate.hopshot_required({
|
186
|
+
ibus: 35,
|
187
|
+
at: 60,
|
188
|
+
volume: 19,
|
189
|
+
extract: 12.2
|
190
|
+
}, { :extract => :brix }).must_equal 3.5
|
191
|
+
|
192
|
+
Calculate.hopshot_required({
|
193
|
+
ibus: 80,
|
194
|
+
at: 60,
|
195
|
+
volume: 38,
|
196
|
+
extract: 20.3
|
197
|
+
}, { :extract => :brix }).must_equal 17.6
|
198
|
+
|
199
|
+
Calculate.hopshot_required({
|
200
|
+
ibus: 80,
|
201
|
+
at: 60,
|
202
|
+
volume: 38,
|
203
|
+
extract: 23.6
|
204
|
+
}, { :extract => :brix }).must_equal 19.2
|
205
|
+
|
206
|
+
Calculate.hopshot_required({
|
207
|
+
ibus: 60,
|
208
|
+
at: 90,
|
209
|
+
volume: 19,
|
210
|
+
extract: 34.1
|
211
|
+
}, { :extract => :brix }).must_equal 7.2
|
212
|
+
end
|
213
|
+
|
214
|
+
it "must calculate milliliters of HopShot required for a specific IBU contribution using gallons" do
|
215
|
+
Calculate.hopshot_required({
|
216
|
+
ibus: 35,
|
217
|
+
at: 60,
|
218
|
+
volume: 5,
|
219
|
+
extract: 11.2
|
220
|
+
}, { :volume => :gallons }).must_equal 3.5
|
221
|
+
end
|
222
|
+
|
223
|
+
it "must raise an exception for unrecognized units of measure" do
|
224
|
+
lambda { Calculate.hop_extract_adjustment 99, :razor_blades }.must_raise ArgumentError
|
225
|
+
lambda { Calculate.hop_utilization 18, 90, :razor_blades }.must_raise ArgumentError
|
226
|
+
|
227
|
+
lambda { Calculate.ibus({ extract: 1.05, at: 60, alpha: 5.0, mass: 56, volume: 19 }, { :extract => :razor_blades }) }.must_raise ArgumentError
|
228
|
+
lambda { Calculate.ibus({ extract: 1.05, at: 60, alpha: 5.0, mass: 56, volume: 19 }, { :mass => :razor_blades }) }.must_raise ArgumentError
|
229
|
+
lambda { Calculate.ibus({ extract: 1.05, at: 60, alpha: 5.0, mass: 56, volume: 19 }, { :volume => :razor_blades }) }.must_raise ArgumentError
|
230
|
+
|
231
|
+
lambda { Calculate.hop_mass_required({ extract: 1.05, at: 60, alpha: 5.0, ibus: 56, volume: 19 }, { :extract => :razor_blades }) }.must_raise ArgumentError
|
232
|
+
lambda { Calculate.hop_mass_required({ extract: 1.05, at: 60, alpha: 5.0, ibus: 56, volume: 19 }, { :volume => :razor_blades }) }.must_raise ArgumentError
|
233
|
+
|
234
|
+
lambda { Calculate.hopshot_required({ extract: 1.05, at: 60, alpha: 5.0, ibus: 56, volume: 19 }, { :extract => :razor_blades }) }.must_raise ArgumentError
|
235
|
+
lambda { Calculate.hopshot_required({ extract: 1.05, at: 60, alpha: 5.0, ibus: 56, volume: 19 }, { :volume => :razor_blades }) }.must_raise ArgumentError
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require "./test/test_helper"
|
2
|
+
require "calculators/yeast"
|
3
|
+
|
4
|
+
describe Calculate do
|
5
|
+
|
6
|
+
it "must calculate yeast cells needed for an ale" do
|
7
|
+
(Calculate.yeast_cells_required 12, 20).must_equal 180_000_000_000
|
8
|
+
end
|
9
|
+
|
10
|
+
it "must calculate yeast cells needed for a hybrid" do
|
11
|
+
(Calculate.yeast_cells_required 12, 20, { :type => :hybrid }).must_equal 270_000_000_000
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must calculate yeast cells needed for a lager" do
|
15
|
+
(Calculate.yeast_cells_required 12, 20, { :type => :lager }).must_equal 360_000_000_000
|
16
|
+
end
|
17
|
+
|
18
|
+
it "must calculate yeast cells needed for an ale using gallons" do
|
19
|
+
(Calculate.yeast_cells_required 12, 5.3, { :volume => :gallons }).must_equal 180_900_000_000
|
20
|
+
end
|
21
|
+
|
22
|
+
it "must calculate yeast cells needed for an ale using specific gravity" do
|
23
|
+
(Calculate.yeast_cells_required 1.048, 20, { :extract => :specific_gravity }).must_equal 178_500_000_000
|
24
|
+
end
|
25
|
+
|
26
|
+
it "must calculate yeast cells needed for an ale using Brix" do
|
27
|
+
(Calculate.yeast_cells_required 18.5, 20, { :extract => :brix }).must_equal 279_000_000_000
|
28
|
+
end
|
29
|
+
|
30
|
+
it "must calculate yeast cells needed for an ale using gallons and specific gravity" do
|
31
|
+
(Calculate.yeast_cells_required 1.048, 5.3, { :volume => :gallons, :extract => :specific_gravity }).must_equal 179_392_500_000
|
32
|
+
end
|
33
|
+
|
34
|
+
it "must calculate yeast cells needed for an hybrid using gallons" do
|
35
|
+
(Calculate.yeast_cells_required 12, 5.3, { :volume => :gallons, :type => :hybrid }).must_equal 271_350_000_000
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must calculate yeast cells needed for an hybrid using specific gravity" do
|
39
|
+
(Calculate.yeast_cells_required 1.048, 20, { :extract => :specific_gravity, :type => :hybrid }).must_equal 267_750_000_000
|
40
|
+
end
|
41
|
+
|
42
|
+
it "must calculate yeast cells needed for an hybrid using Brix" do
|
43
|
+
(Calculate.yeast_cells_required 18.5, 20, { :extract => :brix, :type => :hybrid }).must_equal 418_500_000_000
|
44
|
+
end
|
45
|
+
|
46
|
+
it "must calculate yeast cells needed for an hybrid using gallons and specific gravity" do
|
47
|
+
(Calculate.yeast_cells_required 1.048, 5.3, { :volume => :gallons, :extract => :specific_gravity, :type => :hybrid }).must_equal 269_088_750_000
|
48
|
+
end
|
49
|
+
|
50
|
+
it "must calculate yeast cells needed for an lager using gallons" do
|
51
|
+
(Calculate.yeast_cells_required 12, 5.3, { :volume => :gallons, :type => :lager }).must_equal 361_800_000_000
|
52
|
+
end
|
53
|
+
|
54
|
+
it "must calculate yeast cells needed for an lager using specific gravity" do
|
55
|
+
(Calculate.yeast_cells_required 1.048, 20, { :extract => :specific_gravity, :type => :lager }).must_equal 357_000_000_000
|
56
|
+
end
|
57
|
+
|
58
|
+
it "must calculate yeast cells needed for an lager using Brix" do
|
59
|
+
(Calculate.yeast_cells_required 18.5, 20, { :extract => :brix, :type => :lager }).must_equal 558_000_000_000
|
60
|
+
end
|
61
|
+
|
62
|
+
it "must calculate yeast cells needed for an lager using gallons and specific gravity" do
|
63
|
+
(Calculate.yeast_cells_required 1.048, 5.3, { :volume => :gallons, :extract => :specific_gravity, :type => :lager }).must_equal 358_785_000_000
|
64
|
+
end
|
65
|
+
|
66
|
+
it "must raise an exception when the beer type is unrecognized" do
|
67
|
+
lambda { Calculate.yeast_cells_required 15, 20, { :type => :wine } }.must_raise ArgumentError
|
68
|
+
end
|
69
|
+
|
70
|
+
it "must raise an exception when the extract unit is unrecognized" do
|
71
|
+
lambda { Calculate.yeast_cells_required 15, 20, { :extract => :squeeze } }.must_raise ArgumentError
|
72
|
+
end
|
73
|
+
|
74
|
+
it "must raise an exception when the volume unit is unrecognized" do
|
75
|
+
lambda { Calculate.yeast_cells_required 15, 20, { :volume => :barrels } }.must_raise ArgumentError
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -20,7 +20,13 @@ describe Convert do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it "must convert specific gravity to temperature corrected specific gravity" do
|
23
|
+
(Convert.specific_gravity_to_temperature_corrected_gravity 1.064, 2).must_equal 1.063
|
23
24
|
(Convert.specific_gravity_to_temperature_corrected_gravity 1.064, 42).must_equal 1.072
|
25
|
+
(Convert.specific_gravity_to_temperature_corrected_gravity 1.055, 12, :celsius).must_equal 1.068
|
26
|
+
end
|
27
|
+
|
28
|
+
it "must raise an exception when the temperature unit for specific gravity to temperature corrected specific gravity is not recognized" do
|
29
|
+
lambda { Convert.specific_gravity_to_temperature_corrected_gravity 1.055, 12, :kelvin }.must_raise ArgumentError
|
24
30
|
end
|
25
31
|
|
26
32
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# Rubinius does not (yet?) have the 1.9 Coverage module
|
2
|
+
unless RUBY_DESCRIPTION =~ /rubinius/i
|
3
|
+
require "simplecov"
|
4
|
+
|
5
|
+
class SimpleCov::Formatter::NoHTMLFormatter
|
6
|
+
def format result
|
7
|
+
puts "\n#{result.covered_lines} of #{result.total_lines} LOC tested (#{result.covered_percent.round(2)}%)"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
SimpleCov.start do
|
12
|
+
@formatter = SimpleCov::Formatter::NoHTMLFormatter
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
1
16
|
$:.push File.expand_path "../../lib", __FILE__
|
2
17
|
|
3
18
|
require "minitest/autorun"
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gravitheque
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.1.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- john muhl
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-24 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Tools for brewers.
|
15
15
|
email:
|
@@ -30,6 +30,8 @@ files:
|
|
30
30
|
- lib/calculators.rb
|
31
31
|
- lib/calculators/alcohol.rb
|
32
32
|
- lib/calculators/calories.rb
|
33
|
+
- lib/calculators/hops.rb
|
34
|
+
- lib/calculators/yeast.rb
|
33
35
|
- lib/conversions.rb
|
34
36
|
- lib/conversions/extract.rb
|
35
37
|
- lib/conversions/mass.rb
|
@@ -38,6 +40,8 @@ files:
|
|
38
40
|
- lib/gravitheque.rb
|
39
41
|
- test/calculators/test_alcohol.rb
|
40
42
|
- test/calculators/test_calories.rb
|
43
|
+
- test/calculators/test_hops.rb
|
44
|
+
- test/calculators/test_yeast.rb
|
41
45
|
- test/conversions/test_extract.rb
|
42
46
|
- test/conversions/test_mass.rb
|
43
47
|
- test/conversions/test_temperature.rb
|
@@ -50,17 +54,17 @@ rdoc_options: []
|
|
50
54
|
require_paths:
|
51
55
|
- lib
|
52
56
|
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
53
58
|
requirements:
|
54
59
|
- - ! '>='
|
55
60
|
- !ruby/object:Gem::Version
|
56
61
|
version: '0'
|
57
|
-
none: false
|
58
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
59
64
|
requirements:
|
60
65
|
- - ! '>='
|
61
66
|
- !ruby/object:Gem::Version
|
62
67
|
version: '0'
|
63
|
-
none: false
|
64
68
|
requirements: []
|
65
69
|
rubyforge_project:
|
66
70
|
rubygems_version: 1.8.15
|
@@ -70,6 +74,8 @@ summary: The library that will eventually power the web application of the same
|
|
70
74
|
test_files:
|
71
75
|
- test/calculators/test_alcohol.rb
|
72
76
|
- test/calculators/test_calories.rb
|
77
|
+
- test/calculators/test_hops.rb
|
78
|
+
- test/calculators/test_yeast.rb
|
73
79
|
- test/conversions/test_extract.rb
|
74
80
|
- test/conversions/test_mass.rb
|
75
81
|
- test/conversions/test_temperature.rb
|