# string formatting

Try the Jupyter notebook version.

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