Legends ofPythos
Claim your name
The Standard Library

Formatting output properly

Lesson 1 of 7

Watch the lesson1:21 · with Torsten
You know how to build strings with f-strings. Now you can control how the values look: width, alignment, fill characters, decimal places, and thousands separators.

The syntax lives inside the braces after a colon:
{value:<10} means left-align in 10 spaces.

Width and alignment

name = 'Ada'
count = 42
title = 'Python'

print(f'[{name:<10}]')   # [Ada       ]  left-align in width 10
print(f'[{count:>5}]')    # [   42]       right-align in width 5
print(f'[{title:^20}]')   # [       Python       ]  centre in width 20
< is left, > is right, ^ is centre

Fill character and decimal places

n = 7
price = 19.5
ratio = 0.8342
total = 1_234_567

print(f'{n:*>6}')       # *****7   right-align in width 6, padded with *
print(f'{price:.2f}')   # 19.50   two decimal places
print(f'{ratio:.1%}')   # 83.4%   a percentage, one decimal place
print(f'{total:,}')     # 1,234,567
print(f'{total:,.2f}')  # 1,234,567.00
Fill char goes before the alignment symbol

Zero padding and self-documenting debug

minute = 7
hour   = 12
total  = 4_805.93

print(f'{hour:02d}:{minute:02d}')  # clock-style zero padding -> 12:07
print(f'{total=}')                 # total=4805.93   the name, then its value
{var=} shows the variable name and its value

Building an aligned table

rows = [
    ('Ada', 98.5),
    ('Grace', 102.34),
    ('Linus', 76.0)
]
table_lines = [f"{'Name':<10}{'Score':>8}"]
for name, score in rows:
    table_lines.append(f'{name:<10}{score:>8.2f}')   # same widths as the header
print('\n'.join(table_lines))
# Name         Score
# Ada          98.50
# Grace       102.34
# Linus        76.00
ljust/rjust or f-string width both work

Older styles you will still see

# str.format()
name, score = 'Ada', 98.5
print('{} scored {:.1f}'.format(name, score))

# %-style (very old code)
age = 36
print('%s is %d years old' % (name, age))
Read these; write f-strings

Your turn

0 of 3 solved

Exercise 1

+40 XP
Write tag(name, price, qty), which returns a shop label built from three format specifications, separated by |: the name left-aligned in 10 characters, the price right-aligned in 8 with 2 decimal places, and the quantity padded with zeros to 3 digits. For example, tag('rope', 4.5, 7) is 'rope | 4.50|007'.
def tag(name, price, qty):
    # one f-string, three format specifications
    pass

Run your code to check it against the tests.

Exercise 2

+40 XP
Write build_table(rows), where each row is a (name, score) tuple. Return one line per row, joined with newlines: the name left-aligned in 8 characters, then the score right-aligned in 10 with thousands separators and 2 decimal places. For example, build_table([('Ada', 9850)]) is 'Ada 9,850.00'. An empty list gives an empty string.
def build_table(rows):
    # one formatted line per row, joined with newlines
    pass

Run your code to check it against the tests.

Exercise 3

+40 XP
Write summary(done, total) that returns f'{done=}, {total=}, ' followed by the fraction done as a percentage with one decimal place (the % specification). The = after a name makes the f-string print the name as well as the value. For example, summary(3, 8) is 'done=3, total=8, 37.5%'.
def summary(done, total):
    # {name=} for the first two, a percentage for the last
    pass

Run your code to check it against the tests.