Formatting with f-strings
You can already print text and numbers side by side. By the end of this lesson you'll put values straight into the middle of a sentence, show birr with two decimals and thousands separators, and line up a receipt in neat columns. The tool is called an f-string, and you'll use it in nearly every program from now on.
Values inside text
Joining text and numbers with + gets clumsy fast. The number has to be turned into
text first with str() (lesson 1.6 explains why), and every space has to be typed
by hand:
total = 450
print("Total: " + str(total) + " birr")In the editor, press Escape then Tab to move on.
Here's another way. Notice the f before the opening quote. What does it print?
What will this print?
Decide before you look. Guessing wrong is how this sticks.
item = "macchiato"
price = 45
print(f"One {item} costs {price} birr.")Python prints
One macchiato costs 45 birr.
Inside an f-string, anything in curly braces {} is replaced by its value. {item} becomes macchiato and {price} becomes 45.
A string with an f in front is an
.
Python replaces each {name} with the value that name refers to, and turns numbers
into text for you. Now leave out one letter. Predict this.
What will this print?
Decide before you look. Guessing wrong is how this sticks.
total = 450
print("Total: {total} birr")Python prints
Total: {total} birrWithout the f, it's an ordinary string, and the braces are just characters. Python doesn't warn you, which is what makes this the most common f-string mistake. If you see braces in your output, look for a missing f.
Add the missing f so it prints Total: 450 birr:
total = 450
print("Total: {total} birr")In the editor, press Escape then Tab to move on.
The braces can hold any expression, not only a name. Python works it out and puts the result in the text.
cups = 3
price = 45
print(f"{cups} cups cost {cups * price} birr.")In the editor, press Escape then Tab to move on.
Formatting numbers
After a value in the braces, a colon starts a : instructions for how to show it. Three are worth knowing now:
:.2fshows exactly two decimal places.:,puts a comma between thousands.:,.2fdoes both, which is how you'll show birr.
What will this print?
Decide before you look. Guessing wrong is how this sticks.
print(f"{1234.5:,.2f}")Python prints
1,234.50
, adds the thousands separator and .2f shows two decimals, adding a zero to make .5 into .50.
price = 1234567.891
print(f"{price:.2f}")
print(f"{price:,}")
print(f"{price:,.2f}")In the editor, press Escape then Tab to move on.
Change price to 2035 / 3, a share of a bill, and run it again. Only the display
is rounded; the value itself doesn't change.
The f in .2f means "show as a decimal number", so it only works on numbers. Text
that happens to contain digits isn't a number:
Lining up columns
A number after < or > sets a width. :<12 fills 12 characters with the value
on the left; :>8 fills 8 with the value on the right. That's how receipts get
straight columns.
item = "Macchiato"
price = 45
print(f"{item:<12}{price:>8.2f}")
item = "Sambusa"
price = 30
print(f"{item:<12}{price:>8.2f}")In the editor, press Escape then Tab to move on.
{price:>8.2f} combines both: 8 characters wide, right-aligned, two decimals. The
prices line up on the decimal point, whatever their size. Try a price of 1250.
One last trick for finding bugs: put = after a name in the braces, and Python shows
the name and its value.
price = 45
total = price * 3
print(f"{price=}")
print(f"{total=}")In the editor, press Escape then Tab to move on.
When a program gives a wrong answer, a few lines like these show you what each name refers to at that moment.
Exercise
A receipt in columns
Print a three-line receipt with the item names in a column 12 characters wide on the left, and prices with two decimals in a column 8 characters wide on the right, exactly like this. Use names for the prices.
Macchiato 45.00
Sambusa 30.00
Water 20.00Your code
macchiato = 45
sambusa = 30
water = 20In the editor, press Escape then Tab to move on.
Show a solutionHide the solution
This is one way to solve it, not the only one. If yours prints the same thing, it works.
macchiato = 45
sambusa = 30
water = 20
print(f"{'Macchiato':<12}{macchiato:>8.2f}")
print(f"{'Sambusa':<12}{sambusa:>8.2f}")
print(f"{'Water':<12}{water:>8.2f}")Key takeaways
- An f-string has
fbefore the quote; each{expression}inside is replaced by its value. - Forget the
fand the braces print as they are, with no error. :.2fshows two decimals,:,adds thousands separators, and:,.2fdoes both.:<12and:>8set a width and alignment, for columns.f"{price=}"shows a name and its value, which helps when hunting bugs.