** Controlling the format of printed variables
:PROPERTIES:
:categories: python
:date: 2013/01/21 09:00:00
:updated: 2013/02/27 14:50:18
:END:
This was first worked out in this [[http://matlab.cheme.cmu.edu/2011/10/06/sprintfing-to-the-finish/][original Matlab post]].
Often you will want to control the way a variable is printed. You may want to only show a few decimal places, or print in scientific notation, or embed the result in a string. Here are some examples of printing with no control over the format.
#+BEGIN_SRC python
a = 2./3
print a
print 1/3
print 1./3.
print 10.1
print "Avogadro's number is ", 6.022e23,'.'
#+END_SRC
#+RESULTS:
: 0.666666666667
: 0
: 0.333333333333
: 10.1
: Avogadro's number is 6.022e+23 .
There is no control over the number of decimals, or spaces around a printed number.
In python, we use the format function to control how variables are printed. With the format function you use codes like {/n/:format specifier} to indicate that a formatted string should be used. /n/ is the /n^{th}/ argument passed to format, and there are a variety of format specifiers. Here we examine how to format float numbers. The specifier has the general form "w.df" where w is the width of the field, and d is the number of decimals, and f indicates a float number. "1.3f" means to print a float number with 3 decimal places. Here is an example.
#+BEGIN_SRC python
print 'The value of 1/3 to 3 decimal places is {0:1.3f}'.format(1./3.)
#+END_SRC
#+RESULTS:
: The value of 1/3 to 3 decimal places is 0.333
In that example, the 0 in {0:1.3f} refers to the first (and only) argument to the format function. If there is more than one argument, we can refer to them like this:
#+BEGIN_SRC python
print 'Value 0 = {0:1.3f}, value 1 = {1:1.3f}, value 0 = {0:1.3f}'.format(1./3., 1./6.)
#+END_SRC
#+RESULTS:
: Value 0 = 0.333, value 1 = 0.167, value 0 = 0.333
Note you can refer to the same argument more than once, and in arbitrary order within the string.
Suppose you have a list of numbers you want to print out, like this:
#+BEGIN_SRC python
for x in [1./3., 1./6., 1./9.]:
print 'The answer is {0:1.2f}'.format(x)
#+END_SRC
#+RESULTS:
: The answer is 0.33
: The answer is 0.17
: The answer is 0.11
The "g" format specifier is a general format that can be used to indicate a precision, or to indicate significant digits. To print a number with a specific number of significant digits we do this:
#+BEGIN_SRC python
print '{0:1.3g}'.format(1./3.)
print '{0:1.3g}'.format(4./3.)
#+END_SRC
#+RESULTS:
: 0.333
: 1.33
We can also specify plus or minus signs. Compare the next two outputs.
#+BEGIN_SRC python
for x in [-1., 1.]:
print '{0:1.2f}'.format(x)
#+END_SRC
#+RESULTS:
: -1.00
: 1.00
You can see the decimals do not align. That is because there is a minus sign in front of one number. We can specify to show the sign for positive and negative numbers, or to pad positive numbers to leave space for positive numbers.
#+BEGIN_SRC python
for x in [-1., 1.]:
print '{0:+1.2f}'.format(x) # explicit sign
for x in [-1., 1.]:
print '{0: 1.2f}'.format(x) # pad positive numbers
#+END_SRC
#+RESULTS:
: -1.00
: +1.00
: -1.00
: 1.00
We use the "e" or "E" format modifier to specify scientific notation.
#+BEGIN_SRC python
import numpy as np
eps = np.finfo(np.double).eps
print eps
print '{0}'.format(eps)
print '{0:1.2f}'.format(eps)
print '{0:1.2e}'.format(eps) #exponential notation
print '{0:1.2E}'.format(eps) #exponential notation with capital E
#+END_SRC
#+RESULTS:
: 2.22044604925e-16
: 2.22044604925e-16
: 0.00
: 2.22e-16
: 2.2E-16
As a float with 2 decimal places, that very small number is practically equal to 0.
We can even format percentages. Note you do not need to put the % in your string.
#+BEGIN_SRC python
print 'the fraction {0} corresponds to {0:1.0%}'.format(0.78)
#+END_SRC
#+RESULTS:
: the fraction 0.78 corresponds to 78%
There are many other options for formatting strings. See http://docs.python.org/2/library/string.html#formatstrings for a full specification of the options.