Last active
January 6, 2022 13:35
-
-
Save yoshida-eth0/c8fede2946dd15c6008a9dc9cf8159d5 to your computer and use it in GitHub Desktop.
ビールの仕込み配合から比重を計算してアルコール度数を予想する
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Ingredient | |
attr_reader :original_gravity | |
# @param original_gravity [Float] 初期比重 | |
# @param suger_content [Float] 糖度 | |
def initialize(original_gravity: nil, suger_content: nil) | |
if original_gravity | |
@original_gravity = original_gravity | |
else | |
@original_gravity = suger_content * SUGER.original_gravity | |
end | |
end | |
WATER = new(original_gravity: 0.0) | |
MOLT_EXTRACT = new(original_gravity: 0.30800000459) | |
SUGER = new(original_gravity: 0.385) | |
end | |
class Wort | |
attr_reader :total | |
attr_reader :gravity | |
attr_reader :fermentation_rate | |
# @param fermentation_rate [Float] 発酵率 | |
def initialize(fermentation_rate=0.75) | |
@total = 0.0 | |
@gravity = 0.0 | |
@fermentation_rate = fermentation_rate | |
end | |
# 原料追加 | |
# | |
# @param weight [Float] 重量(g) | |
# @param ingredient [Ingredient] 原材料 | |
def add(weight, ingredient) | |
@total += weight | |
@gravity += ingredient.original_gravity * weight | |
self | |
end | |
# 比率を保ったまま総容量を変更 | |
# | |
# @param to_total [Float] 変更後総容量 | |
def scale(to_total) | |
to_total = to_total.to_f | |
@gravity = gravity * to_total / total | |
@total = to_total | |
self | |
end | |
# 水を入れて総容量を合わせる | |
# | |
# @param to_total [Float] 変更後総容量 | |
def fit(to_total) | |
diff = to_total - total | |
add(diff, Ingredient::WATER) | |
end | |
# 指定容量を減らして新たなWortオブジェクトを返す | |
# タンクの分割など | |
# | |
# @param subtotal [Float] 取り出す容量 | |
def shift(subtotal) | |
sub = dup.scale(subtotal) | |
remove(subtotal) | |
sub | |
end | |
# 指定容量を減らす | |
# 澱引きや試飲など | |
# | |
# @param subtotal [Float] 取り除く容量 | |
def remove(subtotal) | |
scale(total - subtotal) | |
end | |
# 初期比重 | |
def original_gravity | |
gravity / total + 1 | |
end | |
alias_method :og, :original_gravity | |
# 最終比重 | |
def final_gravity | |
original_gravity - (original_gravity - 1) * fermentation_rate | |
end | |
alias_method :fg, :final_gravity | |
# 予想アルコール度数 | |
def alcohol_by_volume | |
(original_gravity - final_gravity) / 0.738 | |
end | |
alias_method :abv, :alcohol_by_volume | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# モルトエキス1.7Lを用いて10Lのウォートを作る | |
# 1L澱引きする | |
# 70gのプライミングシュガーを120mlのお湯に溶かして追加 | |
# 2.8Lはペールエールとして瓶詰め | |
# 残りはオレンジジュース200mlを足してオレンジエールとして瓶詰め | |
require_relative 'beer' | |
wort = Wort.new | |
.add(1_700, Ingredient::MOLT_EXTRACT) | |
.fit(10_000) | |
.remove(1_000) | |
.add(70, Ingredient::SUGER) | |
.add(120, Ingredient::WATER) | |
pale_ale = wort | |
.shift(2_800) | |
orange_juice = Ingredient.new(suger_content: 0.125) | |
orange_ale = wort | |
.add(200, orange_juice) | |
{"ペールエール": pale_ale, "オレンジエール": orange_ale}.each {|a,b| | |
puts <<~EOF | |
<#{a}> | |
総容量 #{b.total}ml | |
発酵率 #{b.fermentation_rate*100}% | |
初期比重 #{b.original_gravity} | |
最終比重 #{b.final_gravity} | |
予想アルコール度数 #{b.alcohol_by_volume*100}% | |
---------- | |
EOF | |
} | |
__END__ | |
% ruby example.rb | |
<ペールエール> | |
総容量 2800.0ml | |
発酵率 75.0% | |
初期比重 1.0542100116455604 | |
最終比重 1.01355250291139 | |
予想アルコール度数 5.509147524955324% | |
---------- | |
<オレンジエール> | |
総容量 6590.0ml | |
発酵率 75.0% | |
初期比重 1.0540253375440258 | |
最終比重 1.0135063343860065 | |
予想アルコール度数 5.490379831709942% | |
---------- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment