python find the minimum number of coins - python

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.

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)

Mixing keyword and default arguments in python 3.5.1

I'm a newbie and taking an online python class through an online workbook. I can't seem to figure out how to get the output to display like the example shown:
Problem instructions:
Write a function number_of_pennies() that returns the total number of pennies given a number of dollars and (optionally) a number of pennies. Ex: 5 dollars and 6 pennies returns 506.
Here is what I have:
def number_of_pennies(dollars = (),pennies=())
return number_of_pennies
print(number_of_pennies(5, 6)) # Should print 506
print(number_of_pennies(4)) # Should print 400
Thanks to your help I just changed it to this:
def number_of_pennies(dollars = 0,pennies=0):
number_of_pennies= (dollars * 100) + pennies
return number_of_pennies
print(number_of_pennies(5, 6)) # Should print 506
print(number_of_pennies(4)) # Should print 400
Default arguments are used when the caller doesn't supply a value. So, what should be the default? In your case, if the user doesn't supply dollars, zero dollars seems like a reasonable choice. Same with pennies. Since number_of_pennies(4) should be 400 you know that they want dollars to be the first parameter. The remainder is just the math.
number_of_pennies is just the name of the function which would be an odd thing to return. In fact, when you try it you get something like <function number_of_pennies at 0x7ff4e962d488> which means that the function returned its own function object. Instead return the data you calculate... that's much more useful!
>>> def number_of_pennies(dollars=0, pennies=0):
... return dollars * 100 + pennies
...
>>> print(number_of_pennies(5,6))
506
>>> print(number_of_pennies(4))
400
def number_of_pennies(dollars = 0, pennies = 0):
return dollars * 100 + pennies
print(number_of_pennies(int(input()), int(input()))) # Both dollars and pennies
print(number_of_pennies(int(input()))) # Dollars only
def number_of_pennies(n,x=0):
return n*100+x
I did the same workbork. This is what I came up with:
def number_of_pennies(dollars=0, pennies=0):
dollars = dollars * 100
pennies = pennies
total = dollars + pennies
return total
print(number_of_pennies(int(input()), int(input()))) # Both dollars and pennies
print(number_of_pennies(int(input()))) # Dollars only

Python Issue with Loops

I have designed a code which will take a 'number' as an input from the user.
The number will be used to make a...
numerator = (3*number) - 2
and a denominator, which will be denominator = (4*n) + 1.
The code will also allow the user to choose how many times they want this sequence to go on after which the sum of all the fractions will be totaled and displayed.
Here is the Code I have:
l=int(input("How many times do you repeat this sequence?: "))
n=int(input("Enter a base number: "))
n1=n
n2=n
total=0
s = ''
def calculate(l,n,n1,n2,total,s):
for j in range(l):
s += "{}/{} + ".format(3*n1-2, 4*n2+1)
n1=n+n1
n2=n+n2
total=(((n*3)-2)/((4*n)+1))+total
print(s)
print(total)
calculate(l, n, n1, n2, total, s)
Now here are the two errors that I receive when I get the output for this code for example:
How many times do you repeat this sequence?: 2
Enter a base number: 1
1/5 + 4/9 +
0.4
The two Issues:
Since 4/9 is the last fraction, is there a way to get rid of that "+" addition sign at the end, because it just points to a blank space..
The total for the two fractions shows to be 0.4 which is incorrect, the total sum should be 1/5 + 4/9 = 0.2 + 0.44 = 0.64, I am unsure where I went astray when inputting my total sum formula above.
Any suggestions/comments would be appreciated!
A cheap way of removing the + would be to simply cut off the last character in the string: str[:-1].
As far a issue 2 goes, it looks like you want to use n1 and n2 instead of n.
As of now, you're getting 1/5(.2) + 1/5(.2) = .4
Instead of concatening a string like that, collect all the parts in a list and then join the items on the plus sign:
s = []
s.append('{}/{}'.format(1, 5))
s.append('{}/{}'.format(4, 9))
print(' + '.join(s)) # 1/5 + 4/9
I’m not really sure what you are doing but if you want to get the sum of the fractions you print, you should just make sure that you calculate those individual fractions in the same way. So instead of incrementing n1 and n2 first before calculating the sum, calculate the sum in the same way you did for the fraction output and only afterwards change those variables:
s.append("{}/{}".format(3 * n1 - 2, 4 * n2 + 1))
total += (3 * n1 - 2) / (4 * n2 + 1)
n1 += n
n2 += n
I dont know python but you could do the following to correct your logical errors.
to remove the '+' at the end, you can do something like below,
if j = l (implies last fraction)
dont include +
else
include +
While calculating total you are using 'n' value which always remains as your input value
total=(((n*3)-2)/((4*n)+1))+total
Here use n1 or n2
total=(((n1*3)-2)/((4*n2)+1))+total

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

Rounding up with pennies in 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

Categories

Resources