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"