F. Кофейня

Руководство местной кофейни для программистов под названием Java-0x00 решило модернизировать систему заказа кофе.

Для этого им требуется реализовать функцию order, которая принимает список предпочтений посетителя в порядке «убывания желания».

Согласно положению, каждый напиток в кофейне строго определён рецептом:

  • Эспрессо готовится из: 1 порции кофейных зерен.
  • Капучино готовится из: 1 порции кофейных зерен и 3 порций молока.
  • Макиато готовится из: 2 порций кофейных зерен и 1 порции молока.
  • Кофе по-венски готовится из: 1 порции кофейных зерен и 2 порций взбитых сливок.
  • Латте Макиато готовится из: 1 порции кофейных зерен, 2 порций молока и 1 порции взбитых сливок.
  • Кон Панна готовится из: 1 порции кофейных зерен и 1 порции взбитых сливок.

В глобальной переменной in_stock содержится словарь, описывающий ингредиенты в наличии. Ключи словаря: coffeecreammilk.

Функция должна вернуть:

  • название напитка, который будет приготовлен;
  • сообщение «К сожалению, не можем предложить Вам напиток», если ни одно из предпочтений не может быть приготовлено.

Если заказ, может быть совершён, количество доступных ингредиентов должно соответствующим образом уменьшиться.

Примечание

В решении не должно быть вызовов требуемых функций.

Пример

Ввод

in_stock = {"coffee": 1, "milk": 2, "cream": 3}
print(order("Эспрессо", "Капучино", "Макиато", "Кофе по-венски", "Латте Макиато", "Кон Панна"))
print(order("Эспрессо", "Капучино", "Макиато", "Кофе по-венски", "Латте Макиато", "Кон Панна"))

Вывод

Эспрессо
К сожалению, не можем предложить Вам напиток

Ввод

in_stock = {"coffee": 4, "milk": 4, "cream": 0}
print(order("Капучино", "Макиато", "Эспрессо"))
print(order("Капучино", "Макиато", "Эспрессо"))
print(order("Капучино", "Макиато", "Эспрессо"))

Вывод

Капучино
Макиато
Эспрессо

Решение

Очень хорошая задача на применение словарей. Применение глобальных переменных не так оправдано, но мы в этом разделе изучаем именно их, а значит, пусть будут глобальные переменные.

Формируем словарь рецептов. Будьте на этом этапе особенно внимательны. 90% вопросов о неработоспособностью программы связаны именно с ошибками в словаре.

Каждый вызов запускаем проверку – всех ли ингредиентов хватает, чтобы приготовить напиток. Если да, то возвращаем название напитка, если нет, то сообщение с извинениями.
Для того, чтобы проверить хватает ли нам ингредиентов, достаточно СНАЧАЛА проверить все ключи словаря рецепта, а потом, и только в случае успеха уменьшить значения соответствующих ингредиентов на складе.

На этом можно было бы и закончить, но представленный алгоритм не учитывает одну простую вещь – а что, если в рецептах есть ингредиент, которого нет в списке ингредиентов на складе? Первые три решения выдадут ошибку, что конечно же, неправильно. Решить проблему может простая проверка – прежде чем проверять хватает ли данного ингредиента на складе, можно проверить есть ли он там вообще в списке ингредиентов. Сделать это можно прямо в конструкции которая проверяет достаточность ингредиентов.

Посмотреть код

Решение

Python
RECIPES = {
    "Эспрессо": {"coffee": 1},
    "Капучино": {"coffee": 1, "milk": 3},
    "Макиато": {"coffee": 2, "milk": 1},
    "Кофе по-венски": {"coffee": 1, "cream": 2},
    "Латте Макиато": {"coffee": 1, "milk": 2, "cream": 1},
    "Кон Панна": {"coffee": 1, "cream": 1},
}

in_stock = {}


def order(*drinks):
    global in_stock

    for drink in drinks:
        for ingredient in RECIPES[drink]:
            if RECIPES[drink].get(ingredient, 0) > in_stock[ingredient]:
                break
        else:
            for ingredient in RECIPES[drink]:
                in_stock[ingredient] -= RECIPES[drink][ingredient]
            return drink

    if in_stock:
        return "К сожалению, не можем предложить Вам напиток"

Решение

Python
RECIPES = {
    'Эспрессо': {'coffee': 1},
    'Капучино': {"coffee": 1, "milk": 3},
    'Макиато': {"coffee": 2, "milk": 1},
    'Кофе по-венски': {"coffee": 1, "cream": 2},
    'Латте Макиато': {"coffee": 1, "milk": 2, "cream": 1},
    'Кон Панна': {"coffee": 1, "cream": 1},
}

in_stock = {}


def is_ingredients_enough(drink):
    global RECIPES, in_stock
    return all(
        ingredient in in_stock and RECIPES[drink][ingredient] <= in_stock[ingredient] for ingredient in RECIPES[drink]
    )  # noqa


def order(*drinks):
    global RECIPES, in_stock

    for drink in drinks:
        if is_ingredients_enough(drink):
            for ingredient, amount in RECIPES[drink].items():
                in_stock[ingredient] -= amount
            return drink

    return 'К сожалению, не можем предложить Вам напиток'

Решение

Python
RECIPES = {
    'Эспрессо': {'coffee': 1},
    'Капучино': {"coffee": 1, "milk": 3},
    'Макиато': {"coffee": 2, "milk": 1},
    'Кофе по-венски': {"coffee": 1, "cream": 2},
    'Латте Макиато': {"coffee": 1, "milk": 2, "cream": 1},
    'Кон Панна': {"coffee": 1, "cream": 1}
}

in_stock = {}


def order(*drinks):
    global in_stock, RECIPES

    for drink in drinks:
        if all(RECIPES[drink][ingredient] <= in_stock[ingredient] for ingredient in RECIPES[drink]):
            for ingredient, amount in RECIPES[drink].items():
                in_stock[ingredient] -= amount
            return drink

    return "К сожалению, не можем предложить Вам напиток"

Решение

Python
# Полное с точки зрения логики, но избыточное с точки зрения тестов Яндекса решение

RECIPES = {
    'Эспрессо': {'coffee': 1},
    'Капучино': {"coffee": 1, "milk": 3},
    'Макиато': {"coffee": 2, "milk": 1},
    'Кофе по-венски': {"coffee": 1, "cream": 2},
    'Латте Макиато': {"coffee": 1, "milk": 2, "cream": 1},
    'Кон Панна': {"coffee": 1, "cream": 1}
}

in_stock = {}


def order(*drinks):
    global in_stock, RECIPES

    for drink in drinks:
        if all(ingredient in in_stock and RECIPES[drink][ingredient] <= in_stock[ingredient] for ingredient in RECIPES[drink]):  # noqa
            for ingredient, amount in RECIPES[drink].items():
                in_stock[ingredient] -= amount
            return drink

    return "К сожалению, не можем предложить Вам напиток"
Подписаться
Уведомить о
guest
4 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Сергей
Сергей
05.06.2024 20:44

К сожалению я понял условие так, что нужно использовать только функцию, и нельзя задавать “дополнительные” глобальные переменные, а задавать словарь для проверки в самой функции тоже нельзя (или не красиво). В связи с чем, вот такое решение…

def order(*name_drink):
    global in_stock

    flag = True
    for name in name_drink:
        match name:
            case ‘Эспрессо’:
                if in_stock[“coffee”] >= 1:
                    in_stock[“coffee”] -= 1
                    return name
            case ‘Капучино’:
                if in_stock[“coffee”] >= 1 and in_stock[“milk”] >= 3:
                    in_stock[“coffee”] -= 1
                    in_stock[“milk”] -= 3
                    return name
            case ‘Макиато’:
                if in_stock[“coffee”] >= 2 and in_stock[“milk”] >= 1:
                    in_stock[“coffee”] -= 2
                    in_stock[“milk”] -= 1
                    return name
            case ‘Кофе по-венски’:
                if in_stock[“coffee”] >= 1 and in_stock[“cream”] >= 2:
                    in_stock[“coffee”] -= 1
                    in_stock[“cream”] -= 2
                    return name
            case ‘Латте Макиато’:
                if in_stock[“coffee”] >= 1 and in_stock[“milk”] >= 2 and in_stock[“cream”] >= 1:
                    in_stock[“coffee”] -= 1
                    in_stock[“cream”] -= 1
                    in_stock[“milk”] -= 2
                    return name
            case ‘Кон Панна’:
                if in_stock[“coffee”] >= 1 and in_stock[“cream”] >= 1:
                    in_stock[“coffee”] -= 1
                    in_stock[“cream”] -= 1
                    return name

    if flag:
        return ‘К сожалению, не можем предложить Вам напиток’

Сергей
Сергей
Ответить на  Сергей Клочко
05.06.2024 21:24

Я согласен, просто повторюсь, условие (в задании хендбука) было понято мной так, что мы можем написать в ответ только одну функцию (ее “тело”) и ничего до, ничего после.
Введение глобальной переменной “рецептов” в вашем решении тут полностью оправдано. Я так изначально и хотел, но почему то решил ,что решение чекер не пропустит.

Сергей
Сергей
05.06.2024 20:47

да и falg тоже лишний….можно просто return ‘К сожалению, не можем предложить Вам напиток’