Skip to content

Instantly share code, notes, and snippets.

@jshuadvd
Forked from vasco3/data.js
Created August 22, 2018 02:28
Show Gist options
  • Save jshuadvd/e312f3e152ad9df271cd4fc532776a42 to your computer and use it in GitHub Desktop.
Save jshuadvd/e312f3e152ad9df271cd4fc532776a42 to your computer and use it in GitHub Desktop.
Meal Planner

Meal Planner

Script in Javascript to automate meal planning in order to hit daily calories and protein.

module.exports = [
{
_key: 'MEXICAN_BURGERS',
_id: 'recipes/MEXICAN_BURGERS',
_rev: '_XTqNHIW--_',
name: 'MEXICAN BURGERS',
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,
},
{
_key: 'BROILED_OMELET',
_id: 'recipes/BROILED_OMELET',
_rev: '_XTqN2pe--_',
name: 'BROILED OMELET',
Calories: 668,
Protein: 92,
Carbs: 4,
Fat: 31,
type: 'Meal',
servings: 1,
},
{
_key: 'CRISPY_CHICKEN_BITES',
_id: 'recipes/CRISPY_CHICKEN_BITES',
_rev: '_XTqOIhK--_',
name: 'CRISPY CHICKEN BITES',
Calories: 510,
Protein: 75,
Carbs: 0,
Fat: 4,
type: 'Meal',
servings: 1,
},
{
_key: 'MONTREAL_STYLE_SIRLOIN_ROAST',
_id: 'recipes/MONTREAL_STYLE_SIRLOIN_ROAST',
_rev: '_XTqOVK2--_',
name: 'MONTREAL STYLE SIRLOIN ROAST',
Calories: 632,
Protein: 103,
Carbs: 0,
Fat: 21,
type: 'Meal',
servings: 1,
},
{
_key: 'EMILYS_RUSSET_POTATO_WEDGES',
_id: 'recipes/EMILYS_RUSSET_POTATO_WEDGES',
_rev: '_XTqOtN---_',
name: 'EMILY’S RUSSET POTATO WEDGES',
Calories: 170,
Fat: 7,
Carbs: 26,
Protein: 3,
type: 'Side',
servings: 2,
},
{
_key: 'CHEESE_QUESADILLAS',
_id: 'recipes/CHEESE_QUESADILLAS',
_rev: '_XTqPAP6--_',
name: 'CHEESE QUESADILLAS',
Calories: 448,
Protein: 26,
Carbs: 37,
Fat: 22,
type: 'Side',
servings: 1,
},
{
_key: 'SALMON_WITH_DILL',
_id: 'recipes/SALMON_WITH_DILL',
_rev: '_XTqPPWe--_',
name: 'SALMON WITH DILL',
Calories: 160,
Fat: 8,
Carbs: 0,
Protein: 23,
type: 'Meal',
servings: 4,
},
{
_key: 'CHICKEN_ENCHILADA_BAKE',
_id: 'recipes/CHICKEN_ENCHILADA_BAKE',
_rev: '_XTqPmXu--_',
name: 'CHICKEN ENCHILADA BAKE',
Calories: 310,
Fat: 8,
Carbs: 29,
Protein: 34,
type: 'Meal',
servings: 8,
},
{
_key: 'CRISPY_FLANK_STEAK',
_id: 'recipes/CRISPY_FLANK_STEAK',
_rev: '_XTqP7GK--_',
name: 'CRISPY FLANK STEAK',
Calories: 715,
Protein: 96,
Carbs: 0,
Fat: 33,
type: 'Meal',
servings: 1,
},
{
_key: 'PATSY_POTATOES',
_id: 'recipes/PATSY_POTATOES',
_rev: '_XTqQQIG--_',
name: 'PATSY POTATOES',
Calories: 590,
Protein: 11,
Carbs: 90,
Fat: 23,
type: 'Side',
servings: 1,
},
{
_key: 'GREGS_RUSSET_POTATO_WEDGES',
_id: 'recipes/GREGS_RUSSET_POTATO_WEDGES',
_rev: '_XTqQhru--_',
name: 'GREG’S RUSSET POTATO WEDGES',
Calories: 512,
Protein: 11,
Carbs: 90,
Fat: 14,
type: 'Side',
servings: 1,
},
];
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