Rounding up with pennies in Python? - python

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"

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.

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.

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

use the decimal package
http://docs.python.org/library/decimal.html
it is meant exactly for this kind of use case

>>> 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

Related

In Python 3, how do I round a floating point number up to a certain decimal place?

I have 12.5, and I want to convert it to 13. How can I do this in Python 3?
The task was like this - "Given the meal price (base cost of a meal), tip percent (the percentage of the meal price being added as tip), and tax percent (the percentage of the meal price being added as tax) for a meal, find and print the meal's total cost"
I solved the problem in Python 3 and in 3 test cases, it shows that my code is working. but in 1 case it is not.
Where,
Sample input:
12.00
20
8
Expected output:
13
And my output was 12.5
How on earth I can take 12.5 as 13?
mealcost = float(input())
tippercent = float(input())
taxpercent = float(input())
tippercent = mealcost * (tippercent / 100)
taxpercent = mealcost * (taxpercent / 100)
totalcost = float( mealcost + tippercent + taxpercent)
print(totalcost)
Use round()
print(round(12.5))
>>> 13.0
To round to the nearest X (ie nearest 20.0)
just divide by the value you want to round to
then round the result
then multiply it by the number you want to round to and cast to an int
for example
round_to_nearest = 20
for a_num in [9,15,22,32,35,66,98]:
rounded = int(round(a_num/round_to_nearest)*round_to_nearest)
print("{a_num} rounded = ".format(a_num=a_num,r=rounded))
to just round
oh nevermind it looks like you just want
print(round(12.3),round(12.6)) # 12, 13
if round rounds wrongly (ie round(12.5) => 12 in python3) you can just add 0.5 to your number and floor it
int(12.5+0.5)

python find the minimum number of coins

i am tasked to make a program that will take a monetary amount and find the minimum number of coins needed to get that amount. here is my code.
import math
n1 = eval(input("Enter a monetary amount: "))
n1 = n1 * 100
dollars = 0
quarters = 0
dimes = 0
nickels = 0
pennies = 0
dollars = n1 / 100
n1 %= 100
quarters = n1 / 25
n1 %= 25
dimes = n1 / 10
n1 %= 10
nickels = n1 / 5
n1 %= 5
pennies = n1
print (int(dollars), int(quarters), int(dimes), int(nickels), int(pennies))
whenever I enter a number that needs nickels, it doesn't count them. for example, the output for 1.05 would be
1 0 0 0 0
the output for 1.15 is
1 0 1 0 4
any hints would be appreciated, thanks.
edited a typo that i had, code is still not working as intended though.
You're running into a floating point issues:
>>>> 1.15*100
114.99999999999999
As you can see, here you clearly do not have 115 cents. You have just under that. So you use one dollar, one dime, and 4.99999 pennies (int rounds it down to four).
The easiest way to fix it is to have the user give you an integer number of cents so that you can work in cents the entire time, or to use the built-in round function to get rid of floating point errors.
You can refer to Is floating point math broken? for a more comprehensive explanation on what is going on but basically when you type 1.05 into your code (or through an eval) it does not store the exact value you might expect:
>>> (1.05).as_integer_ratio()
(4728779608739021, 4503599627370496)
If you want the computer to store the exact decimal representation of the number you can simply use decimal.Decimal for the intermediate step:
n1 = decimal.Decimal(input("Enter a monetary amount: "))
n1 = int(n1 * 100) #now you won't get rounding issues
alternately you can parse the number entered yourself to remove the decimal and skip the math required to compensate all togther:
def dollar_to_cent(s):
n,_,end = s.partition(".")
if not all(i=="0" for i in end[2:]):
raise ValueError("can only have up to two digits after decimal.")
return int("{}{:0<2}".format(n,end[:2]))
>>> dollar_to_cent("1")
100
>>> dollar_to_cent("2.")
200
>>> dollar_to_cent("2.3")
230
>>> dollar_to_cent("2.05")
205
>>> dollar_to_cent("2.050000")
205
>>> dollar_to_cent("2.001")
Traceback (most recent call last):
...
ValueError: can only have up to two digits after decimal.
Looks like a typo: nickels vs nickles
Edit: now that you've fixed the typo, it looks like it's definitely a rounding issue. Since you're converting from dollars to a whole number of cents, try turning it into an integer before doing any operations.
Change your n1 = n1 * 100 line to n1 = int(round(n1 * 100)). I tried this out on my computer and it seemed to work.
It is best to work with cents all the way for these kind of problems. Try to make 105 cents (integer) instead of 1.05 times 100. You can avoid rounding all together. Further, since you care about "remainder", use modulo operator instead of division.
I'd solve it like this:
cents = 115
remainder = cents%25
nickels = (cents - remainder)/25
cents = remainder
remainder = cents%10
dimes = (cents - remainder)/10
...
and so on.
However, probably not the question you asked but in general cases this problem is NP-hard, and further depending on the coin denominations some change is not makeable.

Convert cents to quarters, nickels, dimes and pennies using Python

I'm using Python, and I am trying to convert a certain amount of money in cents to its equivalent in quarters, nickels, dimes and pennies.
This is what I have so far, but I see the problem is that I don't know how to take the remainder from the quarters and break it down into dimes, nickels and pennies. I'm new to this and just having a hard time. I'm not asking for someone to solve the problem, just point out what I did wrong (and maybe what I need to do to fix it).
# Convert some money to an appropriate collection of cents
penny = 1
nickel = 5
dime = 10
quarter = 25
quarters = 0
dimes = 0
nickels = 0
pennys = 0
cents = int(input("Please enter an amount of money you have in cents: "))
if cents >= 25:
quarters = cents / quarter
cents % quarter
if cents >= 10:
dimes = cents/dime
cents % dime
if cents >= 5:
nickels = cents /nickel
cents % nickel
if cents > 0:
pennys = cents / penny
cents = 0
print ("The coins are: quarters", quarters,\
",dimes", dimes, ",nickels", nickels, ", and pennys.", pennys)
Using divmod, it's just three lines:
quarters, cents = divmod(cents, 25)
dimes, cents = divmod(cents, 10)
nickels, pennies = divmod(cents, 5)
There are two operations that you need here: integer division and modulo.
Integer division A / B asks a simple question: How many times will B fit into A cleanly (without having to break B into decimal pieces)? 2 fits into 8 cleanly 4 times. 2 fits into 9 cleanly 4 times as well.
Modulo A % B asks the same question but gives the flip-side of the answer: Given that A goes into B cleanly some number of times, what's left over? 2 goes into 8 cleanly 4 times with nothing left over, so 2 % 8 is 0. 2 goes into 9 cleanly 4 times but 1 is left over, so 2 % 9 is 1.
I'll give you another example, and let you make the transition from that to your problem. Let's say I'm given a number of seconds, and I need to convert it to days, hours, minutes and seconds.
total_seconds = 345169
# Specify conversion between seconds and minutes, hours and days
seconds_per_minute = 60
seconds_per_hour = 3600 # (60 * 60)
seconds_per_day = 86400 # (3600 * 24)
# First, we pull out the day-sized chunks of seconds from the total
# number of seconds
days = total_seconds / seconds_per_day
# days = total_seconds // seconds_per_day # Python3
# Then we use the modulo (or remainder) operation to get the number of
# seconds left over after removing the day-sized chunks
seconds_left_over = total_seconds % seconds_per_day
# Next we pull out the hour-sized chunks of seconds from the number of
# seconds left over from removing the day-sized chunks
hours = seconds_left_over / seconds_per_hour
# hours = seconds // seconds_per_hour # Python3
# Use modulo to find out how many seconds are left after pulling out
# hours
seconds_left_over = seconds_left_over % seconds_per_hour
# Pull out the minute-sized chunks
minutes = seconds_left_over / seconds_per_minute
# minutes = seconds_left_over // seconds_per_minute # Python3
# Find out how many seconds are left
seconds_left_over = seconds_left_over % seconds_per_minute
# Because we've removed all the days, hours and minutes, all we have
# left over are seconds
seconds = seconds_left_over
Was struggling with this yesterday evening. True, you need division and modulo. Not the most Pythonic way, but it works for any amount, when you restrict the amount of dollars you can input into the vending machine to $5.00. This question has been asked around and has been continually ignored. Maybe because it is homeworksque... Anyway....
def vending_machine_change():
cost = float(input("Enter cost of item: "))
change= 5.00-cost
dollars = int(change)
quarters_change= float("%.2f" % ((change-dollars)))
quarters =int(quarters_change/0.25)
dime_change= float("%.2f" % (quarters_change%0.25))
dimes=int(dime_change/0.10)
nickel_change = float("%.2f" % (dime_change%0.10))
nickels= int(nickel_change/0.05)
pennys = int(nickel_change*100)
print("Change amount: " + str((dollars)) + ' Dollars, ' + str((quarters)) + ' Quarters, '+ str((dimes)) + ' Dimes, '+ str((nickels)) + ' Nickels, '+ str((pennys)) + ' Pennies' )
pass

Difference between Round and Int function in PYTHON

Hi Can you please refer to below sample code and let me know what is the exact difference between round and int functions
OUTPUT:
12 dollars and 0 cents
12 dollars and 1.0 cents
# code is to convert xx.yy to xx dollars and yy cents **
val = 12.01
dollars = int(val) #Integer value to know how many Dollars
cents = int(100 * (val - dollars)) #Integer value to know how many cents
print str(dollars) + " dollars and " + str(cents) + " cents"
If i write the same code with round function, I am getting right answer
val = 12.01
dollars = int(val) #Integer value to know how many Dollars
cents = round(100 * (val - dollars)) #Integer value to know how many cents
print str(dollars) + " dollars and " + str(cents) + " cents"
Not sure why it is shown as 0 cents when i use int.
You are using float values, they do not map cleanly to decimal values.
If you try something like:
floatcents = 100 * (val - dollars)
cents = int(floatcents)
print floatcents
print cents
You may well end up with floatcents being something like 0.999999999789 and that, truncated to an integer value, becomes 0 instead of 1.
You may be better off using int((100*val) - (100*dollars)) or simply use an integral value of cents instead of having a float value of dollars.
an integer is a whole number
and a float is a number with decimal points
that's the layman's terms of it
int() gets rid of any decimal points. You should instead use:
cents = float(100 * (val - dollars)) #Integer value to know how many cents
explanation:
The following code treats everything as an integer, so (val - dollars) will give you 0 instead of 0.1 therefore multiplying by 100 will still give you 0.
int(100 * (val - dollars))
Assuming val is the result of some calculation and might be for example
val=12.996
You should actually round the dollar result as well:
dollar = round(val*100)/100
cents = round(val*100)-dollar*100
-> $13 + 0 cents , not $12 + 100 cents...

if/elif/else statement help with money

Updated my new code at the bottom of the page as an answer.
So for my CS 170 class, we have to make a program that has user input for less than $10 and change is returned in the least amount of coins, no bills or 50 cent pieces. For the most part the program does well except when you run into a x.x0
e.g.:
Python 2.7.2 (v2.7.2:8527427914a2, Jun 11 2011, 15:22:34)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
Amount due:
7.80
Amount in return
2.20.
Quaters in return 8.
Dimes in return 0.
Nickels in return 4.
>>>
the program completely skips over the dimes section and straight to nickels providing 4 as a solution when the least amount should be 8 quarters, 2 dimes and end. Also I'm not really skilled in loops too much, but I know this would be possible and a lot shorter code, and cleaning up the code advice would be nice as well. Thanks for any help!
# optional.py
# Calculating the least amount of change in return for a $10 bill.
## amount due
due = input("Amount due:\n ")
## if amount is more than 10, exit program
if due > 10.00:
print "Please enter a number lower then 10.00."
exit()
## if amount is less than 0, exit program
if due < 0:
print "Please enter a number greater than 0.00."
exit()
## subtract amount from 10
else:
change = 10.00 - due
print "Amount in return\n %0.2f." % change
## if amount is 0, no change
if change == 0:
print "No change in return."
## passes expression if previous not met
pass
elif change >= .25:
## setting q, dividing change by .25
q = change / .25
## maaking q an integer
quaters = int(q)
print "Quaters in return %r." % quaters
## subtracting quaters from chane
change = change - (quaters *.25)
if change < .10:
pass
elif change >= .10 <= .24:
d = change * .1
dimes = int(d)
print "Dimes in return %r." % dimes
change = change - (dimes * .1)
if change < .05:
pass
elif change >=.05 <=.09:
n = change / .05
nickels = int(n)
print "Nickels in return %r." % nickels
change = change - (nickels * .05)
if change == .01:
pennies = change / .01
print "Pennies in return %r." % pennies
elif change >=.01 <=.04:
p = change / .01
print "Pennies in return %0.0f." % p
There are a few changes you could make to clean up this code, and one of them might fix your problem. First, pass does absolutely nothing. It is usually used as a placeholder for a loop or function that will be filled in later. Also, the conditions of your elif statements are mutually exclusive with the if statements they follow, so
if change == 0:
print "No change in return."
## passes expression if previous not met
pass
elif change >= .25:
## setting q, dividing change by .25
q = change / .25
## maaking q an integer
quaters = int(q)
print "Quaters in return %r." % quaters
## subtracting quaters from chane
change = change - (quaters *.25)
can be rewritten as
if change >= .25:
## setting q, dividing change by .25
q = change / .25
## making q an integer
quaters = int(q)
print "Quaters in return %r." % quaters
## subtracting quaters from change
change = change - (quaters *.25)
for each if/elif statement. Also, in the statement
if change >=.01 <=.04:
you are testing whether
change >= .01 and .01 <= .04
To make it do what you want, the statement should be rewritten as
if .01 <= change <= .04
In addition, you are using floating point numbers, which often lead to rounding errors. To avoid these errors, I would suggest either representing your money as an integer number of cents and multiply all of the numbers in your problem by 100 or use something with fixed point numbers like python's decimal module.
This is not doing what you expect:
elif change >= .10 <= .24:
It looks like you intend something like:
elif change >= .10 and change <= .24:
or Python also supports:
elif .10 <= change <= .24:
However, you will next run into floating point rounding problems of various kinds. I suggest you first convert the input number to an integer number of cents, and perform all your calculations in cents. Avoid floating point numbers when dealing with money.
So I got it worked out in a better format with cleaner print code. Thanks for the help guys!
If anyone wants to know the difference between the 2 codes, it's getting it out of floating point like the others suggested and converting what is needed to integers, multiplying the integers by the specific amount, say a quarter, and then subtracting int * coin/bill from the change. Worked out well. I tried experimenting with a for statement, but that didn't turn out too well since I don't know a lot about it yet either. Until next time...
Again thanks guys!
Here's the finished code for anyone wondering about it:
import sys
due = input("Please enter the amount due on the item(s):\n ")
# if over $10, exit
if due > 10:
print "Please enter an amount lower then 10."
sys.exit(1)
## if under/equal 0, exit
if due <= 0:
print "Please enter an amount greater than 0."
sys.exit(2)
## 10 - due = change, converts change into cents by * by 100 (100 pennies per dollar)
else :
change = 1000 - (due * 100)
## if change is 0, done
if change == 0:
print "No change in return!"
## if not 0 makes change2 for amount in return
else:
change2 = change / 100
print "Amount in return:\n $%.2f." % change2
## if change > 500, subract 500 and you get 1 $5 bill
if 500.0 <= change:
bill_5 = change / 500
b5 = int(bill_5)
change = change - 500
## if change is over 100, change divided by 100 and subtracted from change for quaters
if 100.0 <= change:
dollars = change / 100
dollar = int(dollars)
change = change - (dollar * 100)
if 25 <= change < 100:
quaters = change / 25
quater = int(quaters)
change = change - (quater * 25)
if 10 <= change <= 24:
dimes = change / 10
dime = int(dimes)
change = change - (dime * 10)
if 5 <= change < 10:
nickels = change / 5
nickel = int(nickels)
change = change - (nickel * 5)
if 0 < change < 5:
pennies = change / 1
penny = int(pennies)
change = change - (penny * 1)
print "Change in return:\n $5:%i\n $1:%i\n Quaters:%i\n Dimes:%i\n Nickels:%i\n Pennies:%i " % (
b5, dollar, quater, dime, nickel, penny )
if 0 >= change:
print "Done!"

Categories

Resources