Added usda food data

This commit is contained in:
Dan Elbert 2016-01-24 17:10:43 -06:00
parent f434900291
commit 9f04a65e19
10 changed files with 8999 additions and 4 deletions

View File

@ -3,4 +3,29 @@ class Ingredient < ActiveRecord::Base
validates :name, presence: true
validates :density, density: true, allow_blank: true
def set_usda_food(food)
self.ndbn = food.ndbn
self.density = calculate_density(food.gram_weight_1, food.gram_weight_desc_1) || calculate_density(food.gram_weight_2, food.gram_weight_desc_2)
end
def calculate_density(grams, description)
return nil if grams.blank? || description.blank?
# replace 'fl oz' with 'floz'
description = description.gsub(/fl oz/i, 'floz')
begin
unit = UnitConversion.parse(description)
if UnitConversion.volume?(unit)
mass = Unitwise(grams, 'g')
density = (mass / unit).convert_to(UnitConversion.normalize_unit_names('oz/cup'))
return "#{density.value.round(4)} oz/cup"
else
return nil
end
rescue UnitConversion::UnparseableUnitError
return nil
end
end
end

View File

@ -15,6 +15,7 @@ module UnitConversion
'[pt_us]': %w(pint pints),
'[qt_us]': %w(quart quarts qt),
'[gal_us]': %w(gallon gallons ga),
'[foz_us]': %w(foz floz),
g: %w(gram grams),
kg: %w(kilograms kilogram),

3
app/models/usda_food.rb Normal file
View File

@ -0,0 +1,3 @@
class UsdaFood < ActiveRecord::Base
end

View File

@ -0,0 +1,25 @@
class CreateUsdaFood < ActiveRecord::Migration
def change
create_table :usda_foods do |t|
t.string :ndbn, limit: 5, index: true, null: false
t.string :short_description
t.decimal :water, precision: 10, scale: 2
t.integer :kcal
t.decimal :protein, precision: 10, scale: 2
t.decimal :lipid, precision: 10, scale: 2
t.decimal :ash, precision: 10, scale: 2
t.decimal :carbohydrates, precision: 10, scale: 2
t.decimal :fiber, precision: 10, scale: 1
t.decimal :sugar, precision: 10, scale: 2
t.decimal :gram_weight_1, precision: 9, scale: 2
t.decimal :gram_weight_2, precision: 9, scale: 2
t.string :gram_weight_desc_1
t.string :gram_weight_desc_2
t.integer :refuse_percent
t.timestamps null: false
end
end
end

View File

@ -0,0 +1,8 @@
class AddNdbnToIngredients < ActiveRecord::Migration
def change
change_table :ingredients do |t|
t.string :ndbn, limit: 5, index: true
end
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160119212055) do
ActiveRecord::Schema.define(version: 20160124222409) do
create_table "ingredients", force: :cascade do |t|
t.string "name"
@ -19,6 +19,7 @@ ActiveRecord::Schema.define(version: 20160119212055) do
t.text "notes"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "ndbn", limit: 5
end
create_table "recipe_ingredients", force: :cascade do |t|
@ -58,6 +59,28 @@ ActiveRecord::Schema.define(version: 20160119212055) do
t.integer "user_id"
end
create_table "usda_foods", force: :cascade do |t|
t.string "ndbn", limit: 5, null: false
t.string "short_description"
t.decimal "water", precision: 10, scale: 2
t.integer "kcal"
t.decimal "protein", precision: 10, scale: 2
t.decimal "lipid", precision: 10, scale: 2
t.decimal "ash", precision: 10, scale: 2
t.decimal "carbohydrates", precision: 10, scale: 2
t.decimal "fiber", precision: 10, scale: 1
t.decimal "sugar", precision: 10, scale: 2
t.decimal "gram_weight_1", precision: 9, scale: 2
t.decimal "gram_weight_2", precision: 9, scale: 2
t.string "gram_weight_desc_1"
t.string "gram_weight_desc_2"
t.integer "refuse_percent"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "usda_foods", ["ndbn"], name: "index_usda_foods_on_ndbn"
create_table "users", force: :cascade do |t|
t.string "username"
t.string "email"

View File

@ -6,12 +6,13 @@
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first)
require 'usda_importer'
puts "Seeding..."
Ingredient.create!([
{name: 'Water', density: '1 g/ml'},
{name: 'Butter, Salted', density: '226 gram/cup'},
{name: 'Butter, Salted', density: '226 gram/cup', ndbn: '01001'},
{name: 'Butter, Unsalted', density: '226 gram/cup'},
{name: 'Flour, Bleached All Purpose', density: '130 gram/cup'},
{name: 'Flour, Cake', density: '120 gram/cup'},
@ -30,6 +31,8 @@ Ingredient.create!([
{name: 'Milk, 2%', density: '1.03 gram/ml'}
])
importer = UsdaImporter.new(Rails.root.join('vendor', 'data', 'usda', 'ABBREV.txt'))
importer.import
puts "Seeds planted."

118
lib/usda_importer.rb Normal file
View File

@ -0,0 +1,118 @@
require 'csv'
class UsdaImporter
COLUMNS = [
'NDB_No',
'Shrt_Desc',
'Water',
'Energ_Kcal',
'Protein',
'Lipid_Tot',
'Ash',
'Carbohydrt',
'Fiber_TD',
'Sugar_Tot',
'Calcium',
'Iron',
'Magnesium',
'Phosphorus',
'Potassium',
'Sodium',
'Zinc',
'Copper',
'Manganese',
'Selenium',
'Vit_C',
'Thiamin',
'Riboflavin',
'Niacin',
'Panto_acid',
'Vit_B6',
'Folate_Tot',
'Folic_acid',
'Food_Folate',
'Folate_DFE',
'Choline_Tot',
'Vit_B12',
'Vit_A_IU',
'Vit_A_RAE',
'Retinol',
'Alpha_Carot',
'Beta_Carot',
'Beta_Crypt',
'Lycopene',
'Lut+Zea',
'Vit_E',
'Vit_D_mcg',
'Vit_D_IU',
'Vit_K',
'FA_Sat',
'FA_Mono',
'FA_Poly',
'Cholestrl',
'GmWt_1',
'GmWt_Desc1',
'GmWt_2',
'GmWt_Desc2',
'Refuse_Pct'
]
COLUMN_MAP = {
ndbn: 'NDB_No',
short_description: 'Shrt_Desc',
water: 'Water',
kcal: 'Energ_Kcal',
protein: 'Protein',
lipid: 'Lipid_Tot',
ash: 'Ash',
carbohydrates: 'Carbohydrt',
fiber: 'Fiber_TD',
sugar: 'Sugar_Tot',
gram_weight_1: 'GmWt_1',
gram_weight_2: 'GmWt_2',
gram_weight_desc_1: 'GmWt_Desc1',
gram_weight_desc_2: 'GmWt_Desc2',
refuse_percent: 'Refuse_Pct'
}
def initialize(file)
@file = file
end
def import
UsdaFood.delete_all
CSV.open(@file, 'r:iso-8859-1:utf-8', csv_options) do |csv|
csv.each_slice(500) do |slice|
UsdaFood.transaction do
attributes = slice.map do |row|
Hash[COLUMN_MAP.map { |db, col| [db, row[col]] }]
end
UsdaFood.create(attributes)
end
end
end
usda_items = Hash[UsdaFood.where(ndbn: Ingredient.select(:ndbn)).map { |uf| [uf.ndbn, uf] }]
Ingredient.where('ndbn IS NOT NULL').each do |i|
item = usda_items[i.ndbn]
if item
i.set_usda_food(item)
i.save
end
end
end
def csv_options
{ col_sep: '^', quote_char: '~', headers: COLUMNS }
end
end

8789
vendor/data/usda/ABBREV.txt vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
vendor/data/usda/sr28_doc.pdf vendored Normal file

Binary file not shown.