diff --git a/solutions/python/cater-waiter/2/sets.py b/solutions/python/cater-waiter/2/sets.py new file mode 100644 index 0000000..0b5a6e7 --- /dev/null +++ b/solutions/python/cater-waiter/2/sets.py @@ -0,0 +1,149 @@ +"""Functions for compiling dishes and ingredients for a catering company.""" +from typing import List, Set + +from sets_categories_data import ( + VEGAN, + VEGETARIAN, + KETO, + PALEO, + OMNIVORE, + ALCOHOLS, + SPECIAL_INGREDIENTS, +) + + +def clean_ingredients(dish_name: str, dish_ingredients: list) -> tuple: + """ + Remove duplicates from `dish_ingredients`. + + :param dish_name: str - containing the dish name. + :param dish_ingredients: list - dish ingredients. + :return: tuple - containing (dish_name, ingredient set). + + This function should return a `tuple` with the name of the dish as + the first item, followed by the de-duped `set` of ingredients as + the second item. + """ + + return dish_name, set(dish_ingredients) + + +def check_drinks(drink_name: str, drink_ingredients: list) -> str: + """ + Append "Cocktail" (alcohol) or "Mocktail" (no alcohol) to `drink_name`, + based on `drink_ingredients`. + + :param drink_name: str - name of the drink. + :param drink_ingredients: list - ingredients in the drink. + :return: str - drink_name appended with "Mocktail" or "Cocktail". + + The function should return the name of the drink followed by "Mocktail" + (non-alcoholic) and drink name followed by "Cocktail" (includes alcohol). + + """ + if ALCOHOLS.intersection(set(drink_ingredients)): + return f"{drink_name} Cocktail" + return f"{drink_name} Mocktail" + + +def categorize_dish(dish_name: str, dish_ingredients: set) -> str: + """ + Categorize `dish_name` based on `dish_ingredients`. + + :param dish_name: str - dish to be categorized. + :param dish_ingredients: set - ingredients for the dish. + :return: str - the dish name appended with ": ". + + This function should return a string with the `dish name: + (which meal category the dish belongs to). + `` can be any one of (VEGAN, VEGETARIAN, PALEO, KETO, or OMNIVORE). + All dishes will "fit" into one of the categories imported from `sets_categories_data.py` + """ + + categories = [ + (ALCOHOLS, "ALCOHOLS"), + (VEGETARIAN, "VEGETARIAN"), + (KETO, "KETO"), + (PALEO, "PALEO"), + (OMNIVORE, "OMNIVORE"), + (VEGAN, "VEGAN"), + (SPECIAL_INGREDIENTS, "SPECIAL_INGREDIENTS"), + ] + + for category_set, category_name in categories: + if dish_ingredients.issubset(category_set): + return f"{dish_name}: {category_name}" + + +def tag_special_ingredients(dish: tuple) -> tuple: + """ + Compare `dish` ingredients to `SPECIAL_INGREDIENTS`. + + :param dish: tuple - of (dish name, list of dish ingredients). + :return: tuple - containing (dish name, dish special ingredients). + + Return the dish name followed by the `set` of ingredients that require + a special note on the dish description. For the purposes of this exercise, + all allergens or special ingredients that need to be tracked are in the + SPECIAL_INGREDIENTS constant imported from `sets_categories_data.py`. + """ + + return dish[0], SPECIAL_INGREDIENTS.intersection(set(dish[1])) + + +def compile_ingredients(dishes: list) -> set: + """ + Create a master list of ingredients. + + :param dishes: list - of dish ingredient sets. + :return: set - of ingredients compiled from `dishes`. + + This function should return a `set` of all ingredients from all listed dishes. + """ + + all_ingredients = set() + + for dish in dishes: + all_ingredients = all_ingredients.union(dish) + + return all_ingredients + + +def separate_appetizers(dishes: list, appetizers: list) -> list: + """ + Determine which `dishes` are designated `appetizers` and remove them. + + :param dishes: list - of dish names. + :param appetizers: list - of appetizer names. + :return: list - of dish names that do not appear on appetizer list. + + The function should return the list of dish names with appetizer names removed. + Either list could contain duplicates and may require de-duping. + """ + + return list(set(dishes).difference(appetizers)) + + +def singleton_ingredients(dishes: List[Set[str]], intersection) -> set: + """ + 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 `_INTERSECTIONS` + constants imported from `sets_categories_data.py`. + :return: set - containing singleton ingredients. + + Each dish is represented by a `set` of its ingredients. + + Each `_INTERSECTIONS` is an `intersection` of all dishes in the + 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. + """ + + singletons: set = set() + for dish in dishes: + singletons = singletons.union(dish.difference(intersection)) + return singletons diff --git a/solutions/python/cater-waiter/3/sets.py b/solutions/python/cater-waiter/3/sets.py new file mode 100644 index 0000000..aa3e961 --- /dev/null +++ b/solutions/python/cater-waiter/3/sets.py @@ -0,0 +1,154 @@ +"""Functions for compiling dishes and ingredients for a catering company.""" +from typing import List, Set + +from sets_categories_data import ( + VEGAN, + VEGETARIAN, + KETO, + PALEO, + OMNIVORE, + ALCOHOLS, + SPECIAL_INGREDIENTS, +) + + +def clean_ingredients(dish_name: str, dish_ingredients: list) -> tuple: + """ + Remove duplicates from `dish_ingredients`. + + :param dish_name: str - containing the dish name. + :param dish_ingredients: list - dish ingredients. + :return: tuple - containing (dish_name, ingredient set). + + This function should return a `tuple` with the name of the dish as + the first item, followed by the de-duped `set` of ingredients as + the second item. + """ + + return dish_name, set(dish_ingredients) + + +def check_drinks(drink_name: str, drink_ingredients: list) -> str: + """ + Append "Cocktail" (alcohol) or "Mocktail" (no alcohol) to `drink_name`, + based on `drink_ingredients`. + + :param drink_name: str - name of the drink. + :param drink_ingredients: list - ingredients in the drink. + :return: str - drink_name appended with "Mocktail" or "Cocktail". + + The function should return the name of the drink followed by "Mocktail" + (non-alcoholic) and drink name followed by "Cocktail" (includes alcohol). + + """ + if ALCOHOLS.intersection(set(drink_ingredients)): + return f"{drink_name} Cocktail" + return f"{drink_name} Mocktail" + + +def categorize_dish(dish_name: str, dish_ingredients: set) -> str: + """ + Categorize `dish_name` based on `dish_ingredients`. + + :param dish_name: str - dish to be categorized. + :param dish_ingredients: set - ingredients for the dish. + :return: str - the dish name appended with ": ". + + This function should return a string with the `dish name: + (which meal category the dish belongs to). + `` can be any one of (VEGAN, VEGETARIAN, PALEO, KETO, or OMNIVORE). + All dishes will "fit" into one of the categories imported from `sets_categories_data.py` + """ + + categories = [ + (ALCOHOLS, "ALCOHOLS"), + (VEGETARIAN, "VEGETARIAN"), + (KETO, "KETO"), + (PALEO, "PALEO"), + (OMNIVORE, "OMNIVORE"), + (VEGAN, "VEGAN"), + (SPECIAL_INGREDIENTS, "SPECIAL_INGREDIENTS"), + ] + + result: str = '' + + for category_set, category_name in categories: + if dish_ingredients.issubset(category_set): + result = f"{dish_name}: {category_name}" + break + + return result + + +def tag_special_ingredients(dish: tuple) -> tuple: + """ + Compare `dish` ingredients to `SPECIAL_INGREDIENTS`. + + :param dish: tuple - of (dish name, list of dish ingredients). + :return: tuple - containing (dish name, dish special ingredients). + + Return the dish name followed by the `set` of ingredients that require + a special note on the dish description. For the purposes of this exercise, + all allergens or special ingredients that need to be tracked are in the + SPECIAL_INGREDIENTS constant imported from `sets_categories_data.py`. + """ + + return dish[0], SPECIAL_INGREDIENTS.intersection(set(dish[1])) + + +def compile_ingredients(dishes: list) -> set: + """ + Create a master list of ingredients. + + :param dishes: list - of dish ingredient sets. + :return: set - of ingredients compiled from `dishes`. + + This function should return a `set` of all ingredients from all listed dishes. + """ + + all_ingredients = set() + + for dish in dishes: + all_ingredients = all_ingredients.union(dish) + + return all_ingredients + + +def separate_appetizers(dishes: list, appetizers: list) -> list: + """ + Determine which `dishes` are designated `appetizers` and remove them. + + :param dishes: list - of dish names. + :param appetizers: list - of appetizer names. + :return: list - of dish names that do not appear on appetizer list. + + The function should return the list of dish names with appetizer names removed. + Either list could contain duplicates and may require de-duping. + """ + + return list(set(dishes).difference(appetizers)) + + +def singleton_ingredients(dishes: List[Set[str]], intersection) -> set: + """ + 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 `_INTERSECTIONS` + constants imported from `sets_categories_data.py`. + :return: set - containing singleton ingredients. + + Each dish is represented by a `set` of its ingredients. + + Each `_INTERSECTIONS` is an `intersection` of all dishes in the + 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. + """ + + singletons: set = set() + for dish in dishes: + singletons = singletons.union(dish.difference(intersection)) + return singletons