USDA density calculations now more powerful; added ability to parse cubic values

This commit is contained in:
Dan Elbert 2016-03-10 16:06:39 -06:00
parent a9527c9626
commit 238adc4b61
7 changed files with 21 additions and 25 deletions

View File

@ -49,25 +49,7 @@ class Ingredient < ActiveRecord::Base
self.kcal = food.kcal self.kcal = food.kcal
self.fiber = food.fiber self.fiber = food.fiber
self.sugar = food.sugar self.sugar = food.sugar
self.density = calculate_density(food.gram_weight_1, food.gram_weight_desc_1) || calculate_density(food.gram_weight_2, food.gram_weight_desc_2) self.density = food.density_best_guess
end
def calculate_density(grams, description)
return nil if grams.blank? || description.blank?
begin
value_unit = UnitConversion.parse(description)
if value_unit.volume?
density_value = grams.to_d / value_unit.raw_value
density_units = "g/#{value_unit.unit.unit}"
density = UnitConversion.parse(density_value, density_units)
return density.convert('oz/cup').to_s
else
return nil
end
rescue UnitConversion::UnparseableUnitError
return nil
end
end end
end end

View File

@ -14,9 +14,8 @@ class UsdaFood < ActiveRecord::Base
end end
def density_best_guess def density_best_guess
usda_food_weights.each do |w| density = usda_food_weights.map { |w| w.calculate_density }.compact.first
density.nil? ? nil : density.to_s
end
end end
end end

View File

@ -20,4 +20,4 @@ class UsdaFoodWeight < ActiveRecord::Base
end end
end end
end end

View File

@ -15,11 +15,12 @@ module UnitConversion
'[qt_us]': %w(quart quarts qt), '[qt_us]': %w(quart quarts qt),
'[gal_us]': %w(gallon gallons ga), '[gal_us]': %w(gallon gallons ga),
'[foz_us]': %w(foz floz), '[foz_us]': %w(foz floz),
'[in_i]': %w(inch inches in)
} }
METRIC_UNIT_ALIASES = { METRIC_UNIT_ALIASES = {
g: %w(gram grams), g: %w(gram grams),
kg: %w(kilograms kilogram), kg: %w(kilogram kilograms),
ml: %w(milliliter milliliters), ml: %w(milliliter milliliters),
cl: %w(centiliter centiliters), cl: %w(centiliter centiliters),

View File

@ -56,6 +56,9 @@ module UnitConversion
# fluid ounce is the only known unit with a space; fix it up before the following replacement # fluid ounce is the only known unit with a space; fix it up before the following replacement
unit_description = unit_description.gsub(/fl oz/i, 'floz') unit_description = unit_description.gsub(/fl oz/i, 'floz')
# if a cubic unit is found, map it to unit3 (ex 'cubic inches' is converted to 'inches3')
unit_description = unit_description.gsub(/cubic\s+(\w+)/i, '\13')
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
end end

View File

@ -12,7 +12,10 @@ RSpec.describe UnitConversion::ParsedUnit do
'Grams' => 'g', 'Grams' => 'g',
'Tbsp' => '[tbs_us]', 'Tbsp' => '[tbs_us]',
'[tbs_us]' => '[tbs_us]', '[tbs_us]' => '[tbs_us]',
'[oz_av]' => '[oz_av]' '[oz_av]' => '[oz_av]',
'cubic inch' => '[in_i]3',
'in3' => '[in_i]3'
} }
data.each do |input, output| data.each do |input, output|

View File

@ -44,6 +44,14 @@ RSpec.describe UnitConversion::ValueUnit do
it 'Converts parsed objects' do it 'Converts parsed objects' do
check_vu(UnitConversion::ValueUnit.for(UnitConversion::ParsedNumber.new('5'), UnitConversion::ParsedUnit.new('cups')), 5, 'cup') check_vu(UnitConversion::ValueUnit.for(UnitConversion::ParsedNumber.new('5'), UnitConversion::ParsedUnit.new('cups')), 5, 'cup')
end end
it 'converts multi word units' do
check_vu(UnitConversion::ValueUnit.for('2 cubic inches'), 2, 'inch3')
end
it 'understands cubic inches to be volume' do
expect(UnitConversion::ValueUnit.for('2 cubic inches').volume?).to be_truthy
end
end end
end end