COMPUTER PROGRAMMING 1 (PYTHON) • STRINGS & TEXT PROCESSING

Formatted Reports — I can use f-strings to produce readable reports with aligned labels/values at my level.

Learn to craft polished, aligned text output using Python f-strings so your programs communicate data clearly.

Historical Context & Motivation

From the earliest days of computing, programs needed to display results to human users. Raw data dumped to a screen is hard to read, so developers quickly realized they needed tools for string formatting — the process of arranging text, numbers, and labels into neat, aligned columns. Think of it like designing a receipt or a scoreboard: the data is only useful if people can scan it at a glance.

Python has gone through several generations of formatting tools. Each new approach aimed to make the code more readable and more powerful. Understanding this evolution helps you appreciate why f-strings (formatted string literals) are the modern standard and why they make your life so much easier.

1991
Python 1.0 — The % Operator
Python adopted C-style formatting with the % operator, using placeholders like %s and %d. It worked but was error-prone and hard to read.
2008
Python 2.6 — str.format()
The .format() method introduced curly-brace placeholders like "{}".format(value). This was clearer, but long expressions still felt clunky.
2015
PEP 498 Proposed
Eric V. Smith proposed f-strings in PEP 498, arguing that embedding expressions directly inside strings would reduce boilerplate and improve readability.
2016
Python 3.6 — f-strings Released
F-strings became available with Python 3.6. Developers could now write f"Hello, {name}!" and embed any valid Python expression inside the braces.
2023
Python 3.12 — Nested f-strings
Python 3.12 lifted earlier restrictions, allowing fully nested f-strings and more complex expressions inside braces, making formatted reports even more flexible.

The core question that drove this evolution is simple: How do we turn raw data into a report that is easy for a human to read? F-strings answer that question with concise syntax and powerful alignment controls that we will explore throughout this lesson.

Core Principles of F-String Formatting

Before diving into code, it helps to understand the foundational ideas behind f-string formatting. Every formatted report relies on the same handful of principles, regardless of whether you are printing a grade book, a sports roster, or a financial summary.

1

Interpolation

An f-string lets you embed a Python expression inside curly braces {}. Python evaluates the expression and inserts its value into the string at runtime.
2

Format Specifier

After the expression, a colon : introduces a mini-language that controls width, alignment, fill characters, and number precision — all in one compact instruction.
3

Alignment

Use < for left, > for right, and ^ for center alignment within a fixed-width field. This is how columns line up.
4

Width & Fill

A number after the alignment character sets the field width. An optional fill character (like a dot or dash) replaces spaces, letting you create visual guides between labels and values.
5

Type Codes

Letters like d (integer), f (float), s (string), and , (thousands separator) tell Python how to display the value.
✦ KEY TAKEAWAY
Think of an f-string format specifier like a label maker at the post office. You set the width of the label (field width), decide whether the text should be pushed left, right, or centered (alignment), and choose what fills the empty space (fill character). The label maker then stamps out perfectly uniform labels every time — and that is exactly what your code does for each row of a report.

Anatomy of an F-String Format Specifier

The diagram below breaks down the complete syntax of a format specifier inside an f-string. Every element is optional, but understanding the full pattern gives you total control over your output.

Each colored segment maps to one part of the format specifier mini-language. The expression is evaluated first, then formatted according to the fill, alignment, width, and type code.

Reading the diagram from left to right, notice that the colon acts as a divider between the expression you want to display and the instructions for how to display it. Everything after the colon is optional — if you write just f"{name}", Python prints the value with no extra padding or formatting. But when you add a width like f"{name:20}", Python guarantees the output occupies at least 20 characters, padding with spaces on the right (for strings) or on the left (for numbers) by default.

The Format Spec Mini-Language

Python's format specifier follows a compact pattern. While it is not a math equation in the traditional sense, you can think of it as a formula that Python parses left to right. The general syntax is:

FORMAT SPECIFIER SYNTAX
{ expression : [fill][align][sign][#][0][width][grouping][.precision][type] }
fill = any single character used for padding; align = < (left), > (right), ^ (center); width = minimum number of characters; .precision = decimal places for floats; type = d (integer), f (fixed-point float), s (string), , (comma separator), % (percentage).

Alignment in Action

The three alignment operators are the key to building columnar reports. When you write f"{'Alice':<15}", Python takes the string Alice (5 characters) and pads it on the right with 10 spaces so it fills 15 characters total. If you switch to f"{'Alice':>15}", the padding goes on the left instead, pushing "Alice" to the right edge of the 15-character field.

PADDING CALCULATION
padding_chars = width − len(str(value))
If the value is already longer than the width, no truncation occurs — Python simply uses the full value. Padding only adds characters; it never removes them.

Number Formatting

For numbers, the format spec gets especially useful. Writing f"{price:.2f}" forces two decimal places, so 9.5 becomes 9.50. Adding a comma for thousands grouping — f"{population:,}" — turns 1000000 into 1,000,000. You can even combine them: f"{revenue:>12,.2f}" right-aligns a number in a 12-character field with commas and two decimal places.

COMMON NUMBER FORMAT EXAMPLES
f"{42:05d}" → 00042 f"{0.753:.1%}" → 75.3% f"{3.14159:.3f}" → 3.142
05d zero-pads an integer to 5 digits; .1% multiplies by 100 and shows 1 decimal place with a % sign; .3f rounds a float to 3 decimal places.

Building Aligned Reports Column by Column

The real power of f-strings shines when you combine multiple format specifiers in a single line to build a row of a report. Each column has its own width and alignment, and because every row uses the same format string, the columns automatically line up. The diagram below shows how a three-column report is constructed.

The dashed vertical lines show column boundaries. Names are left-aligned so they start at the same position. Scores are right-aligned so the ones digits line up. Grades are center-aligned for a balanced look.

Notice how every row uses the exact same format string. You typically write the format string once — often inside a loop — and feed it different data each iteration. This pattern guarantees that no matter how many rows your report has, the columns remain perfectly aligned.

💡 Pro Tip: Header Rows
Use the same format string for your header row, but pass the column titles as the values. For example: f"{'Name':<20}{'Score':>8}{'Grade':^10}". Then print a separator line like print('-' * 38) right after the header to visually separate it from the data.

Worked Example: Student Grade Report

Let's build a complete, formatted grade report step by step. We'll start with raw data and end with a polished, print-ready output.

Building a Student Grade Report
1
Step 1 — Define the DataCreate a list of tuples, where each tuple holds a student's name, score, and letter grade. For example: students = [ ("Alice Johnson", 95, "A"), ("Bob Martinez", 87, "B+"), ("Charlie Kim", 72, "C"), ("Diana Patel", 91, "A-"), ]
Data stored as a list of 4 tuples.
2
Step 2 — Design the Format StringDecide on column widths. The longest name is "Alice Johnson" (13 characters), so we choose 20 for breathing room. Scores are at most 3 digits, so width 8 gives comfortable right-alignment. Grades are short, so 10 centered works well. The format string is: row_fmt = f"{name:<20}{score:>8}{grade:^10}" But we will build this inside a loop, so we use the variables from unpacking each tuple.
Format: left 20, right 8, center 10 = 38 total characters per row.
3
Step 3 — Print the Header and SeparatorUse the same alignment on string literals to create a matching header row, then print a line of dashes: print(f"{'Name':<20}{'Score':>8}{'Grade':^10}") print('-' * 38)
Name Score Grade --------------------------------------
4
Step 4 — Loop Through the DataIterate over the list, unpack each tuple, and print the formatted row: for name, score, grade in students: print(f"{name:<20}{score:>8}{grade:^10}")
Alice Johnson 95 A Bob Martinez 87 B+ Charlie Kim 72 C Diana Patel 91 A-
5
Step 5 — Add a Summary FooterCalculate the average score and display it with two decimal places, right-aligned under the Score column: avg = sum(s for _, s, _ in students) / len(students) print('-' * 38) print(f"{'Average':<20}{avg:>8.2f}")
-------------------------------------- Average 86.25
✦ KEY TAKEAWAY
The secret to a clean report is reusing the same format string for every row — header included. Think of it like a spreadsheet template: you set the column widths once, then every row of data snaps into place automatically. If you later add more students, the alignment stays perfect.

F-Strings vs. Other Formatting Methods

You may encounter older Python code that uses the % operator or the .format() method. Here is how these three approaches compare when producing the same output.

Comparison of Python string formatting approaches
Feature% Operator.format()f-strings
Introduced inPython 1.0 (1991)Python 2.6 (2008)Python 3.6 (2016)
ReadabilityLow — placeholders are far from valuesMedium — clearer but verboseHigh — values inline
Expressions inline?NoLimitedYes — any expression
PerformanceModerateModerateFastest — compiled at parse time
Alignment syntax%-20s, %8d{:<20}, {:>8}{name:<20}, {score:>8}
Best for new code?No — legacy onlyRare edge casesYes — recommended
✦ KEY TAKEAWAY
If you are writing new Python code (Python 3.6+), f-strings should be your default. They run faster, they read more naturally because values appear right where they are used, and they support the full format spec mini-language. You only need the older methods when maintaining legacy code.

Connecting to Advanced Formatting

The f-string skills you are building now are the foundation for more advanced output scenarios. As your programs grow, you will encounter situations that push beyond simple console reports — writing data to files, generating HTML tables, or creating PDF reports. The table below shows how the concepts you have learned map to these next-level tools.

From f-strings to advanced output tools
This Lesson (F-Strings)Advanced Tools
Column alignment with <, >, ^Libraries like tabulate or PrettyTable auto-align columns and add borders
Number precision with .2fThe locale module formats currencies by country (e.g., $1,234.56 vs. 1.234,56 €)
Printing to console with print()Writing to .txt or .csv files with open() and the csv module
String concatenation in f-stringsTemplate engines like Jinja2 build entire web pages from data
Thousands separator with , groupingpandas DataFrame.to_string() for formatted data analysis output

Every one of these advanced tools still relies on the same core idea: specify the field width, choose an alignment, and format the value. Mastering f-string formatting now means you already understand the underlying logic; the advanced libraries just wrap it in extra convenience features.

🚀 Looking Ahead
In future courses, you might explore Python's logging module, which uses format strings to record events in running applications. You will also see f-strings used extensively in web frameworks like Flask and Django, where dynamic text generation is central to building interactive websites.

Practice Problems

PROBLEM 1 — CONCEPTUAL
Explain, in your own words, the difference between f"{value:<10}" and f"{value:>10}". Why would you use left-alignment for text labels but right-alignment for numbers in a report?
PROBLEM 2 — BASIC CALCULATION
Write a single f-string expression that displays the variable price = 49.99 right-aligned in a field of 12 characters with a thousands comma and exactly two decimal places. What would the output look like if price = 1234567.8?
PROBLEM 3 — INTERMEDIATE
You have a list of items for a store receipt: items = [("Widget", 3, 4.99), ("Gizmo", 1, 29.95), ("Thingamajig", 12, 0.50)] Each tuple is (item_name, quantity, unit_price). Write a complete Python script that prints a formatted receipt with four columns: Item (left-aligned, 18 chars), Qty (right-aligned, 5 chars), Unit Price (right-aligned, 10 chars with 2 decimals), and Total (right-aligned, 10 chars with 2 decimals). Include a header, separator line, and a grand total row at the bottom.
PROBLEM 4 — APPLIED
A teacher stores test scores in a dictionary: scores = {"Alice": [88, 92, 79], "Bob": [65, 70, 72], "Carla": [95, 98, 100]} Write a program that prints a report with columns: Student (left-aligned, 15 chars), Test 1 (right-aligned, 8 chars), Test 2 (right-aligned, 8 chars), Test 3 (right-aligned, 8 chars), and Average (right-aligned, 10 chars with 1 decimal). Use a dot-fill character for the Student column so the output looks like Alice.......... 88.
PROBLEM 5 — CRITICAL THINKING
Suppose your dataset contains a name that is 25 characters long, but your format string specifies a width of 15 for the name column. What happens to the alignment of the rest of the row? Propose two different strategies to handle this problem, and write example code for each. Discuss the trade-offs.

Lesson Summary

Python f-strings (introduced in Python 3.6) let you embed expressions directly in strings using curly braces. After a colon, you enter the format specifier mini-language, where you control fill characters, alignment (< left, > right, ^ center), field width, precision for decimals, and type codes like d, f, and ,.

To build a formatted report, design one format string that defines every column's width and alignment, then reuse it for the header and every data row inside a loop. Left-align text labels and right-align numbers so digits stack vertically. Add separator lines with string multiplication ('-' * width) and summary rows for totals or averages. These skills transfer directly to advanced tools like tabulate, pandas, and web template engines.

Varsity Tutors • Computer Programming 1 (Python) • Formatted Reports — I can use f-strings to produce readable reports with aligned labels/values at my level.