缩短if elif elif-否则



我有一个程序,其中一个功能是出售用户拥有的物品。它会提示用户输入名称(id(和金额,然后进行销售。但是用户可以拥有很多项目,所以有很多if-else-elif语句。我该如何缩短它?(附言:我使用的是Replit,Replit目前有Python 3.8(下面是sell函数,供参考。

def sell_command():
  global cash
  cash = 0
  #I created a dictionary, inventory, which has how much the user has of a particular item.
  #itemSell variable contains what the user wants to sell
  #itemSellCount variable contains how much the user wants to sell
  #itemSoldCash variable calculates how much one item is worth, and multiplies for how much the user is selling
  #cash variable is hlobal since another function prints cash
  
  itemSell = input('What would you like to sell? ')
  itemSell = itemSell.lower()
  
  if itemSell == "cobblestone" or "cobble stone":
    itemSellCount = int(input("How many would you like to sell? "))
    if itemSellCount <= inventory["cobblestone"]:
      itemSoldCash = itemSellCount*10
      print("You sold " + str(itemSellCount) + " cobblestone/s for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["cobblestone"] -= itemSellCount
    elif itemSellCount > inventory["cobblestone"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "coal":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["coal"]:
      itemSoldCash = itemSellCount*5
      print("You sold " + str(itemSellCount) + " coal for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["coal"] -= itemSellCount
    elif itemSellCount > inventory["coal"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "iron ore" or "ironore":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["ironOre"]:
      itemSoldCash = itemSellCount*20
      print("You sold " + str(itemSellCount) + " iron ore/s for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["cobblestone"] -= itemSellCount
    elif itemSellCount > inventory["ironOre"]:
      print("You tried to sell more than what you have!")
    elif itemSell == "iron ingot" or "ironingot":
      itemSellCount = int(input("How many would you like to sell?"))
      if itemSellCount <= inventory["ironIngot"]:
        itemSoldCash = itemSellCount*25
        print("You sold " + str(itemSellCount) + " iron ingot/s for $" + str(itemSoldCash))
        cash = cash + itemSoldCash
        inventory["ironIngot"] -= itemSellCount
      elif itemSellCount > inventory["ironIngot"]:
        print("You tried to sell more than what you have!")
  elif itemSell == "emerald" or "emeralds":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["emerald"]:
      itemSoldCash = itemSellCount*100
      print("You sold " + str(itemSellCount) + "emerald/s for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["emerald"] -= itemSellCount
    elif itemSellCount > inventory["emerald"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "diamond" or "diamonds":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["diamond"]:
      itemSoldCash = itemSellCount*300
      print("You sold " + str(itemSellCount) + " diamond/s for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["diamond"] -= itemSellCount
    elif itemSellCount > inventory["diamond"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "oak":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["oak"]:
      itemSoldCash = itemSellCount*15
      print("You sold " + str(itemSellCount) + " oak/s for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["oak"] -= itemSellCount
    elif itemSellCount > inventory["oak"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "birch":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["birch"]:
      itemSoldCash = itemSellCount*15
      print("You sold " + str(itemSellCount) + " birch for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["birch"] -= itemSellCount
    elif itemSellCount > inventory["birch"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "redwood" or "red wood":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["redwood"]:
      itemSoldCash = itemSellCount*15
      print("You sold " + str(itemSellCount) + "redwood for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["redwood"] -= itemSellCount
    elif itemSellCount > inventory["redwood"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "spruce":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["spruce"]:
      itemSoldCash = itemSellCount*15
      print("You sold " + str(itemSellCount) + " spruce for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["spruce"] -= itemSellCount
    elif itemSellCount > inventory["spruce"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "acacia":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["acacia"]:
      itemSoldCash = itemSellCount*15
      print("You sold " + str(itemSellCount) + " acacia for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["acacia"] -= itemSellCount
    elif itemSellCount > inventory["acacia"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "jungle":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["jungle"]:
      itemSoldCash = itemSellCount*15
      print("You sold " + str(itemSellCount) + " jungle for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["jungle"] -= itemSellCount
    elif itemSellCount > inventory["jungle"]:
      print("You tried to sell more than what you have!")
  elif itemSell == "maple":
    itemSellCount = int(input("How many would you like to sell?"))
    if itemSellCount <= inventory["maple"]:
      itemSoldCash = itemSellCount*15
      print("You sold " + str(itemSellCount) + " maple for $" + str(itemSoldCash))
      cash = cash + itemSoldCash
      inventory["maple"] -= itemSellCount
    elif itemSellCount > inventory["maple"]:
      print("You tried to sell more than what you have!")

这是很多重复的代码,本质上是一样的(我已经清理了你的语法(:

itemSellCount = int(input("How many would you like to sell? "))
if itemSellCount <= inventory[itemSell]:
  itemSoldCash = itemSellCount*10
  print(f"You sold {itemSellCount} {itemSell}/s for ${itemSoldCash}")
  cash += itemSoldCash
  inventory[itemSell] -= itemSellCount
else:
  print("You tried to sell more than what you have!")

然而,有三件事需要考虑:

1.每件商品的售价是多少

这可以通过多种方式来解决,具体取决于编程风格以及您需要跟踪的每个项目。OOP方法是创建一个项类,每个项都有一些定义其值的属性。一个简单、程序化的方法是有一个字典来定义这一点:

itemValue = {
    "cobblestone": 10,
    "coal": 5,
    ...
}

现在,使用字典查找来确定itemSoldCash:

itemSoldCash = itemSellCount*itemValue[itemSell]

2.替代项目名称

您接受备选项目名称,例如";鹅卵石";被视为";鹅卵石"这也可以用字典来处理,例如:

itemAltNames = {
    "cobble stone": "cobblestone",
    "iron ingot": "iron ingot",
    ...
}

然后,你可以做一些类似的事情:

if itemSell in itemAltNames:
    itemSell = itemAltNames[itemSell];

或者,如果你的替代方案只涉及剥离空间,那么就这样做:

itemSell = itemSell.replace(" ","")

3.检查项目是否存在

按照目前的情况,如果用户输入了一个无效项目,则控制流将不会执行。这很好,但过于复杂了!此外,如果用户输入了无效项目,您是否会给出错误消息(或允许重复输入(?根据您的库存字典进行检查,以确保用户拥有以下项目:

if itemSell in inventory:

将其整合在一起

以下是现在一切的样子:

def sell_command():
    global cash
    cash = 0
    itemSell = input("What would you like to sell? ")
    while (itemSell := itemSell.lower().strip().replace(" ","")) not in inventory:
        itemSell = input(f"You do not have {itemSell} in your inventory. What would you like to sell? ")
    itemSellCount = int(input("How many would you like to sell? "))
    if itemSellCount <= inventory[itemSell]:
        itemSoldCash = itemSellCount * itemValue[itemSell]
        print(f"You sold {itemSellCount} {itemSell}/s for ${itemSoldCash}")
        cash += itemSoldCash
        inventory[itemSell] -= itemSellCount
    else:
        print("You tried to sell more than what you have!")

您可以使用字典和对象来减少分支。这就是OOP的力量。下面是一个如何重构代码的示例。

cash = 0

class CommodityShelf:
    """
    A shelf to hold commodities
    """
    def __init__(self, item_name, available_quantity, price):
        self.item_name = item_name
        self.available_qty = available_quantity
        self.price = price or 10
    def key(self):
        # "make it easy to search for this shelf"
        return self.item_name.lower().replace(" ", "")
    def sell(self):
        # handle the selling logic at one place, for any item
        global cash
        sell_units = int(input(f"How many {self.item_name} would you like to sell? "))
        if sell_units > self.available_qty:
            print(f"You tried to sell more {self.item_name} than what you have!")
        else:
            cash += (sell_units * self.price)
            self.available_qty -= sell_units
            print(f"You sold {self.item_name} for ${sell_units * self.price}")

def start_selling(pos_registry):
    """
    Start selling commodities
    :param pos_registry:
    :return:
    """
    item_to_sell = input('What would you like to sell? ').lower().replace(" ", "")
    if item_to_sell in pos_registry:
        pos_registry[item_to_sell].sell()
    else:
        print(f"You tried to sell {item_to_sell} but it's not in your inventory!")

if __name__ == '__main__':
    # create a shelf for each commodity
    inventory = [
        CommodityShelf("Cobble Stone", 10, 0),
        CommodityShelf("Coal", 10, 0),
        CommodityShelf("Iron Ore", 10, 0),
        CommodityShelf("Iron Ingot", 10, 0),
        CommodityShelf("Emarald", 10, 0),
        CommodityShelf("Diamond", 10, 0),
    ]
    # create a registry of all the shelves
    pos_registry = {pos.key(): pos for pos in inventory}
    # start selling
    start_selling(pos_registry)
    
    # loop it if the user wants to
    

我希望评论中有合乎逻辑的解释。

这段代码可能是最简单的修复程序。不过,您可能需要更改库存字典,使每个键都是小写的。

此外,itemSell == "cobblestone" or "cobble stone"总是返回true。

def sell_command():
  global cash
  cash = 0
  cashMultiplierDict = {"cobblestone": 10, "coal": 5} #etc
  #The following line just removes all white spaces (e.g. cobble stone becomes cobblestone)
  itemSell = input('What would you like to sell? ').lower().replace(" ", "")
  itemSellCount = int(input("How many would you like to sell? "))
  if itemSellCount <= inventory[itemSell]:
    itemSoldCash = itemSellCount * cashMultiplierDict[itemSell] #Uses the dict created before
    print("You sold " + str(itemSellCount) + " " + itemSell + "/s for $" + str(itemSoldCash))
    cash = cash + itemSoldCash
    inventory[itemSell] -= itemSellCount
  elif itemSellCount > inventory[itemSell]:
    print("You tried to sell more than what you have!")

您可以更好地组织代码:

itemSellCount = int(input("How many would you like to sell?")

为每个项目完成,这可以完成一次,然后

itemSoldCash = itemSellCount*15

是成本的数量。成本可以以更好的数据结构组织到一个目录中,也许是这样的:

# you can add if needed other attributes for all material, like color, weight, damage, duration, and so on
catalogue = {
    "cobblestone": {"cost": 15, 'color':'red'},
    "maple": {"cost": 15},
    "jungle": {"cost": 15},
    "acacia": {"cost": 15},
    "diamond": {"cost": 300},
    ...
}
# aliases
catalogue["cobble stone"] = catalogue["cobblestone"]

def sell(item, qty, inventory):
    if qty <= inventory[item]:
        sold = qty * catalogue[item]["cost"]
        print("You sold {} maple for ${}".format(qty, sold))
        cash += sold
        inventory[item] -= qty
    else:
        print("You tried to sell more {} than what you have!".format(item))

最后,你调用这个函数时需要所有的信息:

itemSell = input('What would you like to sell? ')
itemSell = itemSell.lower()
itemSellCount = int(input("How many would you like to sell? "))
sell(itemSell,itemSellCount, inventory)

示例中未定义库存。

PS如果许多对象的成本相同,并且它们被视为默认成本,则可以简化目录定义,只放入特殊成本,默认值可以作为缺失值应用:

sold = qty * (catalogue[item]["cost"] if item in catalogue else 15)

最新更新