Old style python formatting issues - python

I looking to display numeric data right justified with a forced sign and spaces for the mantissa such that the decimals all align for each column. The new format specifier uses ">" to align, but I'm unable to get something working with the "c style" format.
For example I'm using:
'%+7.2f \n' % (data)
How do I get the alignment? Is this possible with this old style formatting? I'm looking to get the decimal places all aligned up...seems a silly question, but can't seem to get anything other using the .format command.

That will work, you just have to remember that the first number (the 7 in your example) is the total width of the column including all digits before and after the decimal place and the decimal place and the leading +.
>>> for n in (0.12345, 12345.6, 123):
... print '%+9.2f' % (n)
+0.12
+12345.60
+123.00
>>>

Related

How to convert to Python 3

I am in the process of converting Python 2 code into Python 3. Currently I am facing difficulty in converting the following code to Python 3. Please help.
print 'Data cache hit ratio: %4.2f%%' % ratio
Also, what %4.2f%% means?
Tried to rewrite the code with format().
Just put parens around the parameters.
print('Data cache hit ratio: %4.2f%%' % ratio)
There are fancier ways of doing formatting in Python 3, but that will work.
%4.2f says "display this floating point number in a 4-character field with a decimal point and two places after. So, like "9.99". %% says "display a percent sign". The formatting here is straight from the C printf function.
f denotes the fixed point notation. The value that precedes with % (4.2) is for denoting the width (4) and the precision (2) of the number respectively.
You can use either .format or f string
print("Floating point {0:4.2f}".format(ratio))
print(f' Floating point {ratio:4.2f}')
Here 4 is the total width of the field being printed, lefted-padded by spaces. 2 is the number of digits after the decimal point. You can read more about it here https://docs.python.org/3/library/string.html#format-specification-mini-language

Python decimal.Decimal producing result in scientific notation

I'm dividing a very long into much smaller number. Both are of type decimal.Decimal().
The result is coming out in scientific notation. How do I stop this? I need to print the number in full.
>>> decimal.getcontext().prec
50
>>> val
Decimal('1000000000000000000000000')
>>> units
Decimal('1500000000')
>>> units / val
Decimal('1.5E-15')
The precision is kept internally - you just have to explicitly call for the number of decimal places you want at the point you are exporting your decimal value to a string.
So, if you are going a print, or inserting the value in an HTML template, the first step is to use the string format method (or f-strings), to ensure the number is encompassed:
In [29]: print(f"{units/val:.50f}")
0.00000000000000150000000000000000000000000000000000
Unfortunatelly, the string-format minilanguage has no way to eliminate by itself the redundant zeroes on the right hand side. (the left side can be padded with "0", " ", custom characters, whatever one want, but all the precision after the decimal separator is converted to trailing 0s).
Since finding the least significant non-zero digit is complicated - otherwiser we could use a parameter extracted from the number instead of the "50" for precision in the format expression, the simpler thing is to remove those zeros after formatting take place, with the string .rstrip method:
In [30]: print(f"{units/val:.50f}".rstrip("0"))
0.0000000000000015
In short: this seems to be the only way to go: in all interface points, where the number is leaving the core to an output where it is representd as a string, you format it with an excess of precision with the fixed point notation, and strip out the tailing zeros with f-string:
return template.render(number=f"{number:.50f}".rstrip("0"), ...)
Render the decimal into a formatted string with a float type-indicator {:,f}, and it will display just the right number of digits to express the whole number, regardless of whether it is a very large integer or a very large decimal.
>>> val
Decimal('1000000000000000000000000')
>>> units
Decimal('1500000000')
>>> "{:,f}".format(units / val)
'0.0000000000000015'
# very large decimal integer, formatted as float-type string, appears without any decimal places at all when it has none! Nice!
>>> "{:,f}".format(units * val)
'1,500,000,000,000,000,000,000,000,000,000,000'
You don't need to specify the decimal places. It will display only as many as required to express the number, omitting that trail of useless zeros that appear after the final decimal digit when the decimal is shorter than a fixed format width. And you don't get any decimal places if the number has no fraction part.
Very large numbers are therefore accommodated without having to second guess how large they will be. And you don't have to second guess whether they will be have decimal places either.
Any specified thousands separator {:,f} will likewise only have effect if it turns out that the number is a large integer instead of a long decimal.
Proviso
Decimal(), however, has this idea of significant places, by which it will add trailing zeros if it thinks you want them.
The idea is that it intelligently handles situations where you might be dealing with currency digits such as £ 10.15. To use the example from the documentation:
>>> decimal.Decimal('1.30') + decimal.Decimal('1.20')
Decimal('2.50')
It makes no difference if you format the Decimal() - you still get the trailing zero if the Decimal() deems it to be significant:
>>> "{:,f}".format( decimal.Decimal('1.30') + decimal.Decimal('1.20'))
'2.50'
The same thing happens (perhaps for some good reason?) when you treat thousands and fractions together:
>>> decimal.Decimal(2500) * decimal.Decimal('0.001')
Decimal('2.500')
Remove significant trailing zeros with the Decimal().normalize() method:
>>> (2500 * decimal.Decimal('0.001')).normalize()
Decimal('2.5')

How to dynamically format string representation of float number in python?

Hi I would like to dynamically adjust the displayed decimal places of a string representation of a floating point number, but i couldn't find any information on how to do it.
E.g:
precision = 8
n = 7.12345678911
str_n = '{0:.{precision}}'.format(n)
print(str_n) should display -> 7.12345678
But instead i'm getting a "KeyError". What am i missing?
You need to specify where precision in your format string comes from:
precision = 8
n = 7.12345678911
print('{0:.{precision}}'.format(n, precision=precision))
The first time, you specified which argument you'd like to be the number using an index ({0}), so the formatting function knows where to get the argument from, but when you specify a placeholder by some key, you have to explicitly specify that key.
It's a little unusual to mix these two systems, i'd recommend staying with one:
print('{number:.{precision}}'.format(number=n, precision=precision)) # most readable
print('{0:.{1}}'.format(n, precision))
print('{:.{}}'.format(n, precision)) # automatic indexing, least obvious
It is notable that these precision values will include the numbers before the point, so
>>> f"{123.45:.3}"
'1.23e+02'
will give drop drop the decimals and only give the first three digits of the number.
Instead, the f can be supplied to the type of the format (See the documentation) to get fixed-point formatting with precision decimal digits.
print('{number:.{precision}f}'.format(number=n, precision=precision)) # most readable
print('{0:.{1}f}'.format(n, precision))
print('{:.{}f}'.format(n, precision)) # automatic indexing, least obvious
In addition to #Talon, for those interested in f-strings, this also works.
precision = 8
n = 7.12345678911
print(f'{n:.{precision}f}')

Padding Numbers and Truncating them in Python

Im currently writing a program in python and i need to be able to truncate the number after 2 decimal places and align it in a table. However, i am unsure how to truncate AND pad my output. Here is the code i want to alter that currently has truncation.
print(month_count,'\t','\t',monthly_payment,'\t','\t',"%.2f" % '%d' % interest_amount,'\t','\t',"%.2f" % loan)
You might want to use .format() for both truncation and alignment:
In [6]: '{:>10.2f}'.format(1000.00001)
Out[6]: ' 1000.00'
>10 part means right adjusted with total of 10 characters.
.2f means keep only 2 decimal places.
See https://pyformat.info/ for more

Aligning Floats to decimal points in Python 2.7 using the format() mini-language

I want to print lines so that the decimal points of the numbers align. Currently, it prints like shown below:
ydisp 0.176
xdisp -0.509
and what I want is something like this
ydisp 0.176
xdisp -0.509
The code that I am using is
print "{:{width}} {}".format(items,float_dict[items], width=12)
but I am a little bit lost now, I found the following section in the Python 2.7 manual under the format Mini Language
"Preceding the width field by a zero ('0') character enables sign-aware zero-padding for numeric types. This is equivalent to a fill character of '0' with an alignment type of '='."
I cannot really get it to work with this '0' character. It would be nice if someone could give me a hint here.
Note: the dictionary keys are type string, and the values are type float.
Use ' ' as the sign modifier to include a space for the sign:
>>> '{:20} {: }'.format('ydisp', 0.176)
'ydisp 0.176'
>>> '{:20} {: }'.format('xdisp', -0.509)
'xdisp -0.509'
Note the space after the : colon. This causes positive numbers to be padded with a space on the left, negative numbers display a - instead.

Categories

Resources