我有一个程序,其中一个功能是出售用户拥有的物品。它会提示用户输入名称(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)