Script in Javascript to automate meal planning in order to hit daily calories and protein.
Last active
December 8, 2020 04:35
-
-
Save vasco3/81a782437f1790638610d815cf1743a0 to your computer and use it in GitHub Desktop.
Meal Planner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = [ | |
{ | |
_key: 'MEXICAN_TACOS', | |
_id: 'recipes/MEXICAN_TACOS', | |
_rev: '_XTqNHIW--_', | |
name: 'MEXICAN TACOS', | |
Calories: 150, | |
Fat: 5, | |
Carbs: 1, | |
Protein: 23, | |
type: 'Meal', | |
servings: 4, | |
}, | |
{ | |
_key: 'CHOCOLATE_CHIP_FROZEN_YOGURT_ICE_CREAM', | |
_id: 'recipes/CHOCOLATE_CHIP_FROZEN_YOGURT_ICE_CREAM', | |
_rev: '_XTqNfbK--_', | |
name: 'CHOCOLATE CHIP FROZEN YOGURT ICE CREAM', | |
Calories: 519, | |
Protein: 10, | |
Carbs: 86, | |
Fat: 17, | |
type: 'Snack', | |
servings: 1, | |
}, | |
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { List } = require('immutable'); | |
const data = require('./data'); | |
// find the combinations of recipes that amount total calories and protein requirements | |
const BODY_WEIGHT_LBS = 180; | |
const TOTAL_CALORIES = 3200; | |
const CALORIES_LOWER_BOUND = TOTAL_CALORIES - 50; | |
const CALORIES_UPPER_BOUND = TOTAL_CALORIES + 50; | |
const PROTEIN_UPPER_BOUND = 1 * BODY_WEIGHT_LBS; | |
function calculateDayMenu({ | |
menu = List([]), | |
recipes = List([]), | |
recipeIndex = 0, | |
calories = 0, | |
protein = 0, | |
}) { | |
const shouldExit = recipeIndex >= recipes.size; | |
if (shouldExit) { | |
const shouldRestart = calories < CALORIES_LOWER_BOUND; | |
if (shouldRestart) { | |
return calculateDayMenu({ | |
recipes: List(data.sort(randomSort)), | |
}); | |
} | |
return { menu, calories, protein }; | |
} | |
const recipe = recipes.get(recipeIndex) || {}; | |
const caloriesCounted = calories + recipe.Calories; | |
const proteinCounted = protein + recipe.Protein; | |
const remainingServings = recipe.servings - 1; | |
const shouldSkipRecipe = | |
caloriesCounted > CALORIES_UPPER_BOUND || | |
proteinCounted > PROTEIN_UPPER_BOUND || | |
recipe.servings === 0; | |
if (shouldSkipRecipe) { | |
return calculateDayMenu({ | |
menu, | |
recipes, | |
recipeIndex: recipeIndex + 1, | |
calories, | |
protein, | |
}); | |
} | |
const newMenuItem = `${recipe.Calories}cal | protein ${recipe.Protein}g | ${ | |
recipe.name | |
} | ${recipe.type}`; | |
const recipeUpdated = { ...recipe, servings: remainingServings }; | |
return calculateDayMenu({ | |
menu: menu.push(newMenuItem), | |
recipes: recipes.update(recipeIndex, () => recipeUpdated), | |
recipeIndex, | |
calories: caloriesCounted, | |
protein: proteinCounted, | |
}); | |
} | |
function randomSort() { | |
if (Math.random() > 0.5) return 1; | |
if (Math.random() > 0.5) return -1; | |
return 0; | |
} | |
const dayMenu = calculateDayMenu({ | |
recipes: List(data.sort(randomSort)), | |
}); | |
console.log(JSON.stringify(dayMenu, null, 4)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment