2

I'm trying to limit a number's output to 4 characters (including decimals).

def costEdit(nCost):
    nCost = '%.2f'%(nCost*1.25)
    nCost = nCost * 1.25
    return nCost

I want the nCost to be cut off at 2 decimal places. E.g. if the nCost was 8.364912734, cut it off to 8.36 and edit the nCost variable to be replaced with that. Any Ideas?

Im getting the error:

Traceback (most recent call last):
  File "C:\Python33\My Codes\TextTowns\TextTowns.py", line 59, in <module>
    costEdit(nCost)
  File "C:\Python33\My Codes\TextTowns\TextTowns.py", line 27, in costEdit
    nCost = nCost*1.25
  TypeError: can't multiply sequence by non-int of type 'float'

Im using it as: costEdit(nCost)

HarryCBurn
  • 755
  • 1
  • 8
  • 17
  • 2
    Terminology nitpick: if nCost equals `8.364912734`, it's not an integer. Integers are whole numbers. – Kevin Dec 12 '13 at 20:37
  • Here is a side note. If you get a number bigger than 9.99, you'll run into 5+ characters. Is it more important to limit to 2 decimal places, or to only have 4 characters? Would you rather have `1000` than `1000.01`? – jwarner112 Dec 12 '13 at 20:49
  • Do you want this function to return a string representation of a rounded number, or an actual rounded number? – abarnert Dec 12 '13 at 21:13
  • 1
    This isn't a duplicate of [python limiting floats to two decimal points](http://stackoverflow.com/questions/455612/python-limiting-floats-to-two-decimal-points). That question is about the fact that `13.95` has no exact representation as a `float`, and that Python 2.5 and earlier `repr`-d such values in an unintuitive way. – abarnert Dec 12 '13 at 22:22

4 Answers4

4

The problem you're having is confusion between a number, and a string representation of a number. These are different things.

When you do this:

nCost = '%.2f'%(nCost*1.25)

… you're multiplying your number by 1.25, then replacing it with a string that represents the number up to two decimal points. So, when you do this:

    nCost = nCost * 1.25

… you're trying to multiply a string by 1.25, which makes no sense.


I suspect you didn't want a string here at all; you just wanted to round the number as a number. To do that, use the round function:

nCost = round(nCost*1.25, 2)

Of course as soon as you multiply by 1.25 again, you may "unround" it by another decimal place or two:

>>> nCost = 1.33333
>>> nCost = round(nCost*1.25, 2)
>>> nCost
1.33
>>> nCost = nCost * 1.25
>>> nCost
1.6625

And really, it's almost always a bad idea to round values before doing arithmetic on them; that just multiplies rounding errors unnecessarily. It's better to just keep the highest-precision value around as long as possible, and round at the last possible second—ideally by using %.2f/{:.2f} formatting in the printing/writing-to-disk/etc. stage.


Another thing to keep in mind is that not all real numbers can be represented exactly as floats. So, for example, round(13.4999, 2) is actually 13.949999999999999289457264. A simple repr or str or %f will print this out as 13.95, so you may not notice… but it's still not exactly 13.95.

The best way to solve this problem, and your other problems, is to use the Decimal type instead of the float type. Then you can round the value to exactly 2 decimal places, do math in a 2-decimal-places context, etc.

abarnert
  • 354,177
  • 51
  • 601
  • 671
2

One way to do this would be with the following:

def costEdit(nCost):
    nCost = '%.2f'%(nCost*1.25)
    #nCost = nCost*1.25
    return nCost

Let me break this down for you.

Take the line:

'%.2f'%(nCost*1.25)

And break it down into its components:

(' ( (%) .2f) ')%(nCost*1.25)
  • Everything inside '' is just a normal string.
  • The % is a symbol that means "substitute in later".
  • .2f is a command in Python that truncates 2 places after a decimal.
  • %(nCost*1.25) means "nCost*1.25 is what you put in place of %"

So in order, it does the math of nCost*1.25, puts it inside the string, then cuts off everything else and gives you what is left.

Take note that I've rewritten your costEdit function to accept nCost as an argument. This means that now you can call:

costEdit(nCost)

with any number that you want, and it will do the math.

Also note I've replaced print with return. This means that now, you will have to write:

print costEdit(80)

to get

100

However it now means you can do math with costEdit, such as:

print 4*costEdit(80)

and instead of printing 100 along the way, it will just print

400

Questions? Leave a comment.

Happy coding!

EDIT: Regarding your error,

I think I've reproduced it and understand the problem.

When I type:

costEdit('15')

I get your error.

This is because when you do costEdit('15'), you're entering '15' and not 15. If a value is between '' or "", you're dealing with a value of type string.

In python, you can't multiply a float (type of number) with a string. That's what this is complaining about.

To remedy the situation, just remove the quotes. Then you're entering a number of type float or int (integer), both of which can be multiplied by a float (the value 1.25 inside costEdit()).

I hope this solves your issue-- I have to get off the PC for the night. If it doesn't help, leave a comment and I'll return tomorrow.

Otherwise, I'm glad I could help and remember to select a best answer on your question, so those who helped can get their precious precious pointssssss

jwarner112
  • 1,492
  • 2
  • 14
  • 29
  • Edit your original question-- add to the end. Plug in the block of code you're currently using to get this error, followed by this error itself. If I can't help you, someone else will. – jwarner112 Dec 12 '13 at 21:00
  • It's fine when it's in this context. Can you go back and include what it is that you're inputting? As in the line: `costEdit(x)`? – jwarner112 Dec 12 '13 at 21:08
  • @user3092506 Tried to fix your problem in my updated post. Give it a read. Hope I helped! – jwarner112 Dec 12 '13 at 21:28
0

Python 2.6 or higher, use format():

print('{0:.3g}'.format(nCost))
Steve Prentice
  • 23,230
  • 11
  • 54
  • 55
  • '{0:.2f}'.format(nCost) so 2f not 2g – jdennison Dec 12 '13 at 20:37
  • Could you also talk about how to get this value as a numerical type? that would satisfy the "edit the nCost variable to be replaced with that" portion of the question. – Kevin Dec 12 '13 at 20:42
0

You can use special format code for floats

print('{0:.2f}'.format(nCost))

Change the 2f to 4f to increase the number of digits

Documentation(http://docs.python.org/2/library/stdtypes.html#string-formatting)

jdennison
  • 2,000
  • 2
  • 15
  • 22
  • This doesn't seem to be working, any ideas? Code now: `def costEdit(): global nCost nCost = nCost * 1.25 print('{0:.2g}'.format(nCost))` – HarryCBurn Dec 12 '13 at 20:49
  • use 2f not 2g. that should work. so '{0:.2f}' not '{0:.2g}' – jdennison Dec 12 '13 at 20:51
  • This doesn't really do anything different from the `%.2f'%` in his existing code. And it doesn't solve his problem (trying to multiply the formatted string by 1.25, instead of multiplying the number and then formatting it). – abarnert Dec 12 '13 at 21:12