From e06f9cf25c64734c511dc693a500123e89d541f9 Mon Sep 17 00:00:00 2001 From: Alessio Date: Sun, 10 Nov 2024 13:07:27 -0800 Subject: [PATCH] Add function to compute an equivalent food from a recipe --- pkg/db/ingredient.go | 6 +++++ pkg/db/ingredient_test.go | 1 + pkg/db/recipe.go | 46 +++++++++++++++++++++++++++++++++++ pkg/db/recipe_test.go | 50 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) diff --git a/pkg/db/ingredient.go b/pkg/db/ingredient.go index 769c276..354c0ba 100644 --- a/pkg/db/ingredient.go +++ b/pkg/db/ingredient.go @@ -18,6 +18,8 @@ type Ingredient struct { InRecipeID RecipeID `db:"in_recipe_id"` ListOrder int64 `db:"list_order"` IsHidden bool `db:"is_hidden"` + + Food *Food } // // Format as string @@ -85,3 +87,7 @@ func (db *DB) DeleteIngredient(i Ingredient) { panic(fmt.Errorf("tried to delete ingredient with ID (%d) but it doesn't exist", i.ID)) } } + +func (i Ingredient) Quantity() float32 { + return float32(i.QuantityNumerator) / float32(i.QuantityDenominator) +} diff --git a/pkg/db/ingredient_test.go b/pkg/db/ingredient_test.go index a14edbb..682fec7 100644 --- a/pkg/db/ingredient_test.go +++ b/pkg/db/ingredient_test.go @@ -35,6 +35,7 @@ func TestSaveAndLoadIngredient(t *testing.T) { // Create an ingredient on the recipe ingr := Ingredient{ FoodID: food.ID, + Food: &food, QuantityNumerator: 3, QuantityDenominator: 2, Units: 1, // count diff --git a/pkg/db/recipe.go b/pkg/db/recipe.go index ebea6cb..2b91f67 100644 --- a/pkg/db/recipe.go +++ b/pkg/db/recipe.go @@ -94,5 +94,51 @@ func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) { where in_recipe_id = ? order by list_order asc `, id) + if err != nil { + panic(err) + } + for i := range ret.Ingredients { + var food Food + if ret.Ingredients[i].FoodID != FoodID(0) { + // ingredient is a food + food, err = db.GetFoodByID(ret.Ingredients[i].FoodID) + ret.Ingredients[i].Food = &food + } else { + // ingredient is a food; i.Food is the ComputedFood of the Recipe + var computed_food_id FoodID + err = db.DB.Get(&computed_food_id, `select computed_food_id from recipes where rowid = ?`, ret.Ingredients[i].RecipeID) + if err != nil { + panic(err) + } + food, err = db.GetFoodByID(computed_food_id) + ret.Ingredients[i].Food = &food + } + if err != nil { + panic(err) + } + } return } + +func (r Recipe) ComputeFood() Food { + ret := Food{} + for _, ingr := range r.Ingredients { + ret.Cals += ingr.Quantity() * ingr.Food.Cals + ret.Carbs += ingr.Quantity() * ingr.Food.Carbs + ret.Protein += ingr.Quantity() * ingr.Food.Protein + ret.Fat += ingr.Quantity() * ingr.Food.Fat + ret.Sugar += ingr.Quantity() * ingr.Food.Sugar + ret.Alcohol += ingr.Quantity() * ingr.Food.Alcohol + ret.Water += ingr.Quantity() * ingr.Food.Water + ret.Potassium += ingr.Quantity() * ingr.Food.Potassium + ret.Calcium += ingr.Quantity() * ingr.Food.Calcium + ret.Sodium += ingr.Quantity() * ingr.Food.Sodium + ret.Magnesium += ingr.Quantity() * ingr.Food.Magnesium + ret.Phosphorus += ingr.Quantity() * ingr.Food.Phosphorus + ret.Iron += ingr.Quantity() * ingr.Food.Iron + ret.Zinc += ingr.Quantity() * ingr.Food.Zinc + ret.Mass += ingr.Quantity() * ingr.Food.Mass + ret.Price += ingr.Quantity() * ingr.Food.Price + } + return ret +} diff --git a/pkg/db/recipe_test.go b/pkg/db/recipe_test.go index ed17cd0..cc33ca8 100644 --- a/pkg/db/recipe_test.go +++ b/pkg/db/recipe_test.go @@ -42,3 +42,53 @@ func TestRecipeSaveAndLoad(t *testing.T) { t.Error(diff) } } + +func TestRecipeComputeFood(t *testing.T) { + assert := assert.New(t) + f1 := Food{0, "", 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 0, 0} + f2 := Food{0, "", 16.5, 15.5, 14.5, 13.5, 12.5, 11.5, 10.5, 9.5, 8.5, 7.5, 6.5, 5.5, 4.5, 3.5, 2.5, 1.5, 0, 0} + + recipe := Recipe{Ingredients: []Ingredient{ + {QuantityNumerator: 1, QuantityDenominator: 1, Food: &f1}, + {QuantityNumerator: 1, QuantityDenominator: 1, Food: &f2}, + }} + computed_food := recipe.ComputeFood() + assert.Equal(computed_food.Cals, float32(17.5)) + assert.Equal(computed_food.Carbs, float32(17.5)) + assert.Equal(computed_food.Protein, float32(17.5)) + assert.Equal(computed_food.Fat, float32(17.5)) + assert.Equal(computed_food.Sugar, float32(17.5)) + assert.Equal(computed_food.Alcohol, float32(17.5)) + assert.Equal(computed_food.Water, float32(17.5)) + assert.Equal(computed_food.Potassium, float32(17.5)) + assert.Equal(computed_food.Calcium, float32(17.5)) + assert.Equal(computed_food.Sodium, float32(17.5)) + assert.Equal(computed_food.Magnesium, float32(17.5)) + assert.Equal(computed_food.Phosphorus, float32(17.5)) + assert.Equal(computed_food.Iron, float32(17.5)) + assert.Equal(computed_food.Zinc, float32(17.5)) + assert.Equal(computed_food.Mass, float32(17.5)) + assert.Equal(computed_food.Price, float32(17.5)) + + recipe2 := Recipe{Ingredients: []Ingredient{ + {QuantityNumerator: 3, QuantityDenominator: 2, Food: &f1}, + {QuantityNumerator: 1, QuantityDenominator: 2, Food: &f2}, + }} + computed_food2 := recipe2.ComputeFood() + assert.Equal(computed_food2.Cals, float32(9.75)) + assert.Equal(computed_food2.Carbs, float32(10.75)) + assert.Equal(computed_food2.Protein, float32(11.75)) + assert.Equal(computed_food2.Fat, float32(12.75)) + assert.Equal(computed_food2.Sugar, float32(13.75)) + assert.Equal(computed_food2.Alcohol, float32(14.75)) + assert.Equal(computed_food2.Water, float32(15.75)) + assert.Equal(computed_food2.Potassium, float32(16.75)) + assert.Equal(computed_food2.Calcium, float32(17.75)) + assert.Equal(computed_food2.Sodium, float32(18.75)) + assert.Equal(computed_food2.Magnesium, float32(19.75)) + assert.Equal(computed_food2.Phosphorus, float32(20.75)) + assert.Equal(computed_food2.Iron, float32(21.75)) + assert.Equal(computed_food2.Zinc, float32(22.75)) + assert.Equal(computed_food2.Mass, float32(23.75)) + assert.Equal(computed_food2.Price, float32(24.75)) +}