I am trying to put comma's on a number without striping any numbers after the decimal point.
number
12018093.1000
results
12,018,093.10
I tried this code but it strips away the last 0 which I don't know why.
rps_amount_f = ("{:,}".format(float(rps_amount_f)))
I'm not sure why the zeros are stripped away in your example, although this may be a solution using an f-string:
rps_amount_f = 12018093.1
rps_amount_f_str = f"{rps_amount_f:,.10f}"
Here '10' before the f is the decimal precision you want to have in the string, i.e. 10 decimals in this case.
You said that you only want one zero so really isn't the solution just to add a 0 to the end of the string? Anyway here's my solution:
if("." in str(rps_amount_f)):
rps_amount_f = ("{:,}".format(float(rps_amount_f)) + "0")
else:
rps_amount_f = ("{:,}".format(float(rps_amount_f)))
If you want two decimal places you just get rid of the if statement and round it.
print("{:,.4f}".format(float(rps_amount_f))) # 12,018,093.1000
https://docs.python.org/3/library/string.html#format-specification-mini-language
Related
For a coding exercise I'm working on, I'm trying to compare two numbers and choose the one that has the larger number of significant digits.
For example: compare 2.37e+07 and 2.38279e+07, select 2.38279e+07 because it has more significant digits.
I don't know how to implement this in Python. I considered counting the length of each number using len(str(NUMBER)), but this method returns "10" for both of the numbers above because it doesn't differentiate between zero and non-zero digits.
How can I compare the number of significant digits in Python?
A quick and dirty approach might be len(str(NUMBER).strip('0')) which will trim off any trailing zeros and count the remaining digits.
To discount the decimal point then you'd need len(str(NUMBER).replace('.','').strip('0'))
However you need to bear in mind that in many cases converting a python float to a string can give you some odd behaviour, due to the way floating point numbers are handled.
If you're going to go with doing this textually, you can do the following using regular expression:
import re
l = re.compile(r'(\d*?)(0*)(\.0?)')
>>> l.match(str(2.37e+07)).groups()[0]
'237'
Could try an algorithm like this:
sf1 = "2.3723805"
addsf1 = 0
decimal = False
for num in sf1:
if decimal == True:
addsf1 = addsf1 + int(num)
if num == ".":
decimal = True
print(addsf1)
This would check for every letter in the significant number, if you convert it to a string, that is. It will then iterate over every letter until it reaches the decimal part and then it will add the numbers together. You can do this to the other significant figure which can be used to compare the difference between the two. This would tell which one had the larger added numbers.
Not sure if this is the best solution for your problem.
This is what I have, but I know it is incorrect and I'm not sure what to change
print '0.4066145E-07-0.3677403'.split('E+(\-\d{2})', 1 )
I'm looking to get:
['0.4066145E-07','-0.3677403']
or more generally I just want to split up these numbers.
['######E-##','#########']
Also what if there is an exponent in the second number?
['######E-##','#######E-##']
You can try with:
(?<=E-\d\d)(?=-\d+.)
DEMO
I have what I believe to be a simple question. I have the following code and the output is not what I expect:
import socket
import time
r=031508.78
h=373309.9
z=0
mes='"TSRA %s %s %s\r\n"'%(r,h,z)
print mes
My problem is that r prints as '31508.78' and I want '031508.78'. How I get preserve the leading zero?
The 0 in front of the number is not important for python, because numbers have no leading 0s. You can use:
print '%09.2f'%r
I prefer the new string format mini language. I find it more intuitive.
r = 31508.78
h = 373309.9
z = 0
print '"TSRA {0: 011.3f} {1: 011.3f} {2}"\r\n'.format(r, h, z)
print '{0: 011.3f}\n{1: 011.3f}\n{2: 011.3f}'.format(r, h, z)
{0: 011.3f} 0: indicates the first item (r). 011 tells the formatter that there will be 11 characters including the decimal point and a place holder for a negative sign. By placing a 0 in front the formatter will pad the space with leading zeros. Finally, .3f indicates the precision and a fixed number of places after the decimal point.
Yields:
"TSRA 031508.780 373309.900 0"
031508.780
373309.900
000000.000
I don't think there is any way to store a number with a leading zero in python.
This leaves you with two ways:
1) Make r a string i.e. r="031408.78"
I think this is the best method for you as you can do all the arithmetic you want to do (using the implicit typecasting of python) and see the number appended with a 0 wherever you use it.
2) If you simply want to print the number with leading zeros consider using this
print "%09.2f' % r #for this you need the length of the number
For Python, there is no difference in the following things:
31508.78
031508.78
0000000031508.78
31508.7800000000000
0000000000000031508.7800000000000
Those are all valid representations of the exact same number, which is canonically represented by 31508.78, which is essentially just a convention. Different representations are possible too, and actually, the number is represented in a way that’s described by the IEEE-754 standard.
So, when you want that leading zero, you have to tell Python explicitely to put it there because it simply doesn’t know about it. You just used one of many valid representations to specify that one number which default string representation does not include leading zeroes.
The best way to do this is using string formatting, which comes in two flavors. The old style flavor, using the % operator, and the newer str.format function:
>>> '%09.2f' % 31508.78
'031508.78'
>>> '{:09.2f}'.format(31508.78)
'031508.78'
Or, if you don’t actually want a number, you could also just specify the number as a string to begin with, which of course keeps the leading zero.
I want to generate numbers from 00000 to 99999.
with
number=randint(0,99999)
I only generate values without leading zero's, of course, a 23 instead of a 00023.
Is there a trick to generate always 5 digit-values in the sense of %05d or do I really need to play a python-string-trick to fill the missing 0s at front in case len() < 5?
Thanks for reading and helping,
B
You will have to do a python-string-trick since an integer, per se, does not have leading zeroes
number="%05d" % randint(0,99999)
The numbers generated by randint are integers. Integers are integers and will be printed without leading zeroes.
If you want a string representation, which can have leading zeroes, try:
str(randint(0, 99999)).rjust(5, "0")
Alternatively, str(randint(0, 99999)).zfill(5), which provides slightly better performance than string formatting (20%) and str.rjust (1%).
randint generates integers. Those are simple numbers without any inherent visual representation. The leading zeros would only be visible if you create strings from those numbers (and thus another representation).
Thus, you you have to use a strung function to have leading zeros (and have to deal with those strings later on). E.g. it's not possible to do any calculations afterwards. To create these strings you can do something like
number = "%05d" % random.randint(0,99999)
The gist of all that is that an integer is not the same as a string, even if they look similar.
>>> '12345' == 12345
False
For python, you're generating a bunch of numbers, only when you print it / display it is it converted to string and thus, it can have padding.
You can as well store your number as a formatted string:
number="%05d" % random.randint(0,9999)
I have two sets of data that I am reading via nested for loops in Python. I need to match lines of the two different text files using a common number (time). In the two files, time is written differently (ex. 21:53:28.339 vs. 121082008.3399). I only need the last four digits of the times to match them up, for example from 21:53:28.339, I only need '8.339'. For the most part, indexing the number as a string works just fine (ex: timeList[nid][7:]), except for situations such as the numbers listed above, where python rounds .3399 to .34.
Is there a way for me to keep the numbers in float form and to select unrounded digits from the data?
Thanks!
edit - using Decimal exclusively - with full example
import decimal
def simplify(text):
# might be a : separated value
text = text.split(':')[-1]
# turn into decimal
number = decimal.Decimal(text)
# remove everything but the ones place and forwards
number = number - (number/10).quantize(1, rounding=decimal.ROUND_FLOOR) * 10
# truncate to the thousandths
return number.quantize(decimal.Decimal('.001'), rounding=decimal.ROUND_FLOOR)
a = '121082008.3399'
b = '21:53:28.339'
assert simplify(a) == simplify(b)
print simplify(a), '=', simplify(b)
Scott if you compare the numbers using strings then you don't need any floats and there will be no 'rounding' going on.
'8.339' == '8.339'
or, if you have
a = '8.3399'
b = '8.339'
then
a[:-1] == b
however if you do decide to work with them as 'numbers', then as Ignacio pointed out, you can use decimals.
from decimal import Decimal
number_a = Decimal(a[:-1])
number_b = Decimal(b)
now
number_a == number_b
Hope that helps
It appears from your description that you want to compare using one digit before the decimal point and 3 digits after the decimal point, using truncation instead of rounding. So just do that:
>>> def extract(s):
... i = s.find('.')
... return s[i-1:i+4]
...
>>> map(extract, ['21:53:28.339', '121082008.3399'])
['8.339', '8.339']
>>>
Use decimal.Decimal instead of float.