f-strings in Python: format numbers the way people read them
Your model says a tee costs 0.38 a wear and the margin is 0.631578947368421. Both are right, and neither is fit to show anyone. Format specs fix that.
The big idea
An f-string embeds expressions in text inside {}, and a format spec after a colon controls exactly how each value is displayed.
See it in code
Rounding changes a number; it doesn't control how it prints. round(0.8, 2) is still displayed as 0.8. A format spec sets the display directly:
cheap_per_wear = 8 / 10
print(round(cheap_per_wear, 2))
print(f"${cheap_per_wear:.2f} per wear")0.8 $0.80 per wear
:.2f means "fixed-point, two decimal places," so 0.8 is shown as 0.80. Rounding removes digits; it never adds them back.
Other specs handle other shapes of number. :, inserts thousands separators and :.1% multiplies by 100 and adds a percent sign:
margin = (38 - 14) / 38
year_one = 331398
launch_costs = 12500.0
print(f"Margin: {margin:.1%}")
print(f"Year one revenue: ${year_one:,}")
print(f"Launch costs: ${launch_costs:,.0f}")Margin: 63.2% Year one revenue: $331,398 Launch costs: $12,500
Specs combine: :,.0f means thousands separators and zero decimal places. The underlying values are unchanged; only their presentation is.
A number after the colon sets a field width, with < for left-aligned and > for right-aligned. That's enough to print a tidy table:
names = ["Organic tee", "Everyday pants", "Wool socks"]
prices = [38, 78, 14]
costs = [14, 29, 4]
print(f"{'Product':<16}{'Price':>7}{'Margin':>9}")
for i in range(len(names)):
margin = (prices[i] - costs[i]) / prices[i]
print(f"{names[i]:<16}{prices[i]:>7.2f}{margin:>9.1%}")Product Price Margin Organic tee 38.00 63.2% Everyday pants 78.00 62.8% Wool socks 14.00 71.4%
Every row uses the same widths, so the columns line up whatever the lengths of the names. Text reads best left-aligned and numbers right-aligned.
The same specs format any report: a GC-content percentage, a backtest's return, a file size, a timing. Compute at full precision, and round only when you display.
Try it yourself
Add a fourth column for profit per item, prices[i] - costs[i], formatted as >8.2f. Then widen the first column to 20 and see everything shift together.
The common mistake
Forgetting the f. Without it, "Margin: {margin:.1%}" prints the braces and the spec exactly as typed. The symptom is unmistakable: curly braces on screen.
What it unlocks
f-strings are the polished form of print(). The values going into them often need cleaning first with string methods.