首页 > 解决方案 > 试图创建一个代码/功能,允许用户购买成分,然后将其存储在他们的库存中,怎么办?

问题描述

我是一个初学者 Python 编码器,我正在尝试创建一个函数,允许用户购买/购买 3 种不同的成分(“苹果”、“甜菜”和“胡萝卜”),每种成分为 1 美元。我定义的函数将采用 2 个参数(成分名称和他们想要购买的数量)。用户拥有的最大金额为 20 美元。

iinventory={}
iinventory['apple']=0
iinventory['beets']=0
iinventory['carrots']=0

def buyingredient(ingredient_name,number: int):
    total=20
    while total > 0:
        if number > total:
            break
        if number < total:
            iinventory[ingredient_name] += number
            total = total + number
            iinventory.append(number))

我在如何实际开始代码方面遇到了麻烦,因为首先我必须确保他们购买的金额不超过他们的总金额(20 美元)。另外,我不确定如何将购买的金额放入作为字典的库存中。我以为我可以使用 append 但我认为这仅适用于列表而不是字典。

然后,无论他们购买多少苹果、甜菜或胡萝卜,都会反映在他们的总数上并减去。例如,如果他们买了 3 个苹果:

购买redient('苹果',3)

然后库存会说他们有 3 个苹果,总共还剩 17 美元。

iinventory={'苹果':3,'甜菜':0,'胡萝卜':0} 总计=17

现在不知道从这里去哪里获取代码....

标签: pythonpython-3.x

解决方案


尝试跟踪购买新成分时所花费的金额,然后可以避免该循环:

inventory = {
    "apple": 0,
    "beets": 0,
    "carrots": 0}

total_budget = 20
total_spent = 0

def buy_ingredient(name, number):
    if number + total_spent > total_budget:
        raise ValueError("overspent!")
    inventory[name] += number
    total_spent += number

让我们尝试一下(请耐心等待,我将采取一点切线):

>>> buy_ingredient('apple', 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in buy_ingredient
UnboundLocalError: local variable 'total_spent' referenced before assignment

呸!

这失败了,因为total_spent是在函数之外定义的。出于这个原因,让函数更新“存在”在它们之外的变量通常被认为是不好的做法——最好是返回一些东西。(是的,更新iinventory会起作用,但它仍然被认为是不好的风格。)

在这种情况下,您正在创建一些东西,然后对其进行了未知次数的修改——这是一个学习课程的绝佳机会。让我们创建一个GroceryBasket跟踪您的预算和您添加的项目:

from collections import defaultdict

class GroceryBasket(object):
    def __init__(self, budget):
        self.items = defaultdict(int)
        self.budget = budget
        self.spent_so_far = 0

    def add_ingredient(self, name, number):  # note this is almost exactly the `buy_ingredient` function from above
        if number + self.spent_so_far > self.budget:
            raise ValueError("overspent!")
        self.items[name] += number
        self.spent_so_far += number

创建一个实例,指定您的预算:

>>> basket = GroceryBasket(budget=20)
>>> basket.budget
20
>>> basket.spent_so_far
0

加5个苹果:

>>> basket.add_ingredient("apple", 5)
>>>
>>> basket.items
defaultdict(<type 'int'>, {'apple': 5})
>>>
>>> basket.spent_so_far
5

现在有 100 个甜菜:

>>> basket.add_ingredient('beets', 100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in add_ingredient
ValueError: overspent!

无论如何,这可能比您正在寻找的答案更多,但我想加强您的功能,同时指出它应该返回一个值或更新传入的对象的状态(在这种情况下,self)而不会让您挂起. 希望这可以帮助。

(顺便说一句,如果您想知道是什么defaultdict,请查看文档,它们非常好。有一个示例显示使用defaultdict(int)操作+=符不太远:https ://docs.python.org/ 3/library/collections.html#collections.defaultdict )


推荐阅读