CS50第6周的PSET现金在while循环中未正确执行。

huangapple go评论74阅读模式
英文:

CS50 week 6 PSET cash doesn't follow through while loop properly

问题

我正在尝试实现一个程序,该程序接收所需的找零金额,并返回所需的最少硬币数量(25美分、10美分、5美分和1美分)以找零。我选择让用户输入正确的格式(我已经在这一端进行了错误处理,它是有效的),然后将找零的值传递到一个while循环中,将找零的值与上述硬币值之一进行比较,看它是否大于或等于。所需硬币的整数数量被计算并添加到硬币的运行总数中,所需的找零值被更新以从现有找零中减去从计算出的硬币中返回的新找零总数。循环在找零达到0时终止:

import math
while True:
    try:
        changeOwed = float(input("Change owed:"))
        while changeOwed < 0:
            changeOwed = float(input("Change owed:"))
        break
    except ValueError:
        continue

coinCount = 0
while changeOwed > 0:
    if changeOwed >= 0.25:
        quartersNeeded = math.floor(changeOwed/0.25)
        coinCount = coinCount + quartersNeeded
        changeOwed = changeOwed - (quartersNeeded*0.25)
    elif changeOwed >= 0.10:
        dimesNeeded = math.floor(changeOwed/0.1)
        coinCount = coinCount + dimesNeeded
        changeOwed = changeOwed - (dimesNeeded*0.1)
    elif changeOwed >= 0.05:
        NickelsNeeded = math.floor(changeOwed/0.05)
        coinCount = coinCount + NickelsNeeded
        changeOwed = changeOwed - (NickelsNeeded*0.05)
    else:
        PenniesNeeded = math.floor(changeOwed/0.01)
        coinCount = coinCount + PenniesNeeded
        changeOwed = changeOwed - (PenniesNeeded*0.01)
    break
print(coinCount)

问题在于,如果我使用不能完全被上述任何硬币值整除的值来测试程序(例如0.4、4、0.2、0.15等),程序只返回最大硬币值的硬币数量(即4.2返回16个硬币,全部都是0.25,但忽略了两个硬币,它们是0.1。或者0.15返回一个硬币,即0.1,忽略了剩余的0.05。如果我删除break语句,程序只能处理完全可以被任何硬币值整除的值,但对于其他值会进入一个非终止的循环。如何修复这个问题,为什么会出现这个问题?

英文:

I'm trying to implement a program that takes the value of change required and returns back the least the amount of coins required (25 cents,10 cents, 5 cents, and 1 cent) to give back that change. What I've opted for is the user to input the correct format(I've done error handling on this end which works) and this value of change will be passed through a while loop where the value of change will be compared to see if it is greater than or equal or to one of thee aforementioned coin values. The integer number of coins required is calculated and added to a running total of coins, and the value of change required is updated to remove the new total of change given back from the coins calculated from the existing change. The loop terminates once the change reaches 0:

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: python -->

import math
while True:
        try:
            changeOwed = float(input(&quot;Change owed:&quot;))
            while changeOwed &lt; 0:
                changeOwed = float(input(&quot;Change owed:&quot;))
            break
        except ValueError:
            continue


    coinCount = 0
    while changeOwed &gt;float(0):
        if changeOwed &gt;= 0.25:
            quartersNeeded = math.floor(changeOwed/0.25)
            coinCount = coinCount + quartersNeeded
            changeOwed = changeOwed - (quartersNeeded*0.25)
        elif changeOwed &gt;= 0.10:
            dimesNeeded = math.floor(changeOwed/0.1)
            coinCount = coinCount + dimesNeeded
            changeOwed = changeOwed - (dimesNeeded*0.1)
        elif changeOwed &gt;= 0.05:
            NickelsNeeded = math.floor(changeOwed/0.05)
            coinCount = coinCount + NickelsNeeded
            changeOwed = changeOwed - (NickelsNeeded*0.05)
        else:
            PenniesNeeded = math.floor(changeOwed/0.01)
            coinCount = coinCount + PenniesNeeded
            changeOwed = changeOwed - (PenniesNeeded*0.01)
        break
    print(coinCount)

<!-- end snippet -->

The problem here is if I test the program with values that aren't fully divisible by any of the aforementioned coin values (such as 0.4,4,.2,0.15,etc..) the program only returns the coin count for the largest coin value (i.e. 4.2 returns 16 coins (all of which are 0.25) but neglects the 2 coins that are 0.1. Or 0.15 returns one coin (the 0.1) while forgetting about the remaining 0.05. If I remove the break the statement the program only works with values that are fully divisible by any of the coin values, but enters a non-terminating loop for other values. How do I fix this, and why has this happened?

答案1

得分: 1

一个问题是对浮点数进行地板除法,例如0.15给了1角4分。将所有值乘以100以进行整数地板除法似乎可以解决问题。猜测这与浮点数运算有关。

def make_change(change_owed=-1):
    coins = {}

    while change_owed < 0:
        try: change_owed = float(input('Change owed:'))
        except ValueError: print('无效金额,请重试')
    
    print('应找零金额:%.2f' % change_owed)
    
    change_owed *= 100
    
    coins['quarters'] = change_owed // 25
    change_owed -= coins['quarters'] * 25
    coins['dimes'] = change_owed // 10
    change_owed -= coins['dimes'] * 10
    coins['nickels'] = change_owed // 5
    change_owed -= coins['nickels'] * 5
    coins['pennies'] = change_owed

    print('总硬币数:', int(sum(coins.values())))
    for k, v in coins.items():
        if v: print('%11s:' % k, '%d' % v)

for i in (4.20, 0.69, 0.42, 0.2, 0.15):
    print('-' * 17)
    make_change(i)

输出:

-----------------
应找零金额:4.20
总硬币数:18
   quarters: 16
      dimes: 2
-----------------
应找零金额:0.69
总硬币数:8
   quarters: 2
      dimes: 1
    nickels: 1
    pennies: 4
-----------------
应找零金额:0.42
总硬币数:5
   quarters: 1
      dimes: 1
    nickels: 1
    pennies: 2
-----------------
应找零金额:0.20
总硬币数:2
      dimes: 2
-----------------
应找零金额:0.15
总硬币数:2
      dimes: 1
    nickels: 1
英文:

one issue was doing floor division with floats, for example 0.15 gave 1 dime and 4 pennies. multiplying everything by 100 to do floor division by integers seems to fix the problem.
guess it has to do with Floating Point Math.

def make_change(change_owed=-1):
    coins = {}

    while change_owed &lt; 0:
        try: change_owed = float(input(&#39;Change owed:&#39;))
        except ValueError: print(&#39;invalid amount, try again&#39;)
    
    print(&#39;change owed: %.2f&#39; % change_owed)
    
    change_owed *= 100
    
    coins[&#39;quarters&#39;] = change_owed // 25
    change_owed -= coins[&#39;quarters&#39;] * 25
    coins[&#39;dimes&#39;] = change_owed // 10
    change_owed -= coins[&#39;dimes&#39;] * 10
    coins[&#39;nickles&#39;] = change_owed // 5
    change_owed -= coins[&#39;nickles&#39;] * 5
    coins[&#39;pennies&#39;] = change_owed

    print(&#39;total coins:&#39;, int(sum(coins.values())))
    for k, v in coins.items():
        if v: print(&#39;%11s:&#39; % k, &#39;%d&#39; % v)

for i in (4.20, 0.69, 0.42, 0.2, 0.15):
    print(&#39;-&#39; * 17)
    make_change(i)

output:

-----------------
change owed: 4.20
total coins: 18
   quarters: 16
      dimes: 2
-----------------
change owed: 0.69
total coins: 8
   quarters: 2
      dimes: 1
    nickles: 1
    pennies: 4
-----------------
change owed: 0.42
total coins: 5
   quarters: 1
      dimes: 1
    nickles: 1
    pennies: 2
-----------------
change owed: 0.20
total coins: 2
      dimes: 2
-----------------
change owed: 0.15
total coins: 2
      dimes: 1
    nickles: 1

huangapple
  • 本文由 发表于 2023年7月24日 16:37:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76752727.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定