Unit conversion
This commit is contained in:
parent
faf1d20f17
commit
5f955564fb
@ -48,6 +48,20 @@ module UnitConversion
|
|||||||
unit.compatible_with? Unitwise(1, 'g/ml')
|
unit.compatible_with? Unitwise(1, 'g/ml')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def volume?(unit)
|
||||||
|
unit.compatible_with? Unitwise(1, 'ml')
|
||||||
|
end
|
||||||
|
|
||||||
|
def mass?(unit)
|
||||||
|
unit.compatible_with? Unitwise(1, 'g')
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_density(str)
|
||||||
|
unit = parse(str)
|
||||||
|
raise UnknownUnitError, "#{str} expected to be a density" unless density?(unit)
|
||||||
|
unit
|
||||||
|
end
|
||||||
|
|
||||||
def normalize_unit_names(unit_description)
|
def normalize_unit_names(unit_description)
|
||||||
unit_description.downcase.gsub(/[a-z]+/) do |match|
|
unit_description.downcase.gsub(/[a-z]+/) do |match|
|
||||||
UNIT_ALIAS_MAP[match] || match
|
UNIT_ALIAS_MAP[match] || match
|
||||||
@ -71,7 +85,7 @@ module UnitConversion
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def convert(quantity, factor, input_unit, output_unit)
|
def convert(quantity, factor, input_unit, output_unit, density = nil)
|
||||||
|
|
||||||
value = get_value(quantity)
|
value = get_value(quantity)
|
||||||
factor = get_value(factor)
|
factor = get_value(factor)
|
||||||
@ -80,23 +94,36 @@ module UnitConversion
|
|||||||
factor = factor.to_d(10)
|
factor = factor.to_d(10)
|
||||||
end
|
end
|
||||||
|
|
||||||
input_unit = normalize_unit_names(input_unit)
|
converted = value * factor
|
||||||
output_unit = normalize_unit_names(output_unit)
|
|
||||||
|
|
||||||
original = Unitwise(value, input_unit)
|
input_unit = normalize_unit_names(input_unit) unless input_unit.nil?
|
||||||
scaled = original * factor
|
output_unit = normalize_unit_names(output_unit) unless output_unit.nil?
|
||||||
|
|
||||||
converted = scaled.convert_to output_unit
|
if input_unit && output_unit && input_unit != output_unit
|
||||||
|
in_unit = Unitwise(1, input_unit)
|
||||||
|
out_unit = Unitwise(1, output_unit)
|
||||||
|
unit = Unitwise(converted, input_unit)
|
||||||
|
|
||||||
|
if volume?(in_unit) && mass?(out_unit)
|
||||||
|
unit_density = get_density(density)
|
||||||
|
unit = unit * unit_density
|
||||||
|
elsif mass?(in_unit) && volume?(out_unit)
|
||||||
|
unit_density = get_density(density)
|
||||||
|
unit = unit / unit_density
|
||||||
|
end
|
||||||
|
|
||||||
|
converted = unit.convert_to(output_unit).value
|
||||||
|
end
|
||||||
|
|
||||||
if value.is_a? Rational
|
if value.is_a? Rational
|
||||||
rational_val = converted.value.to_r.rationalize(0.001)
|
rational_val = converted.to_r.rationalize(0.001)
|
||||||
if rational_val.denominator == 1
|
if rational_val.denominator == 1
|
||||||
rational_val.to_i.to_s
|
rational_val.to_i.to_s
|
||||||
else
|
else
|
||||||
rational_val.to_s
|
rational_val.to_s
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
"%g" % ("%.3f" % converted.value)
|
"%g" % ("%.3f" % converted)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,11 +40,24 @@ RSpec.describe UnitConversion do
|
|||||||
expect(UnitConversion.convert('2.0', '1', 'tablespoon', 'cup')).to eq '0.125'
|
expect(UnitConversion.convert('2.0', '1', 'tablespoon', 'cup')).to eq '0.125'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'scales odd units without conversion' do
|
||||||
|
expect(UnitConversion.convert('1/2', '2', 'slices', 'slices')).to eq '1'
|
||||||
|
expect(UnitConversion.convert('4', '1/8', nil, nil)).to eq '1/2'
|
||||||
|
end
|
||||||
|
|
||||||
it 'converts and scales' do
|
it 'converts and scales' do
|
||||||
expect(UnitConversion.convert('1/2', '2', 'cup', 'tbsp')).to eq '16'
|
expect(UnitConversion.convert('1/2', '2', 'cup', 'tbsp')).to eq '16'
|
||||||
expect(UnitConversion.convert('2.0', '1 1/2', 'tablespoon', 'cup')).to eq '0.188'
|
expect(UnitConversion.convert('2.0', '1 1/2', 'tablespoon', 'cup')).to eq '0.188'
|
||||||
expect(UnitConversion.convert('2', '1 1/2', 'tablespoon', 'cup')).to eq '3/16'
|
expect(UnitConversion.convert('2', '1 1/2', 'tablespoon', 'cup')).to eq '3/16'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'converts from volume to mass' do
|
||||||
|
expect(UnitConversion.convert('5', '1', 'cup', 'ounce', '5 oz/c')).to eq '25'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'converts from mass to volume' do
|
||||||
|
expect(UnitConversion.convert('25', '1', 'ounce', 'cup', '5 oz/c')).to eq '5'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.parse' do
|
describe '.parse' do
|
||||||
|
Loading…
Reference in New Issue
Block a user