← Home

032. F Strings

Interpolate values directly into string templates

032. F Strings

RAM Manager: Formatting Process Output

Aryan’s RAM manager needs to display process info clearly. The raw data from /proc is just numbers — he needs to format it into readable output.

# What ps aux gives him (after parsing)
pid = 812
name = "chrome"
mem_mb = 544
mem_pct = 6.8

# Old way (from his C habits)
line = name + " [" + str(pid) + "] " + str(mem_mb) + "MB (" + str(mem_pct) + "%)"
# → "chrome [812] 544MB (6.8%)"   but tedious and error-prone

# f-string way
line = f"{name} [{pid}] {mem_mb}MB ({mem_pct:.1f}%)"
# → "chrome [812] 544MB (6.8%)"

Aryan’s format_process function is built using messy string concatenation. The percentage shows too many decimal places and the price formatting doesn’t zero-pad cents. Fix all three functions using f-strings.


💡 Fun fact: F-strings (PEP 498) were introduced in Python 3.6 (2016) and are now the fastest string formatting method in Python — faster than % formatting and .format() because the expression inside {} is compiled directly into bytecode at parse time rather than being evaluated as a runtime function call.

⚠️ Watch out: Forgetting a format specifier like :.2f for prices means floats will display with unpredictable decimal places — f"{5.0}" gives "5.0" but the test expects "5.00". Always specify the format for numbers that must appear in a fixed format in user-facing output.

🤔 Think about it: F-strings evaluate any Python expression inside {} — including function calls, attribute access, and even ternary expressions. Does that power come with any risks, and when might it be better to compute a value before the f-string rather than inside it?

Learning objectives

  • Create f-strings with embedded expressions
  • Apply format specifiers for floats (:.2f, :.1f)
  • Replace string concatenation with f-strings

Key concepts

  • f-strings
  • string formatting
  • format specifiers

Try it

Concept detail

f-strings (formatted string literals, PEP 498, Python 3.6+) embed expressions directly. Syntax: f“text {expression} more text“

Any Python expression works inside {}: f“{2 + 2}“ → “4” f“{name.upper()}“ → “ALICE” f“{d[‘key’]}“ → value from dict (use different quote type)

Format specifiers after :: {value:spec} {3.14159:.2f} → “3.14” (2 decimal places) {1000000:,} → “1,000,000” (thousands separator) {42:05d} → “00042” (zero-padded width 5) {‘left’:<10} → “left “ (left-aligned in 10 chars) {‘right’:>10} → “ right” (right-aligned)

Performance: f-strings are faster than % formatting and .format() because they’re evaluated at parse time as constants. They’re also more readable — the variable sits where it appears in the output, not at the end of a format call.

Solution

def format_score(name, score, max_score):
    pct = score / max_score * 100
    return f"{name} scored {score}/{max_score} ({pct:.1f}%)"

def format_price(item, price):
    return f"{item}: ${price:.2f}"

def format_coords(lat, lon):
    return f"Location: {lat}°N, {lon}°W"

Tests

def test_format_score():
    result = format_score("Alice", 95, 100)
    assert result == "Alice scored 95/100 (95.0%)"

def test_format_score_rounding():
    result = format_score("Bob", 1, 3)
    assert result == "Bob scored 1/3 (33.3%)"

def test_format_price():
    result = format_price("Widget", 12.99)
    assert result == "Widget: $12.99"

def test_format_price_rounding():
    result = format_price("Gadget", 5.0)
    assert result == "Gadget: $5.00"

def test_format_coords():
    result = format_coords(51.5074, 0.1278)
    assert result == "Location: 51.5074°N, 0.1278°W"

Resources