Level 1 Recipe CRUD
Build RecipeManager, an in-memory store of recipes. Each recipe has an id, a display name and a list of ingredient strings.
Recipe names are unique ignoring case: "Pancakes" and "PANCAKES" can't both exist. Keep the name exactly as it was given, though; only comparisons ignore case.
add_recipe(recipe_id, name, ingredients) -> bool: store a new recipe.False(and nothing changes) if the id is already used or another recipe already has that name (ignoring case).get_recipe(recipe_id) -> dict | None:{"id": ..., "name": ..., "ingredients": [...]}for the recipe, orNoneif there's no such recipe.update_recipe(recipe_id, name, ingredients) -> bool: replace the name and ingredients.Falseif the recipe doesn't exist or the new name belongs to a different recipe. A recipe may keep its own name (in any casing).delete_recipe(recipe_id) -> bool:Falseif there's no such recipe. A deleted recipe's id and name become free again.
The store must not share list objects with callers: changing a list you passed in, or one you got back, must not change the stored recipe.
m = RecipeManager()
m.add_recipe("7", "Tomato Soup", ["tomato", "salt"]) # True
m.add_recipe("8", "tomato soup", ["tomato"]) # False: name taken
m.update_recipe("7", "TOMATO SOUP", ["tomato"]) # True: its own name
m.get_recipe("7") # {"id": "7", "name": "TOMATO SOUP", "ingredients": ["tomato"]}
m.delete_recipe("7") # True
m.add_recipe("8", "tomato soup", ["tomato"]) # True now
Aim for O(1) name checks; the store may hold tens of thousands of recipes.