Skip to content

Commit 0550647

Browse files
authored
Merge pull request #218 from ikostan/exercism-sync/d6c11a3123753a9d
[Sync Iteration] python/cater-waiter/2
2 parents ad16761 + 3211e54 commit 0550647

File tree

1 file changed

+149
-0
lines changed
  • solutions/python/cater-waiter/2

1 file changed

+149
-0
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
"""Functions for compiling dishes and ingredients for a catering company."""
2+
from typing import List, Set
3+
4+
from sets_categories_data import (
5+
VEGAN,
6+
VEGETARIAN,
7+
KETO,
8+
PALEO,
9+
OMNIVORE,
10+
ALCOHOLS,
11+
SPECIAL_INGREDIENTS,
12+
)
13+
14+
15+
def clean_ingredients(dish_name: str, dish_ingredients: list) -> tuple:
16+
"""
17+
Remove duplicates from `dish_ingredients`.
18+
19+
:param dish_name: str - containing the dish name.
20+
:param dish_ingredients: list - dish ingredients.
21+
:return: tuple - containing (dish_name, ingredient set).
22+
23+
This function should return a `tuple` with the name of the dish as
24+
the first item, followed by the de-duped `set` of ingredients as
25+
the second item.
26+
"""
27+
28+
return dish_name, set(dish_ingredients)
29+
30+
31+
def check_drinks(drink_name: str, drink_ingredients: list) -> str:
32+
"""
33+
Append "Cocktail" (alcohol) or "Mocktail" (no alcohol) to `drink_name`,
34+
based on `drink_ingredients`.
35+
36+
:param drink_name: str - name of the drink.
37+
:param drink_ingredients: list - ingredients in the drink.
38+
:return: str - drink_name appended with "Mocktail" or "Cocktail".
39+
40+
The function should return the name of the drink followed by "Mocktail"
41+
(non-alcoholic) and drink name followed by "Cocktail" (includes alcohol).
42+
43+
"""
44+
if ALCOHOLS.intersection(set(drink_ingredients)):
45+
return f"{drink_name} Cocktail"
46+
return f"{drink_name} Mocktail"
47+
48+
49+
def categorize_dish(dish_name: str, dish_ingredients: set) -> str:
50+
"""
51+
Categorize `dish_name` based on `dish_ingredients`.
52+
53+
:param dish_name: str - dish to be categorized.
54+
:param dish_ingredients: set - ingredients for the dish.
55+
:return: str - the dish name appended with ": <CATEGORY>".
56+
57+
This function should return a string with the `dish name: <CATEGORY>
58+
(which meal category the dish belongs to).
59+
`<CATEGORY>` can be any one of (VEGAN, VEGETARIAN, PALEO, KETO, or OMNIVORE).
60+
All dishes will "fit" into one of the categories imported from `sets_categories_data.py`
61+
"""
62+
63+
categories = [
64+
(ALCOHOLS, "ALCOHOLS"),
65+
(VEGETARIAN, "VEGETARIAN"),
66+
(KETO, "KETO"),
67+
(PALEO, "PALEO"),
68+
(OMNIVORE, "OMNIVORE"),
69+
(VEGAN, "VEGAN"),
70+
(SPECIAL_INGREDIENTS, "SPECIAL_INGREDIENTS"),
71+
]
72+
73+
for category_set, category_name in categories:
74+
if dish_ingredients.issubset(category_set):
75+
return f"{dish_name}: {category_name}"
76+
77+
78+
def tag_special_ingredients(dish: tuple) -> tuple:
79+
"""
80+
Compare `dish` ingredients to `SPECIAL_INGREDIENTS`.
81+
82+
:param dish: tuple - of (dish name, list of dish ingredients).
83+
:return: tuple - containing (dish name, dish special ingredients).
84+
85+
Return the dish name followed by the `set` of ingredients that require
86+
a special note on the dish description. For the purposes of this exercise,
87+
all allergens or special ingredients that need to be tracked are in the
88+
SPECIAL_INGREDIENTS constant imported from `sets_categories_data.py`.
89+
"""
90+
91+
return dish[0], SPECIAL_INGREDIENTS.intersection(set(dish[1]))
92+
93+
94+
def compile_ingredients(dishes: list) -> set:
95+
"""
96+
Create a master list of ingredients.
97+
98+
:param dishes: list - of dish ingredient sets.
99+
:return: set - of ingredients compiled from `dishes`.
100+
101+
This function should return a `set` of all ingredients from all listed dishes.
102+
"""
103+
104+
all_ingredients = set()
105+
106+
for dish in dishes:
107+
all_ingredients = all_ingredients.union(dish)
108+
109+
return all_ingredients
110+
111+
112+
def separate_appetizers(dishes: list, appetizers: list) -> list:
113+
"""
114+
Determine which `dishes` are designated `appetizers` and remove them.
115+
116+
:param dishes: list - of dish names.
117+
:param appetizers: list - of appetizer names.
118+
:return: list - of dish names that do not appear on appetizer list.
119+
120+
The function should return the list of dish names with appetizer names removed.
121+
Either list could contain duplicates and may require de-duping.
122+
"""
123+
124+
return list(set(dishes).difference(appetizers))
125+
126+
127+
def singleton_ingredients(dishes: List[Set[str]], intersection) -> set:
128+
"""
129+
Determine which `dishes` have a singleton ingredient (an ingredient that
130+
only appears once across dishes).
131+
132+
:param dishes: list - of ingredient sets.
133+
:param intersection: constant - can be one of `<CATEGORY>_INTERSECTIONS`
134+
constants imported from `sets_categories_data.py`.
135+
:return: set - containing singleton ingredients.
136+
137+
Each dish is represented by a `set` of its ingredients.
138+
139+
Each `<CATEGORY>_INTERSECTIONS` is an `intersection` of all dishes in the
140+
category. `<CATEGORY>` can be any one of:
141+
(VEGAN, VEGETARIAN, PALEO, KETO, or OMNIVORE).
142+
143+
The function should return a `set` of ingredients that only appear in a single dish.
144+
"""
145+
146+
singletons: set = set()
147+
for dish in dishes:
148+
singletons = singletons.union(dish.difference(intersection))
149+
return singletons

0 commit comments

Comments
 (0)