Python 制造零钱计数器,不能分割硬币

Python 制造零钱计数器,不能分割硬币,python,Python,我必须设计一个程序,当输入一个项目的金额时,要求用户支付金额,然后提供20's 10's 5's 25美分、10美分、5美分和1美分的零钱。我花了几个小时试图找出我代码中的缺陷,但我没能把它弄对。如果有人能帮助我,我将不胜感激 我意识到我的代码不是很完美,但我刚刚开始,到目前为止还没有学到太多的技术。 我一直在工作,直到它达到一角钱,然后事情就变坏了 以下是我的代码: #assign variables# import math cost=float(input("Enter the price

我必须设计一个程序,当输入一个项目的金额时,要求用户支付金额,然后提供20's 10's 5's 25美分、10美分、5美分和1美分的零钱。我花了几个小时试图找出我代码中的缺陷,但我没能把它弄对。如果有人能帮助我,我将不胜感激

我意识到我的代码不是很完美,但我刚刚开始,到目前为止还没有学到太多的技术。 我一直在工作,直到它达到一角钱,然后事情就变坏了

以下是我的代码:

#assign variables#
import math
cost=float(input("Enter the price of the item: $"))
paid=float(input("Enter the amount paid: $"))
#calculations#
difference=round(paid,2)-round(cost,2)
change= round(difference,2)
#twentys#
remain20=float(change%20)
twent=float(change-remain20)
twent1=abs(float(twent)//20)
twent2=float(twent1*20)
sub1=float(change-float(twent2))
print(sub1,"sub1")
#tens

remain10=change%10
ten=sub1-remain10
ten1=ten//10
ten2=ten1*10
sub2=sub1-ten2
print(sub2,"sub2")
#fives

remain5=float(abs(change%5))
five=abs(float(sub2)-float(abs(remain5)))
five1=float(round(abs(five)//5))
five2=float(round(five*5))
sub3=abs(float(sub2)-abs(float(five2)))
print(sub3,"sub3")
#ones
remain1=change%1
one=abs(round(sub3)-abs(remain1))
one1=abs(round(one//1))
one2=abs(round(one*1))
sub4=abs(float(sub3))-abs(float(one2))
print(sub4,"sub4")
#quarters
remainq=change%(0.25)
remainq1=round(remainq,2)
q=abs(sub4)-(remainq1)
q1=abs(q//float(0.25))
q2=abs(q*0.25)
sub5=abs(float(sub4))-(float(q2))
print(sub5,"sub5")
#dimes

remaind=change%(0.10)
remaind1=round(remaind,2)
d=abs(round(sub5,2)-remaind1)
d1=abs(d//float(0.10))
d2=abs(d1*0.10)
sub6=abs(float(sub5))-abs(float(d2))
print(sub6,"sub6")
#nickles

remainn=change%(0.05)
remainn1=round(remainn,2)
n=abs(round(sub6,2)-abs(remainn1))
n1=abs(d//float(0.05))
n2=abs(d1*0.05)
sub7=float(abs(sub6)-float(n2))
print(sub7,"sub7")
#pennies

remainp=change%(0.01)
remainp1=round(remainp,2)
p=abs(round(sub7,2)-abs(remainp1))
p1=abs(d//float(0.01))
p2=abs(d1*0.01)
#outputs
print(round(twent1),str("Twenty dollar bills"))
print(round(ten1),str("Ten dollar bills"))
print(round(five1),str("Five dollar bills"))
print(round(one1),str("One dollar bills"))
print(round(q1),str("Quarters"))
print(int(d1),str("dimes"))
print(int(n1),str("nickles"))
print(int(p1),str("Pennies"))

如果可以用整数解决问题,我建议您避免使用浮点数。想想看,在这个特殊的问题中,你可以把所有的弹药转换成便士(乘以100)。这样,解决方案变得简单明了,例如:

def distribute(value):
    result = {
        2000: [0, "Twenty dollar"],
        1000: [0, "Ten dollar"],
        500: [0, "Five dollar"],
        100: [0, "One dollar"],
        25: [0, "Quarters"],
        10: [0, "dimes"],
        5: [0, "nickles"],
        1: [0, "Pennies"]
    }

    if value < 0:
        print("Not enough money... you need {0}$ more".format(abs(value)))
    elif value == 0:
        print("Thanks for buying in the shop!")
    else:
        pennies = value * 100

        for k in reversed(sorted(result.keys())):
            if k < pennies:
                result[k][0] = num_coins = int(pennies / k)
                print("{0} {1}{2}".format(
                    num_coins, result[k][1], " bills" if k >= 100 else ""))
                pennies -= num_coins * k

    return result

if __name__ == "__main__":
    try:
        print("---------------------------")
        print(" Welcome to shopping 0.0.1 ")
        print("---------------------------")
        cost = int(input("Enter the price of the item: $"))
        paid = int(input("Enter the amount paid: $"))
        summary = distribute(paid - cost)
    except Exception as e:
        print("Something unexpected happened! {0}".format(e))
def分配(值):
结果={
2000年:[0,“二十美元”],
1000:[0,“十美元”],
500:[0,“五美元”],
100:[0,“一美元”],
25:[0,“季度”],
10:[0,“一角硬币”],
5:[0,“刻痕”],
1:[0,“便士”]
}
如果值<0:
打印(“没有足够的钱……您需要{0}$more”。格式(abs(value)))
elif值==0:
打印(“感谢您在本店购买!”)
其他:
便士=价值*100
对于反转中的k(已排序(result.keys()):
如果k<便士:
结果[k][0]=num_coins=int(便士/k)
打印(“{0}{1}{2}”。格式(
钱币数量,结果[k][1],“纸币”(如果k>=100,则为“其他”)
便士-=num_硬币*k
返回结果
如果名称=“\uuuuu main\uuuuuuuu”:
尝试:
打印(“-------------------------------”)
打印(“欢迎使用购物0.0.1”)
打印(“-------------------------------”)
成本=整数(输入(“输入项目价格:$”)
已付=整数(输入(“输入已付金额:$”)
汇总=分配(已付-成本)
例外情况除外,如e:
打印(“发生了意外事件!{0}”。格式(e))

如果可以用整数解决问题,我建议您避免使用浮点数。想想看,在这个特殊的问题中,你可以把所有的弹药转换成便士(乘以100)。这样,解决方案变得简单明了,例如:

def distribute(value):
    result = {
        2000: [0, "Twenty dollar"],
        1000: [0, "Ten dollar"],
        500: [0, "Five dollar"],
        100: [0, "One dollar"],
        25: [0, "Quarters"],
        10: [0, "dimes"],
        5: [0, "nickles"],
        1: [0, "Pennies"]
    }

    if value < 0:
        print("Not enough money... you need {0}$ more".format(abs(value)))
    elif value == 0:
        print("Thanks for buying in the shop!")
    else:
        pennies = value * 100

        for k in reversed(sorted(result.keys())):
            if k < pennies:
                result[k][0] = num_coins = int(pennies / k)
                print("{0} {1}{2}".format(
                    num_coins, result[k][1], " bills" if k >= 100 else ""))
                pennies -= num_coins * k

    return result

if __name__ == "__main__":
    try:
        print("---------------------------")
        print(" Welcome to shopping 0.0.1 ")
        print("---------------------------")
        cost = int(input("Enter the price of the item: $"))
        paid = int(input("Enter the amount paid: $"))
        summary = distribute(paid - cost)
    except Exception as e:
        print("Something unexpected happened! {0}".format(e))
def分配(值):
结果={
2000年:[0,“二十美元”],
1000:[0,“十美元”],
500:[0,“五美元”],
100:[0,“一美元”],
25:[0,“季度”],
10:[0,“一角硬币”],
5:[0,“刻痕”],
1:[0,“便士”]
}
如果值<0:
打印(“没有足够的钱……您需要{0}$more”。格式(abs(value)))
elif值==0:
打印(“感谢您在本店购买!”)
其他:
便士=价值*100
对于反转中的k(已排序(result.keys()):
如果k<便士:
结果[k][0]=num_coins=int(便士/k)
打印(“{0}{1}{2}”。格式(
钱币数量,结果[k][1],“纸币”(如果k>=100,则为“其他”)
便士-=num_硬币*k
返回结果
如果名称=“\uuuuu main\uuuuuuuu”:
尝试:
打印(“-------------------------------”)
打印(“欢迎使用购物0.0.1”)
打印(“-------------------------------”)
成本=整数(输入(“输入项目价格:$”)
已付=整数(输入(“输入已付金额:$”)
汇总=分配(已付-成本)
例外情况除外,如e:
打印(“发生了意外事件!{0}”。格式(e))

您的主要问题是货币计算(和余数操作)在
浮动
中不能很好地工作。在前面转换成一个
int
pennies数,大多数错误源就会消失(只要正确地四舍五入)

您还可以大大简化代码。现在,每个面额都有其特殊情况,尽管除了字符串名称和单位之外,所有面额的工作基本相同。概括代码,您可以将其简化为一个简单的循环,使用一对(常量、顶级)
tuple
s定义实际更改的部分:

# These are the only thing that differ as you go, so just list them explicitly
denominations = ('Twenty dollar bills', 'Ten dollar bills', 'Five dollar bills', 'One dollar bills', 'quarters', 'dimes', 'nickels', 'pennies')
divisors = (2000, 1000, 500, 100, 25, 10, 5, 1)

def make_change(paid, cost):
    '''paid and cost should be floats with up to two decimal places of precision'''
    # Calculate the difference in price, then convert to an int penny count
    # so we can use accurate math
    change = round((paid - cost) * 100)  # Wrap round in int constructor on Py2

    # Not necessary if inputs are trusted, but good form
    if change < 0: raise ValueError("Underpaid!")

    # Each loop replaces a special case from your code by swapping in the
    # string and divisor for that round
    for denom, div in zip(denominations, divisors):
        numdenom, change = divmod(change, div)
        # Conditional print; weird to say "0 fives", "0 ones" over and over
        # You can print unconditionally if you prefer
        if numdenom:
            print(numdenom, denom)
#这些是唯一与您所做的不同之处,因此请明确列出它们
面额=(‘二十美元钞票’、‘十美元钞票’、‘五美元钞票’、‘一美元钞票’、‘二十五美分’、‘一角硬币’、‘五美分’)
除数=(2000、1000、500、100、25、10、5、1)
def更改(已支付、成本):
“支付和成本应为浮动,精度最多为小数点后两位”
#计算价格差异,然后转换为整数便士计数
#所以我们可以使用精确的数学
变更=舍入((已付-成本)*100)#在Py2上的int构造函数中进行舍入
#如果输入是可信的,则不需要,但形式良好
如果更改<0:raise VALUETERROR(“薪酬过低!”)
#每个循环都会通过在中交换来替换代码中的特殊情况
#该轮的字符串和除数
对于denom,zip中的div(面额、除数):
numdenom,change=divmod(change,div)
#条件性打印;一遍又一遍地说“0个5”,“0个1”很奇怪
#如果愿意,您可以无条件打印
如果是numdenom:
打印(numdenom、denom)

就这样。整个计算过程(忽略注释和空行)是两个常量定义和七行实际代码。

您的主要问题是货币计算(和余数操作)与
float
不太兼容。在前面转换成一个
int
pennies数,大多数错误源就会消失(只要正确地四舍五入)

您还可以大大简化代码。现在,每个面额都有其特殊情况,尽管除了字符串名称和单位之外,所有面额的工作基本相同。概括代码,您可以将其简化为一个简单的