How to convert to Python 3 - python

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

Related

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

formatting in python 2.7.12

I am a beginner python programmer and I have learnt the format specifiers in the print statement.so, %3f will mean that the width of the floating point number should be 3.
But,in the following code,output is not like that
import math
print "%3f"%(math.pi)
this code should output 3.1 because we specified the width as 3.
but the output is 3.141593.
My questions:
1.Does specifying only width work for integers and not for floating point numbers?
2.is it must to specify both width and precision while formatting floating point numbers?
Specifying only width works also for floating point numbers. The thing is that the width includes decimal points too. For example, doing:
"%10f" % math.pi # ' 3.141593'
As you can see, the string is 10 characters long. Another thing to take into account here is that by default, python will output 6 decimal points, so doing "%3f" is the same as "%3.6f".
>>> "%3f" % math.pi
'3.141593'
>>> "%3.6f" % math.pi
'3.141593'
>>>
That's why you are not getting your expected output '3.1'. To get that, and knowing the previous concepts you should specify:
"%3.1f" % math.pi
Or just:
"%.1f" % math.pi
I'd just specify the part after the decimal point like this:
>>> print "%.1f"%(math.pi)
3.1
You should also try the arguably better .format method. It offers much more clarity and functionality while formatting. This is will do what you need,
'{:.1f}'.format(math.pi)
You can also specify padding width,if needed, easily like,
'{:6.1f}'.format(math.pi)
You can read up more here https://pyformat.info/
>>> print "%3f" % x
99999.454540
>>> print "%.3f" % x
99999.455
Well the first one in %30.1%f specifies the length of the string/
>>> print "%30.1f" % x
99999.5
Look at this!
>>> print "%.1f" % x
99999.5
See the last one? It has it rounded off. If you don't want to round off then use decimal instead of float.
import math
from decimal import *
getcontext().prec=6
value = Decimal('999.559987').quantize(Decimal('.01'), rounding=ROUND_DOWN)
print str(value)
print '%.2f' % 999.559987
output:
999.55
999.56
%5.3f here is two part. one is integer '5' part and another is floating part '.3'. integer part print the number of space before printing the number. And floating part specify how many number will print after floating point. And there are given so many example previous answer.

Old style python formatting issues

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

Truncation in python

How can we truncate (not round) the cube root of a given number after the 10th decimal place in python?
For Example:
If number is 8 the required output is 2.0000000000 and for 33076161 it is 321.0000000000
Scale - truncate - unscale:
n = 10.0
cube_root = 1e-10 * int(1e10 * n**(1.0/3.0))
You should only do such truncations (unless you have a serious reason otherwise) while printing out results. There is no exact binary representation in floating point format, for a whole host of everyday decimal values:
print 33076161**(1.0/3.0)
A calculator gives you a different answer than Python gives you. Even Windows calculator does a passable job on cuberoot(33076161), whereas the answer given by python will be minutely incorrect unless you use rounding.
So, the question you ask is fundamentally unanswerable since it assumes capabilities that do not exist in floating point math.
Wrong Answer #1: This actually rounds instead of truncating, but for the cases you specified, it provides the correct output, probably due to rounding compensating for the inherent floating point precision problem you will hit in case #2:
print "%3.10f" % 10**(1.0/3.0)
Wrong Answer #2: But you could truncate (as a string) an 11-digit rounded value, which, as has been pointed out to me, would fail for values very near rollover, and in other strange ways, so DON'T do this:
print ("%3.11f" % 10**(1.0/3.0))[:-1]
Reasonably Close Answer #3: I wrote a little function that is for display only:
import math
def str_truncate(f,d):
s = f*(10.0**(d))
str = `math.trunc(s)`.rstrip('L')
n = len(str)-d
w = str[0:n]
if w=='':
w='0'
ad =str[n:d+n]
return w+'.'+ad
d = 8**(1.0/3.0)
t=str_truncate(d,10)
print 'case 1',t
d = 33076161**(1.0/3.0)
t=str_truncate(d,10)
print 'case 2',t
d = 10000**(1.0/3.0)
t=str_truncate(d,10)
print 'case 3',t
d = 0.1**(1.0/3.0)
t=str_truncate(d,10)
print 'case 4',t
Note that Python fails to perform exactly as per your expectations in case #2 due to your friendly neighborhood floating point precision being non-infinite.
You should maybe know about this document too:
What Every Computer Scientist Should Know About Floating Point
And you might be interested to know that Python has add-ons that provide arbitary precision features that will allow you to calculate the cube root of something to any number of decimals you might want. Using packages like mpmath, you can free yourself from the accuracy limitations of conventional floating point math, but at a considerable cost in performance (speed).
It is interesting to me that the built-in decimal unit does not solve this problem, since 1/3 is a rational (repeating) but non-terminating number in decimal, thus it can't be accurately represented either in decimal notation, nor floating point:
import decimal
third = decimal.Decimal(1)/decimal.Decimal(3)
print decimal.Decimal(33076161)**third # cuberoot using decimal
output:
320.9999999999999999999999998
Update: Sven provided this cool use of Logs which works for this particular case, it outputs the desired 321 value, instead of 320.99999...: Nifty. I love Log(). However this works for 321 cubed, but fails in the case of 320 cubed:
exp(log(33076161)/3)
It seems that fractions doesn't solve this problem, but I wish it did:
import fractions
third = fractions.Fraction(1,3)
def cuberoot(n):
return n ** third
print '%.14f'%cuberoot(33076161)
num = 17**(1.0/3.0)
num = int(num * 100000000000)/100000000000.0
print "%.10f" % num
What about this code .. I have created it for my personal use. although it is so simple, it is working well.
def truncation_machine(original,edge):
'''
Function of the function :) :
it performs truncation operation on long decimal numbers.
Input:
a) the number that needs to undergo truncation.
b) the no. of decimals that we want to KEEP.
Output:
A clean truncated number.
Example: original=1.123456789
edge=4
output=1.1234
'''
import math
g=original*(10**edge)
h=math.trunc(g)
T=h/(10**edge)
print('The original number ('+str(original)+') underwent a '+str(edge)+'-digit truncation to be in the form: '+str(T))
return T

Categories

Resources