public static IngredientBinding Create(Guid ingId, Guid recipeId, Single?qty, Units usageUnit, UnitType convType, Int32 unitWeight, Units formUnit, Single equivAmount, Units equivUnit) { var rawUnit = KitchenPC.Unit.GetDefaultUnitType(convType); if (qty.HasValue && rawUnit != usageUnit) { if (UnitConverter.CanConvert(usageUnit, rawUnit)) { qty = UnitConverter.Convert(qty.Value, usageUnit, rawUnit); } else { var ing = new Ingredient { Id = ingId, ConversionType = convType, UnitWeight = unitWeight }; var form = new IngredientForm { FormUnitType = formUnit, FormAmount = new Amount(equivAmount, equivUnit), IngredientId = ingId }; var usage = new Ingredients.IngredientUsage { Form = form, Ingredient = ing, Amount = new Amount(qty.Value, usageUnit) }; try { var newAmt = FormConversion.GetNativeAmountForUsage(ing, usage); qty = UnitConverter.Convert(newAmt.SizeHigh, newAmt.Unit, rawUnit); //Ingredient graph only stores high amounts } catch (Exception e) { throw new DataLoadException(e); } } } return(new IngredientBinding { RecipeId = recipeId, IngredientId = ingId, Qty = qty.HasValue ? (float?)Math.Round(qty.Value, 3) : null, Unit = rawUnit }); }
private void CategorizeTaste(Recipe recipe, CategorizationResult result) { var totalMass = new Amount(0, Units.Gram); float totalSweet = 0f, totalSpicy = 0f; foreach (var usage in recipe.Ingredients) { if (usage.Amount == null) { continue; } if (usage.Ingredient.Metadata == null) { continue; } var meta = usage.Ingredient.Metadata; var amt = FormConversion.GetWeightForUsage(usage); if (amt == null) { continue; } totalMass += amt; totalSweet += amt.SizeHigh * meta.Sweet; totalSpicy += amt.SizeHigh * meta.Spicy; } if (totalMass.SizeHigh == 0) { return; // Nothing to calc, exit } var maxRating = totalMass.SizeHigh * 4; var recipeSweet = totalSweet / maxRating; // Pct sweet the recipe is var recipeSpicy = totalSpicy / maxRating; // Pct spicy the recipe is result.TasteSavoryToSweet = Convert.ToByte(recipeSweet * 100); // Scale in terms of percentage result.TasteMildToSpicy = Convert.ToByte(recipeSpicy * 100); }
public virtual IngredientAggregation AddUsage(IngredientUsage ingredient) { if (ingredient.Ingredient.Id != this.Ingredient.Id) { throw new ArgumentException("Can only call IngredientAggregation::AddUsage() on original ingredient."); } //Calculate new total if (this.Amount.Unit == ingredient.Amount.Unit || UnitConverter.CanConvert(this.Amount.Unit, ingredient.Amount.Unit)) //Just add { this.Amount += ingredient.Amount; } else //Find a conversion path between Ingredient and Form { var amount = FormConversion.GetNativeAmountForUsage(this.Ingredient, ingredient); this.Amount += amount; } return(this); // Allows AddUsage calls to be chained together }
static void CategorizeTaste(Recipe recipe, CategorizationResult result) { var totalMass = new Amount(0, Units.Gram); float totalSweet = 0f, totalSpicy = 0f; foreach (var usage in recipe.Ingredients) { if (usage.Amount == null) { continue; //No amount specified for this ingredient (TODO: Any way to estimate this?) } if (usage.Ingredient.Metadata == null) { continue; //TODO: Log if ingredient has no metadata } var meta = usage.Ingredient.Metadata; var amt = FormConversion.GetWeightForUsage(usage); if (amt == null) { continue; } totalMass += amt; totalSweet += (amt.SizeHigh * meta.Sweet); totalSpicy += (amt.SizeHigh * meta.Spicy); } if (totalMass.SizeHigh == 0) { return; //Nothing to calc, exit } var maxRating = totalMass.SizeHigh * 4; var recipeSweet = (totalSweet / maxRating); //Pct sweet the recipe is var recipeSpicy = (totalSpicy / maxRating); //Pct spicy the recipe is result.Taste_SavoryToSweet = Convert.ToByte(recipeSweet * 100); //Scale in terms of percentage result.Taste_MildToSpicy = Convert.ToByte(recipeSpicy * 100); }
public Single?Amt; //Optional amount of ingredient, expressed in default units for ingredient public PantryItem(Ingredients.IngredientUsage usage) { IngredientId = usage.Ingredient.Id; //Need to convert IngredientUsage into proper Pantry form if (usage.Amount != null) { var toUnit = Unit.GetDefaultUnitType(usage.Ingredient.ConversionType); if (UnitConverter.CanConvert(usage.Form.FormUnitType, toUnit)) { Amt = UnitConverter.Convert(usage.Amount, toUnit).SizeHigh; //Always take high amount for pantry items } else //Find conversion path { var amount = FormConversion.GetNativeAmountForUsage(usage.Ingredient, usage); Amt = UnitConverter.Convert(amount, toUnit).SizeHigh; //Always take high amount for pantry items } } else { Amt = null; } }
private void CategorizeNutrition(Recipe recipe, CategorizationResult result) { float totalGrams = 0; float totalFat = 0; float totalSugar = 0; float totalCal = 0; float totalSodium = 0; float totalCarbs = 0; var noMatch = false; // First, convert every ingredient to weight foreach (var usage in recipe.Ingredients) { // No amount specified for this ingredient if (usage.Amount == null) { noMatch = true; continue; } var meta = usage.Ingredient.Metadata; if (meta == null) { noMatch = true; continue; } var amount = FormConversion.GetWeightForUsage(usage); if (amount == null) { noMatch = true; continue; // Cannot convert this ingredient to grams, skip it } var grams = amount.SizeHigh; totalGrams += grams; if (!(meta.FatPerUnit.HasValue && meta.SugarPerUnit.HasValue && meta.CaloriesPerUnit.HasValue && meta.SodiumPerUnit.HasValue && meta.CarbsPerUnit.HasValue)) { noMatch = true; } else { totalFat += (meta.FatPerUnit.Value * grams) / 100f; // Total fat per 100g totalSugar += (meta.SugarPerUnit.Value * grams) / 100f; // Total sugar per 100g; totalCal += (meta.CaloriesPerUnit.Value * grams) / 100f; // Total Calories per 100g totalSodium += (meta.SodiumPerUnit.Value * grams) / 100f; // Total sodium per 100g totalCarbs += (meta.CarbsPerUnit.Value * grams) / 100f; // Total carbs per 100g } } result.USDAMatch = !noMatch; // Set to true if every ingredient has an exact USDA match // Set totals result.NutritionTotalFat = (short)totalFat; result.NutritionTotalSugar = (short)totalSugar; result.NutritionTotalCalories = (short)totalCal; result.NutritionTotalSodium = (short)totalSodium; result.NutritionTotalCarbs = (short)totalCarbs; // Flag RecipeMetadata depending on totals in recipe if (!noMatch) { result.NutritionLowFat = totalFat <= (totalCal * 0.03); // Definition of Low Fat is 3g of fat per 100 Cal result.NutritionLowSugar = totalSugar <= (totalCal * 0.02); // There is no FDA definition of "Low Sugar" (Can estimate 2g of sugar per 100 Cal or less) result.NutritionLowCalorie = totalCal <= (totalGrams * 1.2); // Definition of Low Calorie is 120 cal per 100g result.NutritionLowSodium = totalSodium <= (totalGrams * 1.4); // Definition of Low Sodium is 140mg per 100g result.NutritionLowCarb = totalCarbs <= (totalCal * 0.05); // No definition for Low Carb, but we can use 5g per 100 Cal or less } }
public void TestFormConverter() { //Form conversions (Unit ingredients) var unitIng = new Ingredient() { ConversionType = UnitType.Unit, UnitWeight = 200 }; //Ingredient sold by units (unit weighs 200g) var unitIng_UnitForm = new IngredientForm() { FormAmount = new Amount(50, Units.Gram), ConversionMultiplier = 1, FormUnitType = Units.Unit }; //Form expressed in units (unit in this form weighs 50g) var unitIng_WeightForm = new IngredientForm() { ConversionMultiplier = 1, FormUnitType = Units.Ounce }; //Form expressed by weight var unitIng_VolForm = new IngredientForm() { FormUnitType = Units.Cup, ConversionMultiplier = 1, FormAmount = new Amount(20, Units.Gram) }; //Each cup weighs 20g) var unitIng_UnitUsage = new IngredientUsage() { Amount = new Amount(4, Units.Unit), Form = unitIng_UnitForm, Ingredient = unitIng }; var unitIng_WeightUsage = new IngredientUsage() { Amount = new Amount(300, Units.Gram), Form = unitIng_WeightForm, Ingredient = unitIng }; var unitIng_VolUsage = new IngredientUsage() { Amount = new Amount(160, Units.Tablespoon), Form = unitIng_VolForm, Ingredient = unitIng }; //10 cups var unitIng_UnitAmt = FormConversion.GetNativeAmountForUsage(unitIng, unitIng_UnitUsage); var unitIng_WeightAmt = FormConversion.GetNativeAmountForUsage(unitIng, unitIng_WeightUsage); var unitIng_VolAmt = FormConversion.GetNativeAmountForUsage(unitIng, unitIng_VolUsage); Assert.AreEqual(1.0f, unitIng_UnitAmt.SizeHigh); //4 units in this form should convert to 1 unit of ingredient Assert.AreEqual(Units.Unit, unitIng_UnitAmt.Unit); Assert.AreEqual(2.0f, unitIng_WeightAmt.SizeHigh); //300g of this form should convert to 1.5 units of ingredient, however we round up to whole units Assert.AreEqual(Units.Unit, unitIng_WeightAmt.Unit); //TODO: Fix //Assert.AreEqual(1.0f, unitIng_VolAmt.SizeHigh); //10 cups of this form should convert to 1 unit of ingredient //Assert.AreEqual(Units.Unit, unitIng_VolAmt.Unit); //Form conversions (Volume ingredients) var volIng = new Ingredient() { ConversionType = UnitType.Volume }; //Ingredient sold by volume var volIng_UnitForm = new IngredientForm() { FormUnitType = Units.Unit, ConversionMultiplier = 1, FormAmount = new Amount(5, Units.Teaspoon) }; var volIng_WeightForm = new IngredientForm() { FormUnitType = Units.Ounce, ConversionMultiplier = 1, FormAmount = new Amount(2, Units.Teaspoon) }; var volIng_UnitUsage = new IngredientUsage() { Amount = new Amount(2, Units.Unit), Form = volIng_UnitForm, Ingredient = volIng }; var volIng_WeightUsage = new IngredientUsage() { Amount = new Amount(0.25f, Units.Pound), Form = volIng_WeightForm, Ingredient = volIng }; //4oz var volIng_UnitAmt = FormConversion.GetNativeAmountForUsage(volIng, volIng_UnitUsage); var volIng_WeightAmt = FormConversion.GetNativeAmountForUsage(volIng, volIng_WeightUsage); Assert.AreEqual(10.0f, volIng_UnitAmt.SizeHigh); Assert.AreEqual(Units.Teaspoon, volIng_UnitAmt.Unit); Assert.AreEqual(8.0f, volIng_WeightAmt.SizeHigh); Assert.AreEqual(Units.Teaspoon, volIng_WeightAmt.Unit); //Form conversions (Weight ingredients) var weightIng = new Ingredient() { ConversionType = UnitType.Weight }; //Ingredient sold by weight var weightIng_UnitForm = new IngredientForm() { ConversionMultiplier = 1, FormUnitType = Units.Unit, FormAmount = new Amount(100, Units.Gram) }; var weightIng_VolForm = new IngredientForm() { ConversionMultiplier = 1, FormUnitType = Units.Cup, FormAmount = new Amount(50, Units.Gram) }; var weightIng_UnitUsage = new IngredientUsage() { Amount = new Amount(5, Units.Unit), Form = weightIng_UnitForm, Ingredient = weightIng }; var weightIng_VolUsage = new IngredientUsage() { Amount = new Amount(144, Units.Teaspoon), Form = weightIng_VolForm, Ingredient = weightIng }; //3 cups var weightIng_UnitAmt = FormConversion.GetNativeAmountForUsage(weightIng, weightIng_UnitUsage); var weightIng_VolAmt = FormConversion.GetNativeAmountForUsage(weightIng, weightIng_VolUsage); Assert.AreEqual(500.0f, weightIng_UnitAmt.SizeHigh); Assert.AreEqual(Units.Gram, weightIng_UnitAmt.Unit); Assert.AreEqual(150.0f, weightIng_VolAmt.SizeHigh); Assert.AreEqual(Units.Gram, weightIng_VolAmt.Unit); }