Cater Waiter Exercise

I am a newbie, so please forgive the simplicity of the question. In this exercise, I found task 7 description practically incomprehensible. I was unable to begin because I didn’t really understand what we were being asked to do. Can somebody here perhaps state the problem in another way? Which dishes are in the dish parameter? Is the second parameter a list of all the categories or just one? The description is confusing to me. Thanks in advance

Hi @jshames :wave:

This task based only on the instructions is a tad obtuse. It’s meant to have you practice set symmetric difference.

If you take a look at the hints for the exercise and/or the introduction to the concept, things might be a little clearer.

The task is asking you to find unique ingredients across multiple sets. So – not a de-duping of one set (because making a set de-dupes things), but a “sort of” de-duping of ALL (or multiple) sets combined together, where you surface ingredients that only appear once for all recipes.

You can also take a look at the test data and the category data for more details, although you should be warned that both of those files are long and might be hard to read.

The upshot? symmetric difference between two sets can be used to surface items that appear in one set but not both sets.

It can also be used across multiple sets, but has to be applied in a specific pattern or loop.

Let me know if that makes sense - and if you have additional questions or issues. :smile:

1 Like

Just for context, this is the description of task #7 of the “Cater Waiter” exercise.

Within each category (Vegan, Vegetarian, Paleo, Keto, Omnivore), you’re going to pull out ingredients that appear in only one dish. These “singleton” ingredients will be assigned a special shopper to ensure they’re not forgotten in the rush to get everything else done.

Implement the singleton_ingredients(<dishes>, <INTERSECTIONS>) function that takes a list of dishes and a <CATEGORY>_INTERSECTIONS constant for the same category. Each dish is represented by a set of its ingredients. Each <CATEGORY>_INTERSECTIONS is a set of ingredients that appear in more than one dish in the category. Using set operations, your function should return a set of “singleton” ingredients (ingredients appearing in only one dish in the category).

from sets_categories_data import example_dishes, EXAMPLE_INTERSECTION

>>> singleton_ingredients(example_dishes, EXAMPLE_INTERSECTION)
...
{'garlic powder', 'sunflower oil', 'mixed herbs', 'cornstarch', 'celeriac', 'honey', 'mushrooms', 'bell pepper', 'rosemary', 'parsley', 'lemon', 'yeast', 'vegetable oil', 'vegetable stock', 'silken tofu', 'tofu', 'cashews', 'lemon zest', 'smoked tofu', 'spaghetti', 'ginger', 'breadcrumbs', 'tomatoes', 'barley malt', 'red pepper flakes', 'oregano', 'red onion', 'fresh basil'}

Your task is to implement the function singleton_ingredients.

This function takes two arguments:

  • a list of dishes, where each element in this list is a set of ingredients.
  • a set of all ingredients that appear in more than one dish

The functions should return a set of ingredients that appear only in one dish.


For example:

I have a list of dishes:

  • Spicy Omelette (ingredients: eggs, pepper, salt, olive oil, tabasco)
  • Feta Pesto (ingredients: pasta, feta, pignola, basil, olive oil)
  • Spaghetti Cacio e Pepe (ingredients: pasta, olive oil, pepper, salt)

I also have a set of all ingredients that appear in multiple recipes:
pepper, salt, olive oil, pasta

I want to get all ingredients that appear only in a single recipe.
For these three recipes that’s eggs, tabasco, feta, pignola, basil


You can solve this exercise by reusing one of the functions you wrote earlier, and by using a “set operation” as explained in the instructions.

[edit: While I was still typing Bethany gave a much better answer]

1 Like

@siebenschlaefer – I disagree. I think your answer is excellent. Both of us are getting at the same point from different (and valid!) directions. :smile:

1 Like

So, the second parameter is a single list containing the shared ingredients among the dishes in the first parameter. Is that right?

The second parameter <INTERSECTION> is a set, not list, which is why you need to use the symmetric difference set operator. Don’t be fooled by the tuple or the zip() in the tests, or the test data :smile:

Here is the function signature from the stub file:

def singleton_ingredients(dishes, intersection):
    """Determine which `dishes` have a singleton ingredient (an ingredient that only appears once across dishes).

    :param dishes: list - of ingredient sets.
    :param intersection: constant - can be one of `<CATEGORY>_INTERSECTION` constants imported from `sets_categories_data.py`.
    :return: set - containing singleton ingredients.

    Each dish is represented by a `set` of its ingredients.

    Each `<CATEGORY>_INTERSECTION` is an `intersection` of all dishes in the category. `<CATEGORY>` can be any one of:
        (VEGAN, VEGETARIAN, PALEO, KETO, or OMNIVORE).

    The function should return a `set` of ingredients that only appear in a single dish.
    """

So the first parameter is a list of sets. The second is a set representing the intersection of all sets within the first parameter.



As an aside: Because of the size of the data for this exercise, we made a decision to pull test data out into different files and use zip() to reduce clutter. The original tests were effectively breaking the UI and causing readability problems. But abstracting out the data can make it hard to suss out what exactly is going on.

Thank you, I think I understand now. For some reason I was stuck on the language in the description, you helped clarify things for me. The logic of the coding is fairly straightforward.