string formatting

motivation

Adding strings together and converting from ints or floats to strings gets tiresome for anything but simple strings. Additionally, string formatting allows more control over the result, by specifying both width and precision.

From the example we did in class (the times table), if you have three variables:

num = 6
factor = 7
answer = num*factor

Using string concatenation, the print statement looks like this:

print(str(num) + " x " + str(factor) + " = " + str(answer))

Using string formatting, we avoid all of the str() calls:

  print("%d x %d = %d" % (num,factor,answer))

And if the width of the integers changes (double or triple-digits), we can use the width specification to make everything line up! Without specifying the width, our times table looks like this:

6 x 1 = 6
6 x 2 = 12
6 x 3 = 18
6 x 4 = 24
6 x 5 = 30
6 x 6 = 36
6 x 7 = 42
6 x 8 = 48
6 x 9 = 54
6 x 10 = 60
6 x 11 = 66
6 x 12 = 72

Notice the 54 and the 60 don't line up, because the 9 and the 10 have a different number of digits.

Using a width of two:

print("%2d x %2d = %2d" % (num,factor,answer))

makes the numbers in the table line up (all single-digit numbers are padded with one space):

 6 x  1 =  6
 6 x  2 = 12
 6 x  3 = 18
 6 x  4 = 24
 6 x  5 = 30
 6 x  6 = 36
 6 x  7 = 42
 6 x  8 = 48
 6 x  9 = 54
 6 x 10 = 60
 6 x 11 = 66
 6 x 12 = 72

syntax

There are three format-specifiers we normally use:

%f for floats
%s for strings
%d for (decimal) integers (I think %i also works for ints)

Each has an optional width, so, for example, you could print out 8-character usernames with %8s, padding the usernames that have less than 8 characters (like jknerr1) with spaces.

Floats have an additional precision specifier, so %7.2f means a width of 7 (including the decimal point), with 2 digits of precision (after the decimal).

examples

Making usernames line up:

>>> unames = ["ewu1","jtaylor5","dpike1","craty1","wchou1"]
>>> for name in unames:
...   print("%8s" % (name))
... 
    ewu1
jtaylor5
  dpike1
  craty1
  wchou1

Making numbers line up, with 2 digits of precision:

>>> nums = [3.14159, 145.7, 2, 2000, 2.1234567]
>>> for num in nums:
...   print("Cost of item: $%7.2f" % (num))
... 
Cost of item: $   3.14
Cost of item: $ 145.70
Cost of item: $   2.00
Cost of item: $2000.00
Cost of item: $   2.12

challenge

Given parallel lists:

players = ["Vladimir Radmanovic","Lou Williams","Lebron James", \
         "Kevin Durant","Kobe Bryant","Kevin Garnett"]
ppg     = [0, 11.5, 30.3, 28.5, 30.0, 19.2]  # points-per-game
games   = [2, 13, 23, 20, 12, 20]            # games played

Display the data such that the names and numbers all line up:

Vladimir Radmanovic averaged  0.0 pts/gm in  2 games
       Lou Williams averaged 11.5 pts/gm in 13 games
       Lebron James averaged 30.3 pts/gm in 23 games
       Kevin Durant averaged 28.5 pts/gm in 20 games
        Kobe Bryant averaged 30.0 pts/gm in 12 games
      Kevin Garnett averaged 19.2 pts/gm in 20 games

CS21 Topics