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
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.
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 alist
of dishes and a<CATEGORY>_INTERSECTIONS
constant for the same category. Each dish is represented by aset
of its ingredients. Each<CATEGORY>_INTERSECTIONS
is aset
of ingredients that appear in more than one dish in the category. Using set operations, your function should return aset
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 aset
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]
@siebenschlaefer – I disagree. I think your answer is excellent. Both of us are getting at the same point from different (and valid!) directions.
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
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.