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