Back

How to build a random recipe selector with Python

October 26, 2023 12 minute read
A selection of meals under platters
Source: Pexels

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.py
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

costs.py
"""
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

ingredirandom.py
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-16-09-2023.txt
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! 😆