views:

161

answers:

5

I am making a change program in python. The user must input a dollar amount and then the program will calculate the change in twenties, tens, fives, ones, quarters, dimes, nickels, and pennies. I was instructed to use the round function for the pennies because If I input an amount of $58.79, the program tells me to give 3 pennies back when it should be 4. Is there a way to round up these pennies?

I know the value of a penny is .01, but python reads this as .100000000001 which I believe is the problem.

Any help is appreciated, here is the section I need rounded:

# get the amount to change from the user

change = input("Please enter the amount to change: $")

print "To make change for $",change,"give the customer back:"

# calculate number of twenties
twenties = int(change/ 20)

print twenties, "twenties"

change = change - twenties *20

# calculate tens
tens = int(change / 10)

print tens, "tens"

change = change - tens *10

#calculate fives
fives = int(change / 5)

print fives, "fives"

change = change - fives *5

#calculate ones
ones = int(change / 1)

print ones, "ones"

change = change - ones * 1

#calculate quarters
quarters = int(change / .25)

print quarters, "quarters"

change = change - quarters * .25

#calculate dimes
dimes = int(change / .10)

print dimes, "dimes"

change = change - dimes * .10

#calculate nickels
nickels = int(change / .05)

print nickels, "nickels"

change = change - nickels * .05

#calculate pennies
pennies = int(change / .01)

print pennies, "pennies"
A: 
>>> from math import ceil
>>> a = 58.79
>>> ceil(a % 0.05 * 100)
4.0
>>>

[edit]

Now that I think of it, might aswell just go with

>>> a = 58.79
>>> a*100 % 5
4.0
Robus
I am still getting 3 pennies. The user can input any value to be changed, so for a i have it set as a = change, because in the beginning I have change as the name for the input function
Mike
*Shrug* Works perfectly fine here
Robus
here is the ouput I get when I input either of those: Please enter the amount to change: $58.79To make change for $ 58.79 give the customer back:2 twenties1 tens1 fives3 ones3 quarters0 dimes0 nickels3 pennies
Mike
+2  A: 

Multiply the user's inputed dollar value by 100, convert to int, and work in units of pennies.

Integer arithmetic is dead simple (and exact). Floating point arithmetic is tricky and forces you to use more brain cells :) . Save brain cells and work entirely in ints.

unutbu
That's what the OP is doing (dividing by .01 and casting to `int`)
NullUserException
`change = change - pennies * .01` seems to imply he's doing arithmetic with floats.
unutbu
@NullUserException: Multiplication by 100 and division by 0.01 are *not* equivalent on a binary (=any) computer.
Tim Pietzcker
@Tim I think we can leave the (im)precision of floating point arithmetic aside here.
NullUserException
I have added the entire program code.
Mike
+2  A: 

The problem is that 0.01 cannot be accurately represented as a binary floating point value (which is how normal floats are stored – this is true for any language, not just Python). So if you need exact values for dollars and cents, you can use the decimal module. That way you can be sure that your values will be rounded exactly.

Or (since Decimals might be overkill here), first multiply every dollar value by 100 (this is not the same as dividing by 0.01 for the above reasons!), convert to int, do your calculations, and divide by 100.

Tim Pietzcker
+1  A: 

use the decimal package

http://docs.python.org/library/decimal.html

it is meant exactly for this kind of use case

lesmana
A: 

The problems you are having are a result of imprecise floating-point arithmetic. There is no way to precisely represent 0.01 in IEEE floating point. That is one reason not to use floats when working with currency.

You should use decimals or even integers, because you know there are at most 2 digits after the decimal point. In that case, just work with the amount in pennies.


On the problem itself, I think the easiest way to do it is convert your amount in dollars to the amount in pennies, then iterate through a predefined list of values containing listing the equivalent amount of pennies (in descending order) for each denomination:

def change(amount):

    # this can be removed if you pass the amount in pennies
    # rather than dollars
    amount = int(round(amount*100))

    values = [2000, 1000, 500, 100, 25, 10, 5, 1]
    denom = ['twenties', 'tens', 'fives', 'ones', 'quarters', 'dimes', 'nickels', 'pennies']

    for i in range(len(values)):
        num = amount / values[i]
        amount -= num * values[i]
        print str(num) + " " + denom[i]

Now calling change(58.79) will print

2 twenties
1 tens
1 fives
3 ones
3 quarters
0 dimes
0 nickels
4 pennies

As seen on codepad.org

NullUserException
Thank you, this has helped a lot. My professor is picky in the way he wants us to write in python, hence why we are using floats this time.
Mike
I would prefer `num, amount= divmod(amount, values[i])` instead of two separate assignments (`num = amount / values[i]; amount -= num * values[i]`)
ΤΖΩΤΖΙΟΥ