Skip to content

Problem 5: Vending Machine (100pts)

Problem

A vending machine sells a particular product for a fixed price. It supports the following three operations:

  • restock(amount): Adds amount items to the machine and returns the current stock.
  • deposit(amount): Deposits amount dollars into the machine and returns the current balance if the machine has stock. If the machine is out of stock, it returns a message as shown in the doctests.
  • vend(): Attempts to vend one product. If the machine is out of stock or the balance is insufficient, the vending fails and a message is returned as shown in the doctests. If the balance is sufficient, the machine vends one product and gives back any change remaining after the purchase.

Implement the function make_vending_machine, which takes a product and its price, and returns three functions — restock, deposit, and vend — for interacting with the vending machine.

一台自动售货机以固定的 price 价格出售特定的 product。 它支持以下三种操作:

  • restock(amount): 向机器中添加 amount 数量的商品并返回当前库存。
  • deposit(amount): 向机器中存入 amount 美元,如果机器有库存,则返回当前余额。 如果机器缺货,则返回 doctests 中所示的消息。
  • vend(): 尝试售出一件商品。 如果机器缺货或余额不足,则售卖失败并返回 doctests 中所示的消息。 如果余额充足,机器售出一件商品,并找回购买后剩余的零钱。

实现函数 make_vending_machine,它接受一个 product 及其 price, 并返回三个函数—— restockdepositvend ——用于与自动售货机交互。

def make_vending_machine(product, price):
    """
    Create a vending machine for the given product and price.

    >>> restock, deposit, vend = make_vending_machine('SICP book', 10)
    >>> deposit(7)
    'Machine is out of stock.'
    >>> restock(2)
    2
    >>> deposit(7)
    7
    >>> vend()
    'Insufficient balance. Please deposit 3 yuan more.'
    >>> deposit(5)
    12
    >>> vend()
    'Here is your SICP book and 2 yuan change.'
    >>> deposit(10)
    10
    >>> vend()
    'Here is your SICP book.'
    >>> vend()
    'Machine is out of stock.'
    """
    "*** YOUR CODE HERE ***"

Hints

Hint 1: You may find Python string formatting syntax useful. A quick example:

>>> ten, twenty, thirty = 10, 'twenty', [30]
>>> '{0} plus {1} is {2}'.format(ten, twenty, thirty)
'10 plus twenty is [30]'

Hint 2: A vending machine doesn’t "eat money". It should never keep any money when out of stock or after completing a vend.

Hint 3: When debugging, you can call restock(0) to check the remaining number of products and deposit(0) to check the current balance in your vending machine.

Hint 4: This TA is kind, not evil — he won’t steal products (e.g., restock(-1)) or steal money (e.g., deposit(-1)) from your vending machine.

>>> ten, twenty, thirty = 10, 'twenty', [30]
>>> '{0} plus {1} is {2}'.format(ten, twenty, thirty)
10 plus twenty is [30]'
  • 自动售货机不会“吃钱”。当缺货时或完成售卖后,它不应保留任何金钱。

  • 调试时,您可以调用 restock(0) 来检查剩余的产品数量,并调用 deposit(0) 来检查自动售货机中的当前余额。

  • 这位助教很善良,不坏——他不会从您的自动售货机中偷走产品(例如,restock(-1))或偷走金钱(例如,deposit(-1))。

  • 还可以使用 f-string 来格式化字符串。

Solutions

这里使用 f-string:

def make_vending_machine(product, price):
    stock = 0
    balance = 0
    def restock(x):
        nonlocal stock
        stock += x
        return stock
    def deposit(x):
        nonlocal balance
        if stock == 0:
            return "Machine is out of stock."
        balance += x
        return balance
    def vend():
        nonlocal stock, balance
        if stock == 0:
            return "Machine is out of stock."
        if balance < price:
            return f"Insufficient balance. Please deposit {price - balance} yuan more."
        if balance == price:
            balance = 0 
            stock -= 1
            return f"Here is your {product}."
        if balance > price:
            change = balance - price
            balance = 0
            stock -= 1
            return f"Here is your {product} and {change} yuan change."
    return restock, deposit, vend