Meal Planning with Python and Networkx
I enjoy cooking. It can be a good way to wind down after a day of work, and for recipes I know well switch on auto-pilot. But that’s only once I’ve decided what to cook. I don’t enjoy deciding what to cook. Laying out a meal plan, day by day has become a weekly event for my partner and I.
“When do we have gym classes / runs planned?” she might ask. On these days, time may be short, and calorie demand high. “Are you out with work friends on Thursday? Maybe I’ll cook my favourite meal which I know you’re less of a fan of.” “Oh, if we’re having chicken curry on Monday, then we won’t want chicken on Tuesday as well.”
If only I had a tool which could make these decisions for me! Between study deadlines, I spent some time building a solution. Code and data is freely available in github.
My Meal Data
First, I created a spreadsheet of ~20 meals we like to cook. For each meal, the protein and carbohydrate are recorded.
Then, using the python graphing package network, this data is transformed into a graph. Each meal becomes a node, and edges are drawn between nodes only if the meals contain different proteins and carbohydrates.
For example chicken pie is joined neither to creamy chicken pasta (both contain chicken) nor bangers and mash (both contain potato), but is joined to mac and cheese, sausage pasta bake, etc.
Meal Planner Activate
With the graph set up, we’re ready to get meal planning. The input() function is used to interact with the user – the code suggests adjacent nodes (‘legal next meals’) from the graph, but these are only added to the plan following my approval.
Your Shopping List Coming Right Up
Now it’s time to make the shopping list. The code takes the ingredients from the finished meal plan, removes duplicates, and now asks me if I’d like to add some common staples.
Specified items can be removed from the shopping list if already in my kitchen, but otherwise all that’s left to do is email me the plan.
Also in my meal spreadsheet is a list of foods together with the supermarket department they are found in. This allows the list to be ordered based on the order in which the foods will be encountered in the shop. A really simple thing to do (.sort()!) but makes a big difference when we are doing the shopping.
Further development could include integration with my calendar, and distinction between days where leftovers are ideally needed for lunch the following day (Monday to Thursday).
Until next time,
Scott