How to build a random recipe selector with Python
Introduction
For a while I've wanted to try and mimic the setup of HelloFresh, whereby you:
- have a list of meals you like to cook and eat
- want to choose a random a number of recipes for the following week
- then want a shopping list for the ingredients for those recipes
Although I have never tried HelloFresh I've heard from others it's great for simplicity - you only get the ingredients you need for the recipe and it's mostly healthy stuff. Nevertheless, the principles inspired my own solution. I wanted to sharpen up my cooking skills, learn new recipes, and automate the stressful decision and procurement part of the process.
This is where ingredirandom steps in to help, it:
- defines a list of
recipes
dictionaries from various cook books I use - defines a list of
costs
as a tuple with product codes from online shopping at ASDA - a script
ingredirandom
which randomly selects a given number of those recipes, and outputs the shopping list to a text file
The following code blocks contain each of these steps, so please enjoy having a read through 😄
Create a list of recipes
recipes = [
{
"name": "Beefy Mince and Pasta Bake",
"book": "Enter cookbook name here",
"page": 38,
"serves": "2-3",
"ingredients": [
"Tin of Campbell's condensed Tomato soup",
"500g beef mince",
"Beef or vegetable stock cubes",
"Grated cheese",
"Garlic cloves",
"Onion",
"Butter",
"Pasta",
"Freeze dried basil",
"Salt",
"Pepper"
]
},
{
"name": "Hoisin Chicken Noodles",
"book": "Enter cookbook name here",
"page": 59,
"serves": "2",
"ingredients": [
"Spring onions",
"Fresh ginger",
"Garlic cloves",
"Chicken breasts",
"Mushrooms",
"Chicken stock",
"Soy sauce",
"Hoisin sauce",
"Can of sweetcorn",
"Fresh egg noodles",
"Olive oil"
]
},
{
"name": "Pan Roast Chicken Breast with mustard sauce",
"book": "Enter cookbook name here",
"page": 64,
"serves": "Enter cookbook name here",
"ingredients": [
"Cherry tomatoes",
"Lettuce",
"Cucumber",
"Chicken breasts",
"Potato wedges or new potatoes",
"Olive oil",
"Balsamic vinegar",
"Sugar",
"Salt",
"Pepper",
"Mustard sauce",
"Prosecco"
]
},
{
"name": "Chicken and Mushroom Pasta with 'Philly' cheese and fresh basil",
"book": "Enter cookbook name here",
"page": 68,
"serves": "2",
"ingredients": [
"500g tagliatelle",
"Onion",
"Garlic cloves",
"Chicken breasts",
"Mushrooms",
"200g Philadelphia soft cheese",
"Fresh basil",
"Salt",
"Pepper",
"Parmesan",
"Olive oil"
]
},
{
"name": "Thai Salmon with coconut rice and green chilli dressing",
"book": "Enter cookbook name here",
"page": 200,
"serves": "2-3",
"ingredients": [
"Olive oil",
"Thai red curry paste",
"Spring onions",
"400g can coconut milk",
"Fresh coriander leaves",
"Lemon",
"Rice",
"Salmon steaks",
"Hoisin sauce",
"Sugar",
"Green chilli"
]
},
{
"name": "Pan Roasted Chicken with spicy fried rice",
"book": "Enter cookbook name here",
"page": 154,
"serves": "2-3",
"ingredients": [
"Basmati rice",
"Chicken breasts",
"Eggs",
"Onion",
"Garlic cloves",
"Red pepper",
"Fresh ginger",
"Red chilli",
"Oyster sauce",
"Soy sauce",
"Spring onions"
]
},
{
"name": "Tuna Noodles with honey and ginger dressing",
"book": "Enter cookbook name here",
"page": 153,
"serves": "2-3",
"ingredients": [
"Honey",
"Soy sauce",
"White wine vinegar",
"Red chilli",
"Fresh ginger",
"Salt",
"Pepper",
"Spring onions",
"Cucumber",
"Red pepper",
"Can of tuna",
"Fresh egg noodles"
]
},
{
"name": "Zesty Tuna Steaks with chilli tagliatelle",
"book": "Enter cookbook name here",
"page": 87,
"serves": "2-3",
"ingredients": [
"500g tagliatelle",
"Olive oil",
"Spring onions",
"Red chilli",
"Tuna steaks",
"Black olives",
"Fresh thyme",
"Olive Oil",
"Sugar",
"Lime",
"Salt",
"Pepper"
]
},
{
"name": "Spaghetti Carbonara with Parmesan",
"book": "Enter cookbook name here",
"page": 80,
"serves": "2-3",
"ingredients": [
"500g pack spaghetti",
"Onion",
"Garlic cloves",
"200g pack pancetta lardons or strips of streaky bacon",
"Olive oil",
"Eggs",
"Parmesan",
"Fresh basil",
"Red wine"
]
},
{
"name": "Chorizo Spaghetti with balsamic and basil sauce",
"book": "Enter cookbook name here",
"page": 79,
"serves": "2-3",
"ingredients": [
"500g pack spaghetti",
"Onion",
"Garlic cloves",
"Red pepper",
"Chorizo sausages",
"Tomatoes",
"Olives",
"Fresh basil",
"Olive oil",
"Balsamic vinegar",
"Red wine vinegar",
"Sugar"
]
},
{
"name": "Italian Meatballs with spaghetti",
"book": "Enter cookbook name here",
"page": 175,
"serves": "2-3",
"ingredients": [
"Olive oil",
"Onion",
"Garlic cloves",
"400g tin tomatoes",
"Tomato puree",
"Brown sugar",
"Red wine vinegar",
"Fresh basil",
"Salt",
"Pepper",
"500g beef mince",
"Onion",
"Red wine"
]
},
{
"name": "Beef Chow Mein with oyster sauce",
"book": "Enter cookbook name here",
"page": 72,
"serves": "2-3",
"ingredients": [
"Fresh ginger",
"Garlic cloves",
"Tomato puree",
"Oyster sauce",
"Soy sauce",
"Onion",
"Red pepper",
"Rump steak",
"Bean sprouts",
"Fresh egg noodles",
"Olive oil"
]
},
{
"name": "Crispy Fried Duck Breast with ginger dressing and fried rice",
"book": "Enter cookbook name here",
"page": 180,
"serves": "2",
"ingredients": [
"Basmati rice",
"Carrots",
"Courgette",
"Duck breasts",
"Eggs",
"Spring onions",
"Olive oil",
"Fresh ginger",
"Lime",
"Soy sauce",
"Honey"
]
},
{
"name": "Irish Lamb Stew with colcannon",
"book": "Enter cookbook name here",
"page": 184,
"serves": "4",
"ingredients": [
"Olive oil",
"Onion",
"Garlic cloves",
"Stewing or diced lamb",
"Carrots",
"Flour",
"Vegetable stock cube",
"Apricot jam",
"Red wine",
"Rosemary",
"Mushrooms",
"Potatoes",
"Butter",
"250g pack of spring greens or savoy cabbage (optional)",
"300ml pot of soured cream (optional)"
]
},
{
"name": "Beef Steak with balsamic onion and peppercorn sauce",
"book": "Enter cookbook name here",
"page": 171,
"serves": "2",
"ingredients": [
"Peppercorn sauce",
"Onion",
"Olive oil",
"Onion",
"Balsamic vinegar",
"Brown sugar",
"Potatoes",
"Butter",
"Salt",
"Pepper",
"Rump steak"
]
},
{
"name": "Sweet Honey Chicken with risotto rice",
"book": "Enter cookbook name here",
"page": 187,
"serves": "2",
"ingredients": [
"Soy sauce",
"Fresh ginger",
"Honey",
"Dried chives",
"Chicken breasts",
"Butter",
"Garlic cloves",
"Yellow pepper",
"Basmati rice",
"Chicken stock",
"Mushrooms",
"Spring onions",
"Courgette"
]
},
{
"name": "Sweet and Sour Chicken Noodles",
"book": "Enter cookbook name here",
"page": 196,
"serves": "2",
"ingredients": [
"Soy sauce",
"Spring onions",
"Red pepper",
"Garlic cloves",
"Chicken breasts",
"Fresh egg noodles",
"Olive oil",
"Tomato puree",
"Honey",
"White wine vinegar",
"Fresh ginger"
]
},
{
"name": "Corned Beef Hash with fried eggs",
"book": "Enter cookbook name here",
"page": 141,
"serves": "2",
"ingredients": [
"Potatoes",
"Onion",
"Corned beef",
"Eggs",
"Olive oil",
"Salt",
"Pepper"
]
},
{
"name": "Shiitake Mushroom Risotto with Parmesan",
"book": "Enter cookbook name here",
"page": 149,
"serves": "2",
"ingredients": [
"Butter",
"Onion",
"Garlic cloves",
"Risotto rice",
"Vegetable stock cube",
"Shiitake mushrooms",
"Salt",
"Pepper",
"Fresh basil",
"Parmesan"
]
},
{
"name": "Traditional Pork Steaks with honey and mustard sauce",
"book": "Enter cookbook name here",
"page": 76,
"serves": "2",
"ingredients": [
"Potato wedges or new potatoes",
"Carrots",
"Pork steaks",
"Green beans",
"Onion",
"Fresh ginger",
"Cumin",
"Cinnamon",
"Flour",
"Honey",
"Wholegrain mustard",
"Salt",
"Pepper",
"Olive oil"
]
},
{
"name": "Thai Prawn Curry with rice",
"book": "Enter cookbook name here",
"page": 83,
"serves": "2",
"ingredients": [
"Rice",
"Pilau rice seasoning",
"Prawns",
"Olive oil",
"Thai red curry paste",
"400g can coconut milk",
"Mangetout",
"Baby sweetcorn",
"Spring onions"
]
},
{
"name": "Crispy Parmesan Cod with fresh tomato sauce and mini roasts",
"book": "Enter cookbook name here",
"page": 84,
"serves": "2",
"ingredients": [
"Olive oil",
"Tomato and basil sauce",
"Pepper",
"Fresh basil",
"Breadcrumbs",
"Parmesan",
"Lemon",
"Potatoes",
"Cod",
"Eggs"
]
},
{
"name": "Easy Cooked Breakfast",
"book": "Enter cookbook name here",
"page": 100,
"serves": "2",
"ingredients": [
"Hash browns",
"Salt",
"Pepper",
"Sausages",
"Streaky bacon",
"Tomatoes",
"Eggs",
"Bread",
"Olive oil",
"Orange juice"
]
},
{
"name": "Chicken Biryani with Naan bread",
"book": "Enter cookbook name here",
"page": 199,
"serves": "2",
"ingredients": [
"Butter",
"Onion",
"Chicken thighs",
"Korma curry paste",
"Rice",
"Chicken stock",
"Yoghurt",
"Raisins"
"Fresh coriander leaves",
"Flaked almonds",
"Naan bread"
]
},
{
"name": "Pork with apple and pear chutney",
"book": "Enter cookbook name here",
"page": 75,
"serves": "2",
"ingredients": [
"Apple and pear chutney",
"Pilau rice seasoning",
"Rice",
"Mangetout",
"Pork steaks"
]
},
{
"name": "Zesty Cod with rice",
"book": "Enter cookbook name here",
"page": 96,
"serves": "2",
"ingredients": [
"Rice",
"Pilau rice seasoning",
"Cod fillets",
"Eggs",
"Onion",
"Mushrooms",
"Lemon",
"Freeze dried basil"
]
}
]
Record ingredients and costs
"""
A record of costs per ingredient.
Key is ingredient name, value is tuple (cost of item, ASDA product code)
Last updated: September 2023
"""
cost_lookup = {
"Tin of Campbell's condensed Tomato soup": (1.30, "5498495"),
"500g beef mince": (3.70, "1525219"),
"Beef or vegetable stock cubes": (3.10, "4052433"),
"Grated cheese": (2.55, "4639365"),
"Garlic cloves": (2.00, "6599892"),
"Onion": (1.00, "5737702"),
"Butter": (3.25, "6858100"),
"Pasta": (0.95, "6125466"),
"Freeze dried basil": (0.80, "544353"),
"Salt": (0.80, "4938721"),
"Pepper": (0.90, "1352762"),
"Spring onions": (0.75, "410212"),
"Fresh ginger": (0.60, "6668284"),
"Chicken breasts": (4.70, "7648521"),
"Mushrooms": (1.29, "4110717"),
"Chicken stock": (0.75, "2687967"),
"Soy sauce": (1.90, "6124290"),
"Hoisin sauce": (1.80, "6124274"),
"Can of sweetcorn": (0.65, "5986511"),
"Fresh egg noodles": (1.50, "5128622"),
"500g tagliatelle": (2.00, "2207092"),
"Olive oil": (5.90, "6722819"),
"Red chilli": (0.55, "4928242"),
"Tuna steaks": (5.00, "7740432"),
"Black olives": (1.15, "951664"),
"Fresh thyme": (0.55, "5139830"),
"Sugar": (0.89, "217367"),
"Lime": (1.00, "5596923"),
"500g pack spaghetti": (0.75, "12943"),
"200g pack pancetta lardons or strips of streaky bacon": (2.25, "6345750"),
"Eggs": (2.95, "166781"),
"Parmesan": (1.85, "3160573"),
"Fresh basil": (0.55, "6753736"),
"Red wine": (8.50, "1701819"),
"Red pepper": (0.55, "1857059"),
"Chorizo sausages": (2.70, "3567277"),
"Tomatoes": (1.25, "5794643"),
"Olives": (2.00, "6697522"),
"Balsamic vinegar": (1.30, "1554788"),
"Red wine vinegar": (4.50, "7681719"),
"400g tin tomatoes": (1.25, "7675447"),
"Tomato puree": (1.40, "7675461"),
"Brown sugar": (1.35, "6345327"),
"Oyster sauce": (1.75, "6124294"),
"Rump steak": (6.20, "7357125"),
"Bean sprouts": (0.50, "6536231"),
"Basmati rice": (2.20, "18631"),
"Carrots": (0.50, "150208"),
"Courgette": (0.75, "6566770"),
"Duck breasts": (6.00, "7443861"),
"Honey": (1.47, "5506364"),
"Stewing or diced lamb": (4.95, "6740100"),
"Flour": (0.80, "11120"),
"Vegetable stock cube": (0.75, "2687969"),
"Apricot jam": (1.15, "6722853"),
"Rosemary": (0.55, "5148466"),
"Potatoes": (1.70, "1843017"),
"250g pack of spring greens or savoy cabbage (optional)": (0.75, "150460"),
"300ml pot of soured cream (optional)": (1.00, "5673649"),
"Thai red curry paste": (2.30, "7563362"),
"400g can coconut milk": (2.00, "7679943"),
"Fresh coriander leaves": (2.00, "18695"),
"Lemon": (0.55, "5797459"),
"Rice": (2.70, "18802"),
"Salmon steaks": (5.50, "6349272"),
"Green chilli": (0.50, "1208242"),
"Cucumber": (0.79, "152446"),
"Can of tuna": (4.00, "6041045"),
"White wine vinegar": (1.30, "2569207"),
"200g Philadelphia soft cheese": (2.20, "7345715"),
"Potato wedges or new potatoes": (1.50, "6311576/6141368"),
"Peppercorn sauce": (1.20, "6923656"),
"Dried chives": (0.80, "544339"),
"Yellow pepper": (0.55, "1857071"),
"Corned beef": (2.30, "2594051"),
"Risotto rice": (2.40, "6125968"),
"Shiitake mushrooms": (1.60, "4708261"),
"Pork steaks": (3.60, "7452907"),
"Green beans": (0.93, "7132612"),
"Cumin": (0.80, "544313"),
"Cinnamon": (0.80, "6684574"),
"Wholegrain mustard": (2.65, "3667611"),
"Pilau rice seasoning": (2.00, "59161"),
"Prawns": (2.80, "6305703"),
"Baby sweetcorn": (1.35, "6523635"),
"Mangetout": (0.85, "5795246"),
"Tomato and basil sauce": (1.15, "7458116"),
"Breadcrumbs": (1.00, "5496030"),
"Cod": (5.00, "6088572"),
"Hash browns": (2.00, "3843261"),
"Sausages": (3.50, "7600840"),
"Streaky bacon": (2.25, "6345750"),
"Bread": (1.30, "2160171"),
"Orange juice": (1.15, "656042"),
"Chicken thighs": (4.95, "6923652"),
"Korma curry paste": (2.10, "5904835"),
"Saffron": (2.45, "5615948"),
"Yoghurt": (1.00, "3425334"),
"Raisins": (1.50, "4960067"),
"Flaked almonds": (1.50, "4960109"),
"Naan bread": (0.75, "5215599"),
"Apple and pear chutney": (1.95, "6210082"),
"Cod fillets": (4.75, "6246480"),
"Curry paste": (2.10, "5017664")
}
Select random recipes
import random
import datetime
from recipes import recipes
from costs import cost_lookup
def get_random_selections():
k = int(input("Number of recipes to randomly choose?: "))
selections = random.sample(recipes, k=k)
return selections
def output_to_text_file(selections):
now = datetime.datetime.now()
file_path = "shopping-list-" + now.strftime("%d-%m-%Y") + ".txt"
with open(file_path, "w") as file:
file.write("Shopping list for ")
file.write(now.strftime("%B %d, %Y\n\n"))
file.write("* = Ingredient is in multiple recipes\n\n")
total_week_cost = 0
all_ingredients = set()
for i, recipe in enumerate(selections):
if (i > 0):
file.write("\n\n")
total_recipe_cost = 0
file.write(f"Recipe {i + 1}\n")
file.write("____________________________\n")
file.write(f"{recipe['name']}\n")
file.write(f"{recipe['book']} - Page {recipe['page']}\n\n")
for ingredient in recipe['ingredients']:
if ingredient in cost_lookup:
ingredient_cost = float(cost_lookup[ingredient][0])
ingredient_product_id = cost_lookup[ingredient][1]
file.write(
'{:70s} {:20s} {:20s}'.format(
ingredient + "*" if ingredient in all_ingredients else ingredient,
"\u00a3" + str(ingredient_cost),
str(ingredient_product_id))
)
file.write("\n")
total_recipe_cost += ingredient_cost
else:
file.write(
ingredient + "*" if ingredient in all_ingredients else ingredient)
file.write("\n")
all_ingredients.add(ingredient)
file.write(f"\nEstimated recipe cost: \u00a3{round(total_recipe_cost, 2)}\n")
total_week_cost += total_recipe_cost
file.write(f"\n\nEstimated week cost: \u00a3{round(total_week_cost, 2)}")
print("Selections saved to shopping-list.txt", end="\n")
print("Happy cooking :)")
if __name__ == "__main__":
print("Welcome to IngrediRandom!", end="\n")
print(f"There are {len(recipes)} recipes in total.")
selections = get_random_selections()
output_to_text_file(selections)
You run python ingredirandom.py
, enter the number of random recipes you want selecting and the recipes, ingredients and costs are output to a text file shopping-list.txt
.
In the text file below we can see the output of the program, our random meals, the page number of the recipe book for the instructions along with a shopping list with the ingredients required and their costs.
Remember the below list shows the total cost, that is if you were starting with nothing and had to buy everything. That's not to say you don't already have most of the ingredients or can find them cheaper elsewhere. These are just suggestions, groceries are becoming increasingly expensive so always shop around and adapt the program! That's just the way I decided to build this program, so I always know the cost of the core ingredients but remembering that the expensive one off items like olive oil or butter will bring that cost upwards.
Shopping list for September 16, 2023
* = Ingredient is in multiple recipes
Recipe 1
____________________________
Crispy Fried Duck Breast with ginger dressing and fried rice
Your cookbook name - Page 180
Basmati rice £2.2 18631
Carrots £0.5 150208
Courgette £0.75 6566770
Duck breasts £6.0 7443861
Eggs £2.95 166781
Spring onions £0.75 410212
Olive oil £5.9 6722819
Fresh ginger £0.6 6668284
Lime £1.0 5596923
Soy sauce £1.9 6124290
Honey £1.47 5506364
Estimated recipe cost: £24.02
Recipe 2
____________________________
Beef Steak with balsamic onion and peppercorn sauce
Your cookbook name - Page 171
Peppercorn sauce £1.2 6923656
Onion £1.0 5737702
Olive oil* £5.9 6722819
Onion* £1.0 5737702
Balsamic vinegar £1.3 1554788
Brown sugar £1.35 6345327
Potatoes £1.7 1843017
Butter £3.25 6858100
Salt £0.8 4938721
Pepper £0.9 1352762
Rump steak £6.2 7357125
Estimated recipe cost: £24.6
Recipe 3
____________________________
Hoisin Chicken Noodles
Your cookbook name - Page 59
Spring onions* £0.75 410212
Fresh ginger* £0.6 6668284
Garlic cloves £2.0 6599892
Chicken breasts £4.7 7648521
Mushrooms £1.29 4110717
Chicken stock £0.75 2687967
Soy sauce* £1.9 6124290
Hoisin sauce £1.8 6124274
Can of sweetcorn £0.65 5986511
Fresh egg noodles £1.5 5128622
Olive oil* £5.9 6722819
Estimated recipe cost: £21.84
Estimated week cost: £70.46
Adapting to your needs
You can add, remove or modify recipe entries from recipes.py
.
You can also update the costs in costs.py
for each ingredient. If you order online this should be easy to do as you do it, or find the cost from your receipt.
I haven't added actual recipes to avoid copyright issues, however I will say my main cook books are HelloFresh Recipes That Work, Nosh for Students and Nosh for Graduates - yes these are simple but effective books I am no expert so simple is good for me.
I entered my favourite recipes from these books into the recipes.py
lookup and entered the costs from online grocery shopping at ASDA into costs.py
lookup. Voila!
I could also almost fully automate this process by turning the cost and recipe lookups into JSON files, storing them in GitHub, then having an AWS Lambda function read them and run ingredirandom.py, then send an email to me with the recipes for the week. I might explore this in a future article.
Bon appetit
This program works really well at mixing things up and enjoying learning new recipes. You can also adapt this code to fulfil any other random selection use case you may have.
The major benefit is you can add more recipes you enjoy and remove the ones that you don't want to try again.
It keeps your cooking skills sharp and I hope you find like me, eases the stressful procurement part of cooking. This leaves you to gather everything you need upfront and then just enjoy the process of preparing, cooking and eating good clean fresh food at least a few times per week! 😆