Previous | Tutorial index | Next

Tutorial 8: Outputting Data (print())

Learning Objective

To be able to write correct statements using print

1. Introduction

1.1 Purpose of print()

The print() function is Python's primary tool for displaying information to the console (standard output). It converts the objects you pass to it into strings and writes them to the output stream, typically your terminal or command prompt.

Why is this important?

Under the Hood:

1.2 Basic Usage – Printing Values

Printing a single value:

print(42) # Outputs: 42 print("Hello") # Outputs: Hello print(3.14159) # Outputs: 3.14159 print(True) # Outputs: True print([1, 2, 3]) # Outputs: [1, 2, 3]

Printing multiple values:

print("Hello", "World", 2026) # Outputs: Hello World 2026

When you pass multiple arguments, print() automatically inserts a space between them.

Multiple types in one print():

name = "Alice" age = 30 score = 95.5 print("Name:", name, "Age:", age, "Score:", score) # Outputs: Name: Alice Age: 30 Score: 95.5

Important: print() can accept any number of arguments. Each argument is converted to a string and printed with separators.

1.3 The sep Parameter – Controlling Separators

The sep (separator) parameter specifies what string is placed between multiple arguments. By default, sep is a single space ' '.

Syntax:

print(value1, value2, ..., sep='separator_string')

Examples:

# Default separator (space) print("A", "B", "C") # A B C # Comma and space print("A", "B", "C", sep=", ") # A, B, C # No separator print("A", "B", "C", sep="") # ABC # Custom separator print("A", "B", "C", sep="-*-") # A-*-B-*-C # Newline separator print("A", "B", "C", sep="\n") # A (newline) B (newline) C

Use Case – Creating CSV (Comma-Separated Values):

print("Name", "Age", "City", sep=",") # Name,Age,City

Use Case – Building a Path:

print("folder", "subfolder", "file.txt", sep="/") # folder/subfolder/file.txt

1.4 The end Parameter – Controlling the Ending

The end parameter specifies what string is printed at the end of the print() call. By default, end is a newline character '\n', which moves the cursor to the next line.

Syntax:

print(value1, value2, ..., end='ending_string')

Examples:

# Default (newline) print("Hello") print("World") # Outputs: # Hello # World # No newline (print on same line) print("Hello", end=" ") print("World") # Outputs: Hello World # Custom ending print("Hello", end="!!!") print("World") # Outputs: Hello!!!World # Empty ending print("Hello", end="") print("World") # Outputs: HelloWorld

Use Case – Building a Progress Indicator:

import time for i in range(5): print(".", end="", flush=True) # flush=True forces immediate output time.sleep(0.5) print(" Done!") # Outputs: ..... Done! (with delays between dots)

Use Case – Printing in a Loop Without Newlines:

for i in range(1, 6): print(i, end=" ") # Outputs: 1 2 3 4 5

Use Case – Creating a Table Row:

print("Row 1", end=" | ") print("Column A", end=" | ") print("Column B") # Outputs: Row 1 | Column A | Column B

1.5 Combining sep and end

You can use both parameters simultaneously:

print("A", "B", "C", sep=", ", end=".\n") # Outputs: A, B, C. # (then a newline)

Example – Building a Sentence:

words = ["The", "quick", "brown", "fox"] for word in words: print(word, end=" ") print("jumps over the lazy dog.") # Outputs: The quick brown fox jumps over the lazy dog.

1.6 The file Parameter – Writing to a File

print() can also write to a file instead of the console. This is done using the file parameter.

Syntax:

print("Hello", file=file_object)

Example:

with open("output.txt", "w") as f: print("Hello, World!", file=f) print("This is line 2.", file=f) # This writes to output.txt instead of the console.

Note: This is an advanced topic; for this unit, the focus is on console output.

1.7 String Formatting – Making Output Look Professional

While you can use + for concatenation, it gets messy quickly. Python provides better ways to embed variables in strings.

1.7.1 f‑strings (Formatted String Literals) – RECOMMENDED (Python 3.6+)

Prefix the string with f or F. Inside curly braces {}, you can put any Python expression (variable names, arithmetic, function calls, etc.).

Basic Usage:

name = "Alice" age = 30 print(f"Hello, {name}! You are {age} years old.") # Outputs: Hello, Alice! You are 30 years old.

Expressions Inside f‑strings:

price = 19.99 quantity = 3 print(f"Total: ${price * quantity:.2f}") # Outputs: Total: $59.97

Calling Functions:

name = "python" print(f"Uppercase: {name.upper()}") # Outputs: Uppercase: PYTHON

Formatting Numbers (Important):

Format Specifier Meaning Example Output
{value:.2f} 2 decimal places {3.14159:.2f} 3.14
{value:.0f} No decimals (rounds) {3.7:.0f} 4
{value:,} Comma as thousands separator {1234567:,} 1,234,567
{value:,.2f} Thousands + 2 decimals {1234567.891:,} 1,234,567.89
{value:>10} Right‑align in 10 spaces {"abc":>10} abc
{value:<10} Left‑align in 10 spaces {"abc":<10} abc
{value:^10} Center in 10 spaces {"abc":^10} abc
{value:.3%} Percentage with 3 decimals {0.1234:.3%} 12.340%
{value:b} Binary representation {10:b} 1010
{value:x} Hexadecimal {255:x} ff

Examples:

salary = 75000.50 print(f"Salary: ${salary:,.2f}") # Salary: $75,000.50 percentage = 0.8576 print(f"Pass rate: {percentage:.1%}") # Pass rate: 85.8% name = "Bob" print(f"{name:>10}") # " Bob" print(f"{name:<10}") # "Bob "

1.7.2 The .format() Method (Older but Still Common)

Before f‑strings, this was the recommended method.

Basic Usage:

name = "Alice" age = 30 print("Hello, {}! You are {} years old.".format(name, age)) # Outputs: Hello, Alice! You are 30 years old.

Positional Arguments:

print("{1} is {0} years old.".format(30, "Alice")) # Outputs: Alice is 30 years old.

Named Arguments:

print("Hello, {name}! You are {age} years old.".format(name="Alice", age=30))

Number Formatting:

print("Total: {:.2f}".format(19.99 * 3)) # Total: 59.97 print("Salary: {:,}".format(75000)) # Salary: 75,000

1.7.3 Old‑Style % Formatting (Legacy)

Older than .format(), inspired by C's printf.

Examples:

name = "Alice" age = 30 print("Hello, %s! You are %d years old." % (name, age)) # Outputs: Hello, Alice! You are 30 years old.

Common Placeholders:

Note: f‑strings are recommended for new code. This method is kept for legacy code.

1.8 Escape Sequences – Special Characters in Strings

Escape sequences allow you to insert special characters into strings. They start with a backslash \.

Escape Sequence Description Example Output
\n Newline print("A\nB") A (newline) B
\t Tab print("A\tB") A B
\\ Backslash print("C:\\path") C:\path
\" Double quote print("She said \"Hi\"") She said "Hi"
\' Single quote print('It\'s nice') It's nice
\r Carriage return print("Hello\rWorld") World (overwrites)
\b Backspace print("Hello\bWorld") HellWorld

Examples:

print("Line 1\nLine 2\nLine 3") # Outputs: # Line 1 # Line 2 # Line 3 print("Name\tAge\tCity") print("Alice\t30\tNYC") print("Bob\t25\tLA") # Outputs a simple table with tabs

1.9 Combining print() with input() – Interactive Programs

Here's a complete interactive program using both:

name = input("Enter your name: ").strip() age = input("Enter your age: ") try: age = int(age) print(f"Hello, {name}! Next year you will be {age + 1}.") except ValueError: print("Invalid age. Please enter a number.")

1.10 Common Pitfalls and Best Practices

Pitfall 1: Forgetting to Convert Types:

age = 30 print("Age: " + age) # TypeError! # Correct: print("Age: " + str(age)) # Or better: print(f"Age: {age}")

Pitfall 2: Using print() in Production Code:

Pitfall 3: Missing Newlines:

print("Loading", end="") # User sees "Loading" without a newline, which can be confusing. # Better to show progress with a dot: for i in range(5): print(".", end="", flush=True) time.sleep(0.5) print(" Done!")

Best Practices:

  1. Use f‑strings for most formatting – they're readable and fast.
  2. Use sep and end for clean output, especially in loops.
  3. Provide clear messages – tell the user what they're seeing.
  4. Use \n for readability in long output.
  5. Avoid string concatenation (+) when you have many variables – use f‑strings.

2. Code Examples (Annotated)

# --- Basic Print --- print("--- Basic Print ---") print(42) print("Hello") print(3.14159) print([1, 2, 3]) # --- Multiple Arguments --- print("\n--- Multiple Arguments ---") print("Hello", "World", 2026) print("Name:", "Alice", "Age:", 30) # --- The sep Parameter --- print("\n--- sep Parameter ---") print("A", "B", "C", sep=", ") # A, B, C print("A", "B", "C", sep="") # ABC print("A", "B", "C", sep="|") # A|B|C print("A", "B", "C", sep="\n") # A (newline) B (newline) C # --- The end Parameter --- print("\n--- end Parameter ---") print("Hello", end=" ") print("World") # Hello World print("Hello", end="!!!") print("World") # Hello!!!World print("1", end="") print("2", end="") print("3") # 123 # --- Combining sep and end --- print("\n--- Combining Parameters ---") print("A", "B", "C", sep=", ", end=".\n") # A, B, C. # --- f-strings --- print("\n--- f-strings ---") name = "Alice" age = 30 price = 19.99 quantity = 3 salary = 75000.50 percentage = 0.8576 print(f"Hello, {name}! You are {age} years old.") print(f"Total: ${price * quantity:.2f}") print(f"Salary: ${salary:,.2f}") print(f"Pass rate: {percentage:.1%}") print(f"{name:>10}") # Right-aligned print(f"{name:<10}") # Left-aligned # --- Escape Sequences --- print("\n--- Escape Sequences ---") print("Line 1\nLine 2\nLine 3") print("Name\tAge\tCity") print("Alice\t30\tNYC") print("C:\\Users\\Alice") print("She said \"Hello!\"") # --- Realistic Example: Shopping Receipt --- print("\n--- Shopping Receipt ---") item = "Laptop" unit_price = 1299.99 quantity = 2 tax_rate = 0.08 subtotal = unit_price * quantity tax = subtotal * tax_rate total = subtotal + tax print("=" * 40) print(f"{'ITEM':<20}{'QTY':>5}{'PRICE':>10}") print("-" * 40) print(f"{item:<20}{quantity:>5}${unit_price:>9,.2f}") print("-" * 40) print(f"{'Subtotal:':>30} ${subtotal:>9,.2f}") print(f"{'Tax (8%):':>30} ${tax:>9,.2f}") print(f"{'Total:':>30} ${total:>9,.2f}") print("=" * 40)

3. Quiz (Check Your Understanding)

Question 1: What is the output of print("Hello", "World")?
a) HelloWorld
b) Hello World
c) Hello,World
d) Hello\nWorld

Answer b) `Hello World`

Question 2: What is the output of print("A", "B", "C", sep=", ")?
a) A,B,C
b) A B C
c) A, B, C
d) A-B-C

Answer c) `A, B, C`

Question 3: What is the output of print("Hello", end=" "); print("World")?
a) Hello World
b) HelloWorld
c) Hello\nWorld
d) Hello World (with newline after)

Answer a) `Hello World` (on the same line)

Question 4: What is the output of print(f"Total: {3 * 4}")?
a) Total: 12
b) Total: 3 * 4
c) Total: 34
d) Total: 7

Answer a) `Total: 12`

Question 5: What does \n represent?
a) Tab
b) Newline
c) Backslash
d) Space

Answer b) Newline

Question 6: Which f‑string correctly formats a float to 2 decimal places?
a) {value:.2f}
b) {value:2f}
c) {value:.2}
d) {value:.2d}

Answer a) `{value:.2f}`

Question 7: What is the output of print(f"{1234567:,}")?
a) 1234567
b) 1,234,567
c) 1234567,
d) 1.234.567

Answer b) `1,234,567`

Question 8: What is the output of print("Hello", "World", sep="\n")?
a) Hello World
b) Hello\nWorld
c) Hello (newline) World
d) Hello,World

Answer c) `Hello` and `World` on separate lines.

Question 9: What is the output of:

for i in range(3): print(i, end=" ")

a) 0 1 2
b) 0\n1\n2
c) 012
d) 0,1,2

Answer a) `0 1 2`

Question 10: Which is the recommended way to format a string in modern Python?
a) % formatting
b) .format() method
c) f‑strings
d) String concatenation with +

Answer c) f‑strings

4. Exercises (In-Class / Lab Practice)

Exercise 1: Basic Formatting
Create variables for name, age, height, weight; print a summary with appropriate formatting.

Sample Solution ```python name = "Alice" age = 30 height = 1.75 weight = 68.5 bmi = weight / (height ** 2) print(f"Name: {name}") print(f"Age: {age} years old") print(f"Height: {height:.2f} m") print(f"Weight: {weight:.1f} kg") print(f"BMI: {bmi:.1f}") ```

Exercise 2: Shopping Cart Output
Given items and quantities, print a formatted table.

Sample Solution ```python items = [("Apple", 0.50), ("Banana", 0.30), ("Orange", 0.80)] quantities = [3, 5, 2] total = 0 print("Item Qty Price Subtotal") for (item, price), qty in zip(items, quantities): subtotal = price * qty total += subtotal print(f"{item:<8}{qty:>3} ${price:>5.2f} ${subtotal:>6.2f}") print(f"Total: ${total:.2f}") ```

Exercise 3: Progress Bar
Print a progress indicator that updates on the same line.

Sample Solution ```python import time for i in range(1, 11): percent = i * 10 bar = '#' * i + '.' * (10 - i) print(f"\rProgress: [{bar}] {percent}%", end="") time.sleep(0.5) print() ```

Exercise 4: Multiplication Table

Write a program that:

  1. Asks the user for a number.

  2. Prints the multiplication table from 1 to 10 in a formatted grid:

    1 x 5 = 5 2 x 5 = 10 ... 10 x 5 = 50
  3. Use f‑strings with alignment to line up the equals signs.

Sample Answer
""" MULTIPLICATION TABLE Demonstrates formatted output with f-strings and alignment """ print("=" * 60) print("MULTIPLICATION TABLE GENERATOR") print("=" * 60) # --- Get user input --- try: number = float(input("\nEnter a number: ")) except ValueError: print("❌ Invalid input! Using 5 as default.") number = 5 print(f"\nMultiplication Table for {number}") print("-" * 40) # --- Method 1: Simple version --- print("\nMethod 1: Simple") print("-" * 30) for i in range(1, 11): result = i * number print(f"{i} x {number} = {result}") # --- Method 2: Aligned version with f-strings --- print("\nMethod 2: Aligned") print("-" * 30) for i in range(1, 11): result = i * number print(f"{i:>2} x {number:>5} = {result:>8}") # --- Method 3: Fully formatted grid --- print("\nMethod 3: Formatted Grid") print("-" * 40) print(f"{'Multiplier':<10} {'Number':<10} {'Result':<10}") print("-" * 40) for i in range(1, 11): result = i * number print(f"{i:<10} {number:<10} {result:<10.2f}") # --- Method 4: Professional table with alignment --- print("\nMethod 4: Professional Table") print("=" * 50) # Header print(f"{'MULTIPLICATION TABLE FOR':^50}") print(f"{number:^50}") print("=" * 50) print(f"{'Expression':<20} {'Result':>30}") print("-" * 50) # Rows with aligned equals signs for i in range(1, 11): result = i * number # Using f-string with alignment expression = f"{i} × {number}" print(f"{expression:<20} = {result:>28.2f}") print("=" * 50) # --- Method 5: With number formatting for decimals --- print("\nMethod 5: With Decimal Formatting") print("-" * 50) # Detect if number is a whole number if number.is_integer(): display_number = int(number) else: display_number = number for i in range(1, 11): result = i * number if result.is_integer(): display_result = int(result) else: display_result = result # Align the equals sign print(f"{i:>2} × {display_number:<5} = {display_result}") # --- Bonus: Complete multiplication table (1-10) --- print("\n" + "=" * 60) print("BONUS: COMPLETE MULTIPLICATION TABLE (1-10)") print("=" * 60) # Generate a full 10x10 table print("\n" + " " * 4 + "|", end="") for col in range(1, 11): print(f"{col:>4}", end="") print() print("-" * 45) for row in range(1, 11): print(f"{row:>2} |", end="") for col in range(1, 11): print(f"{row * col:>4}", end="") print() print("\n" + "=" * 60) print("FORMATTING CODES USED:") print("=" * 60) print(" • `{var:<10}` - Left align in 10 spaces") print(" • `{var:>10}` - Right align in 10 spaces") print(" • `{var:^10}` - Center in 10 spaces") print(" • `{var:.2f}` - Format as float with 2 decimals") print(" • `{var:,.2f}` - Format with thousands separators") print(" • `{var:<20}` - Left align to line up equals signs") print(" • `.is_integer()` - Check if float is a whole number") print("=" * 60)

Sample Output:

============================================================ MULTIPLICATION TABLE GENERATOR ============================================================ Enter a number: 7 Multiplication Table for 7.0 ---------------------------------------- Method 1: Simple ------------------------------ 1 x 7.0 = 7.0 2 x 7.0 = 14.0 3 x 7.0 = 21.0 4 x 7.0 = 28.0 5 x 7.0 = 35.0 6 x 7.0 = 42.0 7 x 7.0 = 49.0 8 x 7.0 = 56.0 9 x 7.0 = 63.0 10 x 7.0 = 70.0 Method 2: Aligned ------------------------------ 1 x 7.0 = 7.0 2 x 7.0 = 14.0 3 x 7.0 = 21.0 4 x 7.0 = 28.0 5 x 7.0 = 35.0 6 x 7.0 = 42.0 7 x 7.0 = 49.0 8 x 7.0 = 56.0 9 x 7.0 = 63.0 10 x 7.0 = 70.0 Method 3: Formatted Grid ---------------------------------------- Multiplier Number Result ---------------------------------------- 1 7 7.00 2 7 14.00 3 7 21.00 4 7 28.00 5 7 35.00 6 7 42.00 7 7 49.00 8 7 56.00 9 7 63.00 10 7 70.00 Method 4: Professional Table ================================================== MULTIPLICATION TABLE FOR 7.0 ================================================== Expression Result -------------------------------------------------- 1 × 7.0 = 7.00 2 × 7.0 = 14.00 3 × 7.0 = 21.00 4 × 7.0 = 28.00 5 × 7.0 = 35.00 6 × 7.0 = 42.00 7 × 7.0 = 49.00 8 × 7.0 = 56.00 9 × 7.0 = 63.00 10 × 7.0 = 70.00 ================================================== Method 5: With Decimal Formatting -------------------------------------------------- 1 × 7 = 7 2 × 7 = 14 3 × 7 = 21 4 × 7 = 28 5 × 7 = 35 6 × 7 = 42 7 × 7 = 49 8 × 7 = 56 9 × 7 = 63 10 × 7 = 70 ============================================================ BONUS: COMPLETE MULTIPLICATION TABLE (1-10) ============================================================ | 1 2 3 4 5 6 7 8 9 10 --------------------------------------------- 1 | 1 2 3 4 5 6 7 8 9 10 2 | 2 4 6 8 10 12 14 16 18 20 3 | 3 6 9 12 15 18 21 24 27 30 4 | 4 8 12 16 20 24 28 32 36 40 5 | 5 10 15 20 25 30 35 40 45 50 6 | 6 12 18 24 30 36 42 48 54 60 7 | 7 14 21 28 35 42 49 56 63 70 8 | 8 16 24 32 40 48 56 64 72 80 9 | 9 18 27 36 45 54 63 72 81 90 10 | 10 20 30 40 50 60 70 80 90 100 ============================================================ FORMATTING CODES USED: ============================================================ • `{var:<10}` - Left align in 10 spaces • `{var:>10}` - Right align in 10 spaces • `{var:^10}` - Center in 10 spaces • `{var:.2f}` - Format as float with 2 decimals • `{var:,.2f}` - Format with thousands separators • `{var:<20}` - Left align to line up equals signs • `.is_integer()` - Check if float is a whole number ============================================================

Explanation:

Formatting Codes Used:

Code Description Example
{var:<10} Left align in 10 spaces "5 "
{var:>10} Right align in 10 spaces " 5"
{var:^10} Center in 10 spaces " 5 "
{var:.2f} Float with 2 decimals 7.00
{var:,.2f} Thousands separators + 2 decimals 1,234.56

Key Concepts:

  1. Alignment – Use <, >, or ^ to control text positioning.
  2. Width – The number after the alignment specifies the field width.
  3. Number Formattingf for float, d for integer.
  4. Integer Check.is_integer() checks if a float is a whole number.

Alternative Compact Version:

# Simple one-liner approach n = float(input("Enter number: ")) print('\n'.join(f'{i:>2} x {n:>5} = {i*n:>8.2f}' for i in range(1, 11)))

Exercise 5: Receipt Printer

Write a program that:

  1. Asks the user for item name, quantity, and price.

  2. Calculates subtotal, tax (8%), and total.

  3. Prints a formatted receipt:

    ======================================== ITEM QTY PRICE ---------------------------------------- Laptop 2 $1,299.99 ---------------------------------------- Subtotal: $2,599.98 Tax (8%): $208.00 Total: $2,807.98 ========================================
  4. Use proper alignment, thousands separators, and 2 decimal places.

Sample Answer
""" RECEIPT PRINTER Demonstrates formatted output with alignment, currency, and tax calculation """ print("=" * 60) print("📄 RECEIPT PRINTER") print("=" * 60) print("\nWelcome! Please enter the item details.\n") # --- Get user input --- item_name = input("Item name: ").strip() if not item_name: item_name = "Item" try: quantity = int(input("Quantity: ")) if quantity < 0: print("⚠️ Quantity cannot be negative. Using 1.") quantity = 1 except ValueError: print("⚠️ Invalid quantity. Using 1.") quantity = 1 try: price = float(input("Price per item: $")) if price < 0: print("⚠️ Price cannot be negative. Using $0.00.") price = 0.0 except ValueError: print("⚠️ Invalid price. Using $0.00.") price = 0.0 # --- Calculate totals --- subtotal = quantity * price tax_rate = 0.08 tax = subtotal * tax_rate total = subtotal + tax # --- Method 1: Simple receipt --- print("\n" + "=" * 60) print("METHOD 1: Simple Receipt") print("=" * 60) print("\n" + "=" * 40) print("RECEIPT") print("=" * 40) print(f"Item: {item_name}") print(f"Qty: {quantity}") print(f"Price: ${price:,.2f}") print("-" * 40) print(f"Subtotal: ${subtotal:,.2f}") print(f"Tax (8%): ${tax:,.2f}") print("=" * 40) print(f"TOTAL: ${total:,.2f}") print("=" * 40) # --- Method 2: Professional receipt --- print("\n" + "=" * 60) print("METHOD 2: Professional Receipt") print("=" * 60) # Define constants for formatting LINE_WIDTH = 50 print("\n" + "=" * LINE_WIDTH) print(f"{'RECEIPT':^{LINE_WIDTH}}") print("=" * LINE_WIDTH) print(f"{'ITEM':<30} {'QTY':>5} {'PRICE':>12}") print("-" * LINE_WIDTH) # Format the item line with alignment print(f"{item_name:<30} {quantity:>5} ${price:>11,.2f}") print("-" * LINE_WIDTH) # Summary lines with right alignment print(f"{'Subtotal:':>38} ${subtotal:>9,.2f}") print(f"{'Tax (8%):':>38} ${tax:>9,.2f}") print("=" * LINE_WIDTH) print(f"{'TOTAL:':>38} ${total:>9,.2f}") print("=" * LINE_WIDTH) # --- Method 3: Multi-item receipt --- print("\n" + "=" * 60) print("METHOD 3: Multi-Item Receipt") print("=" * 60) # Allow multiple items items = [] print("\nEnter multiple items (type 'done' when finished):\n") while True: name = input("Item name (or 'done'): ").strip() if name.lower() == 'done': break try: qty = int(input(" Quantity: ")) if qty < 0: qty = 0 except ValueError: qty = 0 try: p = float(input(" Price: $")) if p < 0: p = 0.0 except ValueError: p = 0.0 items.append({"name": name, "qty": qty, "price": p}) print() if items: # Calculate totals subtotal = sum(item["qty"] * item["price"] for item in items) tax = subtotal * 0.08 total = subtotal + tax # Print receipt print("\n" + "=" * LINE_WIDTH) print(f"{'STORE RECEIPT':^{LINE_WIDTH}}") print("=" * LINE_WIDTH) print(f"{'ITEM':<30} {'QTY':>5} {'PRICE':>12}") print("-" * LINE_WIDTH) for item in items: item_total = item["qty"] * item["price"] print(f"{item['name']:<30} {item['qty']:>5} ${item['price']:>11,.2f}") print("-" * LINE_WIDTH) print(f"{'Subtotal:':>38} ${subtotal:>9,.2f}") print(f"{'Tax (8%):':>38} ${tax:>9,.2f}") print("=" * LINE_WIDTH) print(f"{'TOTAL:':>38} ${total:>9,.2f}") print("=" * LINE_WIDTH) else: print("\nNo items entered. Receipt not printed.") # --- Method 4: Receipt with date and time --- print("\n" + "=" * 60) print("METHOD 4: Full Receipt with Date/Time") print("=" * 60) from datetime import datetime def print_full_receipt(items, store_name="My Store", tax_rate=0.08): """ Prints a full receipt with header, items, totals, and footer. """ LINE_WIDTH = 50 # Calculate totals subtotal = sum(item["qty"] * item["price"] for item in items) tax = subtotal * tax_rate total = subtotal + tax # Current date and time now = datetime.now() date_str = now.strftime("%B %d, %Y") time_str = now.strftime("%I:%M %p") # Print receipt print("\n" + "=" * LINE_WIDTH) print(f"{store_name:^{LINE_WIDTH}}") print("-" * LINE_WIDTH) print(f"{'Date:':<30} {date_str}") print(f"{'Time:':<30} {time_str}") print("-" * LINE_WIDTH) print(f"{'ITEM':<30} {'QTY':>5} {'PRICE':>12}") print("-" * LINE_WIDTH) for item in items: print(f"{item['name']:<30} {item['qty']:>5} ${item['price']:>11,.2f}") print("-" * LINE_WIDTH) print(f"{'Subtotal:':>38} ${subtotal:>9,.2f}") print(f"{'Tax (8%):':>38} ${tax:>9,.2f}") print("=" * LINE_WIDTH) print(f"{'TOTAL:':>38} ${total:>9,.2f}") print("=" * LINE_WIDTH) # Payment footer print(f"{'Thank you for your business!':^{LINE_WIDTH}}") print("=" * LINE_WIDTH) # Demo with sample data sample_items = [ {"name": "Laptop", "qty": 2, "price": 1299.99}, {"name": "Mouse", "qty": 3, "price": 29.99}, {"name": "Keyboard", "qty": 1, "price": 89.50} ] print("\nSample Multi-Item Receipt:") print_full_receipt(sample_items, "TECH STORE", 0.08) # --- Single Item Full Receipt --- print("\n" + "=" * 60) print("FULL RECEIPT (Single Item)") print("=" * 60) # Recreate the exact receipt from the exercise single_item = [{"name": "Laptop", "qty": 2, "price": 1299.99}] print_full_receipt(single_item, "TECH STORE", 0.08) print("\n" + "=" * 60) print("KEY TAKEAWAYS") print("=" * 60) print(" • `{var:>10}` - Right align in 10 spaces") print(" • `{var:^10}` - Center in 10 spaces") print(" • `{var:<10}` - Left align in 10 spaces") print(" • `{var:,.2f}` - Thousands separator with 2 decimals") print(" • Use `$` prefix for currency formatting") print(" • `datetime` module for date/time display") print(" • Tax = subtotal × tax_rate") print(" • Total = subtotal + tax") print("=" * 60)

Sample Output:

============================================================ 📄 RECEIPT PRINTER ============================================================ Welcome! Please enter the item details. Item name: Laptop Quantity: 2 Price per item: $1299.99 ============================================================ METHOD 1: Simple Receipt ============================================================ ======================================== RECEIPT ======================================== Item: Laptop Qty: 2 Price: $1,299.99 ---------------------------------------- Subtotal: $2,599.98 Tax (8%): $208.00 ======================================== TOTAL: $2,807.98 ======================================== ============================================================ METHOD 2: Professional Receipt ============================================================ ================================================== RECEIPT ================================================== ITEM QTY PRICE -------------------------------------------------- Laptop 2 $1,299.99 -------------------------------------------------- Subtotal: $2,599.98 Tax (8%): $208.00 ================================================== TOTAL: $2,807.98 ================================================== ============================================================ METHOD 3: Multi-Item Receipt ============================================================ Enter multiple items (type 'done' when finished): Item name (or 'done'): Laptop Quantity: 2 Price: $1299.99 Item name (or 'done'): Mouse Quantity: 3 Price: $29.99 Item name (or 'done'): Keyboard Quantity: 1 Price: $89.50 Item name (or 'done'): done ================================================== STORE RECEIPT ================================================== ITEM QTY PRICE -------------------------------------------------- Laptop 2 $1,299.99 Mouse 3 $29.99 Keyboard 1 $89.50 -------------------------------------------------- Subtotal: $2,719.96 Tax (8%): $217.60 ================================================== TOTAL: $2,937.56 ================================================== ============================================================ METHOD 4: Full Receipt with Date/Time ============================================================ Sample Multi-Item Receipt: ================================================== TECH STORE -------------------------------------------------- Date: August 14, 2026 Time: 02:30 PM -------------------------------------------------- ITEM QTY PRICE -------------------------------------------------- Laptop 2 $1,299.99 Mouse 3 $29.99 Keyboard 1 $89.50 -------------------------------------------------- Subtotal: $2,719.96 Tax (8%): $217.60 ================================================== TOTAL: $2,937.56 ================================================== Thank you for your business! ================================================== ============================================================ FULL RECEIPT (Single Item) ============================================================ ================================================== TECH STORE -------------------------------------------------- Date: August 14, 2026 Time: 02:30 PM -------------------------------------------------- ITEM QTY PRICE -------------------------------------------------- Laptop 2 $1,299.99 -------------------------------------------------- Subtotal: $2,599.98 Tax (8%): $208.00 ================================================== TOTAL: $2,807.98 ================================================== Thank you for your business! ================================================== ============================================================ KEY TAKEAWAYS ============================================================ • `{var:>10}` - Right align in 10 spaces • `{var:^10}` - Center in 10 spaces • `{var:<10}` - Left align in 10 spaces • `{var:,.2f}` - Thousands separator with 2 decimals • Use `$` prefix for currency formatting • `datetime` module for date/time display • Tax = subtotal × tax_rate • Total = subtotal + tax ============================================================

Explanation:

Receipt Formatting Elements:

  1. Alignment: Use <, >, ^ for left, right, and center alignment.
  2. Width: Specify the field width after the alignment character.
  3. Currency Formatting: {value:,.2f} adds commas and 2 decimal places.
  4. Tax Calculation: tax = subtotal * 0.08 (8%).
  5. Total: total = subtotal + tax.

Formatting Codes Used:

Code Example Output
{var:>10} {total:>10.2f} Right-aligns in 10 spaces
{var:<20} {item:<20} Left-aligns in 20 spaces
{var:^30} {store:^30} Centers in 30 spaces
{var:,.2f} {subtotal:,.2f} 2,599.98
{var:>9,.2f} {total:>9,.2f} $2,807.98 with right alignment

Key Concepts:

  1. Currency Formatting: Always use :,.2f for money values.
  2. Tax Calculation: Apply tax rate to subtotal.
  3. Alignment: Use alignment to create clean tables.
  4. Date/Time: Use datetime module for professional receipts.
  5. Multi-Item: Store items in a list for flexible processing.

Simplified Version (Directly Matching the Exercise):

# Exact receipt from the exercise item_name = input("Item name: ") quantity = int(input("Quantity: ")) price = float(input("Price: $")) subtotal = quantity * price tax = subtotal * 0.08 total = subtotal + tax print("\n" + "=" * 40) print("ITEM QTY PRICE") print("-" * 40) print(f"{item_name:<20} {quantity:>5} ${price:>8,.2f}") print("-" * 40) print(f"{'Subtotal:':>30} ${subtotal:>8,.2f}") print(f"{'Tax (8%):':>30} ${tax:>8,.2f}") print(f"{'Total:':>30} ${total:>8,.2f}") print("=" * 40)

5. Homework Questions (Deep Thinking)

**Qu Question 1 (Code Analysis – Find the Bug):
The following code is supposed to print a report, but the output is incorrect. Identify the bugs and fix them.

name = "John" salary = 50000 bonus = 0.15 total = salary * (1 + bonus) print("Employee: " + name) print("Salary: $" + salary) print("Bonus: " + bonus * 100 + "%") print("Total: $" + total)
Sample Answer Bugs: - `+` concatenation with non‑strings causes `TypeError`. - `bonus * 100` yields a float; cannot concatenate with string. Fix by using f‑strings: ```python print(f"Employee: {name}") print(f"Salary: ${salary:,.2f}") print(f"Bonus: {bonus*100:.1f}%") print(f"Total: ${total:,.2f}") ```

Question 2 (Formatting Challenge):
Take a float input and print it as currency, scientific notation, and percentage.

Sample Answer ```python value = 1234567.891 print(f"Currency: ${value:,.2f}") print(f"Scientific: {value:.3e}") print(f"Percentage: {value*100:.2f}%") ```

Question 3 (Real-World Application – Time Display):

Write a program that:

  1. Asks the user for a number of seconds (integer).
  2. Converts it to hours, minutes, and seconds.
  3. Prints the result in a readable format using f‑strings:
  4. Use proper pluralization ("hour" vs "hours").
Sample Answer
""" TIME DISPLAY Converts seconds to hours, minutes, and seconds with proper pluralization """ print("=" * 60) print("⏱️ TIME CONVERTER") print("=" * 60) # --- Get user input --- try: total_seconds = int(input("\nEnter number of seconds: ")) if total_seconds < 0: print("⚠️ Seconds cannot be negative. Using absolute value.") total_seconds = abs(total_seconds) except ValueError: print("❌ Invalid input! Using 0 seconds.") total_seconds = 0 print(f"\nConverting {total_seconds} seconds...") print("-" * 40) # --- Method 1: Basic conversion --- print("\nMethod 1: Basic Conversion") print("-" * 30) # Calculate hours, minutes, seconds hours = total_seconds // 3600 remaining = total_seconds % 3600 minutes = remaining // 60 seconds = remaining % 60 print(f"Hours: {hours}") print(f"Minutes: {minutes}") print(f"Seconds: {seconds}") # --- Method 2: With pluralization --- print("\nMethod 2: With Pluralization") print("-" * 30) # Helper function for pluralization def pluralize(value, singular, plural=None): """Returns the appropriate singular or plural form.""" if plural is None: plural = singular + "s" return singular if value == 1 else plural # Build the time string with proper pluralization time_parts = [] if hours > 0: time_parts.append(f"{hours} {pluralize(hours, 'hour')}") if minutes > 0: time_parts.append(f"{minutes} {pluralize(minutes, 'minute')}") if seconds > 0 or not time_parts: # Show seconds if no hours/minutes time_parts.append(f"{seconds} {pluralize(seconds, 'second')}") result = ", ".join(time_parts) print(f"Result: {result}") # --- Method 3: Complete function with formatting --- print("\nMethod 3: Complete Time Display Function") print("-" * 30) def format_time(seconds): """ Converts seconds to a human-readable time string. Examples: 3665 → "1 hour, 1 minute, 5 seconds" 125 → "2 minutes, 5 seconds" 45 → "45 seconds" 0 → "0 seconds" """ if seconds == 0: return "0 seconds" hours = seconds // 3600 remaining = seconds % 3600 minutes = remaining // 60 secs = remaining % 60 parts = [] if hours > 0: parts.append(f"{hours} {'hour' if hours == 1 else 'hours'}") if minutes > 0: parts.append(f"{minutes} {'minute' if minutes == 1 else 'minutes'}") if secs > 0: parts.append(f"{secs} {'second' if secs == 1 else 'seconds'}") return ", ".join(parts) # Test with the examples test_values = [3665, 125, 45, 7200, 3600, 61, 1, 0] print("\nTest Cases:") print("-" * 30) for value in test_values: formatted = format_time(value) print(f"{value:>6} seconds → {formatted}") # --- Method 4: Advanced - With zero padding for display --- print("\nMethod 4: Time Format (HH:MM:SS)") print("-" * 30) def format_time_hhmmss(seconds): """ Formats time as HH:MM:SS with zero padding. Example: 3665 → "01:01:05" """ hours = seconds // 3600 remaining = seconds % 3600 minutes = remaining // 60 secs = remaining % 60 return f"{hours:02d}:{minutes:02d}:{secs:02d}" print(f"3665 seconds → {format_time_hhmmss(3665)}") print(f"125 seconds → {format_time_hhmmss(125)}") print(f"45 seconds → {format_time_hhmmss(45)}") # --- Interactive demo --- print("\n" + "-" * 40) print("INTERACTIVE DEMO") print("-" * 40) while True: user_input = input("\nEnter seconds (or 'quit' to exit): ").strip() if user_input.lower() == 'quit': print("Goodbye!") break try: seconds = int(user_input) if seconds < 0: print("⚠️ Please enter a positive number.") continue formatted = format_time(seconds) hhmmss = format_time_hhmmss(seconds) print(f" {seconds} seconds = {formatted}") print(f" Time format: {hhmmss}") except ValueError: print("❌ Please enter a valid integer.") print("\n" + "=" * 60) print("KEY TAKEAWAYS") print("=" * 60) print(" • Use `//` for floor division (hours, minutes)") print(" • Use `%` for remainder (remaining seconds)") print(" • Create a helper function for pluralization") print(" • Build time parts in a list and join with commas") print(" • Use `format_time_hhmmss` for clock-style display") print(" • Handle edge cases: 0, 1, negative values") print("=" * 60)

Sample Output:

============================================================ ⏱️ TIME CONVERTER ============================================================ Enter number of seconds: 3665 Converting 3665 seconds... ---------------------------------------- Method 1: Basic Conversion ------------------------------ Hours: 1 Minutes: 1 Seconds: 5 Method 2: With Pluralization ------------------------------ Result: 1 hour, 1 minute, 5 seconds Method 3: Complete Time Display Function ------------------------------ Test Cases: ------------------------------ 3665 seconds → 1 hour, 1 minute, 5 seconds 125 seconds → 2 minutes, 5 seconds 45 seconds → 45 seconds 7200 seconds → 2 hours 3600 seconds → 1 hour 61 seconds → 1 minute, 1 second 1 seconds → 1 second 0 seconds → 0 seconds Method 4: Time Format (HH:MM:SS) ------------------------------ 3665 seconds → 01:01:05 125 seconds → 00:02:05 45 seconds → 00:00:45 ---------------------------------------- INTERACTIVE DEMO ---------------------------------------- Enter seconds (or 'quit' to exit): 3665 3665 seconds = 1 hour, 1 minute, 5 seconds Time format: 01:01:05 Enter seconds (or 'quit' to exit): 125 125 seconds = 2 minutes, 5 seconds Time format: 00:02:05 Enter seconds (or 'quit' to exit): quit Goodbye! ============================================================ KEY TAKEAWAYS ============================================================ • Use `//` for floor division (hours, minutes) • Use `%` for remainder (remaining seconds) • Create a helper function for pluralization • Build time parts in a list and join with commas • Use `format_time_hhmmss` for clock-style display • Handle edge cases: 0, 1, negative values ============================================================

Explanation:

Time Conversion Logic:

  1. Hours: hours = total_seconds // 3600 (floor division)
  2. Remaining Seconds: remaining = total_seconds % 3600 (modulo)
  3. Minutes: minutes = remaining // 60
  4. Seconds: seconds = remaining % 60

Pluralization:

def pluralize(value, singular, plural=None): if plural is None: plural = singular + "s" return singular if value == 1 else plural

Building the Time String:

  1. Create a list of parts (e.g., ["1 hour", "1 minute", "5 seconds"])
  2. Join with commas: ", ".join(parts)
  3. Only include parts that are greater than 0.

Edge Cases Handled:

Question 4 (ASCII Art with print()):

Write a program that prints the following shapes using only print() statements. Use escape sequences, sep, and end where appropriate.

Shape 1:

* *** *****

Shape 2 (Diamond):

* *** ***** ******* ***** *** *

Bonus: Make the size of the diamond configurable by the user.

Sample Answer
""" ASCII ART Demonstrates print() with escape sequences and formatting """ print("=" * 60) print("🎨 ASCII ART GENERATOR") print("=" * 60) # --- Shape 1: Triangle --- print("\n" + "-" * 40) print("SHAPE 1: TRIANGLE") print("-" * 40) print("\nMethod 1: Using print() statements directly") print(" *") print(" ***") print("*****") print("\nMethod 2: Using loops") triangle_size = 3 for i in range(1, triangle_size + 1): stars = "*" * (2 * i - 1) spaces = " " * (triangle_size - i) print(spaces + stars) print("\nMethod 3: Using end parameter") for i in range(1, triangle_size + 1): stars = "*" * (2 * i - 1) spaces = " " * (triangle_size - i) # Print spaces without newline, then stars with newline print(spaces, end="") print(stars) # --- Shape 2: Diamond --- print("\n" + "-" * 40) print("SHAPE 2: DIAMOND") print("-" * 40) print("\nMethod 1: Direct print statements") print(" *") print(" ***") print(" *****") print("*******") print(" *****") print(" ***") print(" *") print("\nMethod 2: Using loops") diamond_size = 4 # Number of rows in the top half # Top half (including middle) for i in range(1, diamond_size + 1): stars = "*" * (2 * i - 1) spaces = " " * (diamond_size - i) print(spaces + stars) # Bottom half for i in range(diamond_size - 1, 0, -1): stars = "*" * (2 * i - 1) spaces = " " * (diamond_size - i) print(spaces + stars) print("\nMethod 3: Using join and list comprehension") rows = [] for i in range(1, diamond_size + 1): rows.append(" " * (diamond_size - i) + "*" * (2 * i - 1)) for i in range(diamond_size - 1, 0, -1): rows.append(" " * (diamond_size - i) + "*" * (2 * i - 1)) print("\n".join(rows)) # --- Bonus: Configurable Diamond --- print("\n" + "-" * 40) print("BONUS: CONFIGURABLE DIAMOND") print("-" * 40) def draw_diamond(size): """ Draws a diamond of the specified size. Size = number of rows in the top half. """ if size < 1: print("Size must be at least 1.") return print(f"\nDiamond of size {size}:") print("-" * 30) # Top half (including middle) for i in range(1, size + 1): spaces = " " * (size - i) stars = "*" * (2 * i - 1) print(spaces + stars) # Bottom half for i in range(size - 1, 0, -1): spaces = " " * (size - i) stars = "*" * (2 * i - 1) print(spaces + stars) # Test with different sizes draw_diamond(3) draw_diamond(4) draw_diamond(5) # --- Interactive version --- print("\n" + "-" * 40) print("INTERACTIVE VERSION") print("-" * 40) while True: try: user_input = input("\nEnter diamond size (2-10, or 'quit' to exit): ").strip() if user_input.lower() == 'quit': print("Goodbye!") break size = int(user_input) if 2 <= size <= 10: draw_diamond(size) else: print("Please enter a size between 2 and 10.") except ValueError: print("Please enter a valid integer.") print("\n" + "=" * 60) print("ADDITIONAL ASCII ART SHAPES") print("=" * 60) def draw_square(size): """Draws a square of the given size.""" print(f"\nSquare ({size}x{size}):") for i in range(size): if i == 0 or i == size - 1: print("*" * size) else: print("*" + " " * (size - 2) + "*") def draw_rectangle(width, height): """Draws a rectangle of the given dimensions.""" print(f"\nRectangle ({width}x{height}):") for i in range(height): if i == 0 or i == height - 1: print("*" * width) else: print("*" + " " * (width - 2) + "*") def draw_pyramid(height): """Draws a pyramid of the given height.""" print(f"\nPyramid (height {height}):") for i in range(1, height + 1): spaces = " " * (height - i) stars = "*" * (2 * i - 1) print(spaces + stars) def draw_hollow_diamond(size): """Draws a hollow diamond of the given size.""" print(f"\nHollow Diamond (size {size}):") # Top half (including middle) for i in range(1, size + 1): spaces = " " * (size - i) if i == 1: stars = "*" else: stars = "*" + " " * (2 * i - 3) + "*" print(spaces + stars) # Bottom half for i in range(size - 1, 0, -1): spaces = " " * (size - i) if i == 1: stars = "*" else: stars = "*" + " " * (2 * i - 3) + "*" print(spaces + stars) # Demonstrate additional shapes draw_square(5) draw_rectangle(8, 4) draw_pyramid(5) draw_hollow_diamond(5) print("\n" + "=" * 60) print("KEY TAKEAWAYS") print("=" * 60) print(" • Use `print()` with string multiplication: `'*' * 5`") print(" • Use `end=''` to prevent newlines") print(" • Use `sep=''` to remove spaces between arguments") print(" • Escape sequences: `\\n` for newline, `\\t` for tab") print(" • Loops + string multiplication create repeated patterns") print(" • `print('\\n'.join(rows))` prints multiple lines at once") print("=" * 60)

Sample Output:

============================================================ 🎨 ASCII ART GENERATOR ============================================================ ---------------------------------------- SHAPE 1: TRIANGLE ---------------------------------------- Method 1: Using print() statements directly * *** ***** Method 2: Using loops * *** ***** Method 3: Using end parameter * *** ***** ---------------------------------------- SHAPE 2: DIAMOND ---------------------------------------- Method 1: Direct print statements * *** ***** ******* ***** *** * Method 2: Using loops * *** ***** ******* ***** *** * Method 3: Using join and list comprehension * *** ***** ******* ***** *** * ---------------------------------------- BONUS: CONFIGURABLE DIAMOND ---------------------------------------- Diamond of size 3: ------------------------------ * *** ***** *** * Diamond of size 4: ------------------------------ * *** ***** ******* ***** *** * Diamond of size 5: ------------------------------ * *** ***** ******* ********* ******* ***** *** * ---------------------------------------- INTERACTIVE VERSION ---------------------------------------- Enter diamond size (2-10, or 'quit' to exit): 3 Diamond of size 3: ------------------------------ * *** ***** *** * Enter diamond size (2-10, or 'quit' to exit): quit Goodbye! ============================================================ ADDITIONAL ASCII ART SHAPES ============================================================ Square (5x5): ***** * * * * * * ***** Rectangle (8x4): ******** * * * * ******** Pyramid (height 5): * *** ***** ******* ********* Hollow Diamond (size 5): * * * * * * * * * * * * * * * * ============================================================ KEY TAKEAWAYS ============================================================ • Use `print()` with string multiplication: `'*' * 5` • Use `end=''` to prevent newlines • Use `sep=''` to remove spaces between arguments • Escape sequences: `\n` for newline, `\t` for tab • Loops + string multiplication create repeated patterns • `print('\n'.join(rows))` prints multiple lines at once ============================================================

Explanation:

Pattern Logic:

Triangle (size n):

Diamond (size n):

String Multiplication:

Key Patterns:

Hollow Diamond Pattern:

Question 5 (Advanced – Custom CSV Exporter):

Write a program that:

  1. Creates a list of dictionaries, each representing a student: {"name": "Alice", "math": 85, "science": 92, "english": 78}.

  2. Uses print() to generate a CSV‑formatted output:

    Name,Math,Science,English Alice,85,92,78 Bob,90,88,95 Charlie,76,82,89
  3. Use sep="," and loops to print each row.

  4. Bonus: Write the output to a file using the file parameter.

Sample Answer
""" CUSTOM CSV EXPORTER Demonstrates CSV generation using print() with sep parameter """ import csv print("=" * 60) print("📊 CUSTOM CSV EXPORTER") print("=" * 60) # --- Step 1: Create student data --- students = [ {"name": "Alice", "math": 85, "science": 92, "english": 78}, {"name": "Bob", "math": 90, "science": 88, "english": 95}, {"name": "Charlie", "math": 76, "science": 82, "english": 89}, {"name": "Diana", "math": 94, "science": 87, "english": 91}, {"name": "Eve", "math": 88, "science": 79, "english": 84} ] print("\nStudent Data:") for student in students: print(f" {student}") print("\n" + "-" * 40) print("METHOD 1: Basic CSV Export (Console)") print("-" * 40) # --- Step 2: Export as CSV to console --- def export_csv_console(data, fields=None): """ Exports data as CSV to the console using print() with sep=','. """ if not data: return # Determine fields (headers) if fields is None: fields = list(data[0].keys()) # Print header print(*fields, sep=",") # Print each row for row in data: # Get values in the same order as fields values = [str(row.get(field, "")) for field in fields] print(*values, sep=",") print("\nCSV Output:") export_csv_console(students) print("\n" + "-" * 40) print("METHOD 2: CSV Export with Different Formats") print("-" * 40) # Export with custom ordering custom_fields = ["name", "english", "math", "science"] print("\nCustom field order:") export_csv_console(students, custom_fields) # --- Step 3: Bonus - Export to file --- print("\n" + "-" * 40) print("BONUS: EXPORT TO FILE") print("-" * 40) def export_csv_file(data, filename="students.csv", fields=None): """ Exports data as CSV to a file using print() with file parameter. """ if not data: return if fields is None: fields = list(data[0].keys()) # Open file for writing with open(filename, 'w', encoding='utf-8') as file: # Print header to file print(*fields, sep=",", file=file) # Print each row to file for row in data: values = [str(row.get(field, "")) for field in fields] print(*values, sep=",", file=file) print(f"✅ Data exported to '{filename}'") # Export to file export_csv_file(students, "students.csv") # --- Step 4: Advanced - Using csv module --- print("\n" + "-" * 40) print("METHOD 3: Using csv Module (Standard Library)") print("-" * 40) def export_csv_module(data, filename="students_module.csv", fields=None): """ Exports data as CSV using the csv module. """ if not data: return if fields is None: fields = list(data[0].keys()) with open(filename, 'w', newline='', encoding='utf-8') as file: writer = csv.DictWriter(file, fieldnames=fields) writer.writeheader() writer.writerows(data) print(f"✅ Data exported to '{filename}' using csv module") export_csv_module(students, "students_module.csv") # --- Step 5: Display the exported file content --- print("\n" + "-" * 40) print("VERIFICATION: File Content") print("-" * 40) try: with open("students.csv", 'r', encoding='utf-8') as file: content = file.read() print("\nContent of students.csv:") print("-" * 30) print(content) except FileNotFoundError: print("File not found.") # --- Step 6: Advanced features --- print("\n" + "-" * 40) print("METHOD 4: Advanced CSV Features") print("-" * 40) def export_csv_advanced(data, filename="advanced.csv", fields=None, delimiter=","): """ Advanced CSV export with customizable delimiter. """ if not data: return if fields is None: fields = list(data[0].keys()) with open(filename, 'w', encoding='utf-8') as file: # Print header print(*fields, sep=delimiter, file=file) # Print rows with data type handling for row in data: values = [] for field in fields: value = row.get(field, "") # Handle different data types if isinstance(value, str): # Quote strings that contain the delimiter if delimiter in value or '"' in value: value = f'"{value}"' values.append(str(value)) print(*values, sep=delimiter, file=file) print(f"✅ Advanced data exported to '{filename}'") export_csv_advanced(students, "advanced.csv", delimiter=";") # --- Step 7: Auto-detected fields --- print("\n" + "-" * 40) print("METHOD 5: Auto-detected Fields") print("-" * 40) def auto_detect_fields(data): """Automatically detect all unique field names.""" fields = set() for row in data: fields.update(row.keys()) return sorted(list(fields)) # Create data with different fields mixed_data = [ {"name": "Alice", "math": 85, "science": 92}, {"name": "Bob", "math": 90, "english": 95}, {"name": "Charlie", "science": 82, "english": 89, "history": 78} ] print("\nMixed data with different fields:") for row in mixed_data: print(f" {row}") print("\nAuto-detected fields:", auto_detect_fields(mixed_data)) print("\nCSV Output with auto-detected fields:") export_csv_console(mixed_data, auto_detect_fields(mixed_data)) # --- Step 8: CSV with summary statistics --- print("\n" + "-" * 40) print("METHOD 6: CSV with Summary Statistics") print("-" * 40) def export_csv_with_stats(data, filename="students_stats.csv"): """Exports CSV with summary statistics appended.""" if not data: return fields = list(data[0].keys()) fields_without_name = [f for f in fields if f != "name"] with open(filename, 'w', encoding='utf-8') as file: # Header print(*fields, sep=",", file=file) # Data rows for row in data: values = [str(row.get(field, "")) for field in fields] print(*values, sep=",", file=file) # Summary statistics print("\n--- Summary Statistics ---", file=file) print("Field,Average,Min,Max", file=file) for field in fields_without_name: values = [row[field] for row in data if field in row] if values: avg = sum(values) / len(values) min_val = min(values) max_val = max(values) print(f"{field},{avg:.2f},{min_val},{max_val}", file=file) export_csv_with_stats(students, "students_stats.csv") print("✅ CSV with statistics exported to 'students_stats.csv'") print("\n" + "=" * 60) print("KEY TAKEAWAYS") print("=" * 60) print(" • Use `print(*list, sep=',')` to print CSV rows") print(" • Use `file` parameter to write to a file") print(" • Use `csv` module for more robust CSV handling") print(" • Fields are the dictionary keys") print(" • Values are extracted in field order") print(" • Strings containing commas should be quoted") print(" • `with open(...) as file:` ensures proper file closing") print(" • `csv.DictWriter` is the professional approach") print("=" * 60)

Sample Output:

============================================================ 📊 CUSTOM CSV EXPORTER ============================================================ Student Data: {'name': 'Alice', 'math': 85, 'science': 92, 'english': 78} {'name': 'Bob', 'math': 90, 'science': 88, 'english': 95} {'name': 'Charlie', 'math': 76, 'science': 82, 'english': 89} {'name': 'Diana', 'math': 94, 'science': 87, 'english': 91} {'name': 'Eve', 'math': 88, 'science': 79, 'english': 84} ---------------------------------------- METHOD 1: Basic CSV Export (Console) ---------------------------------------- CSV Output: Name,Math,Science,English Alice,85,92,78 Bob,90,88,95 Charlie,76,82,89 Diana,94,87,91 Eve,88,79,84 ---------------------------------------- METHOD 2: CSV Export with Different Formats ---------------------------------------- Custom field order: name,english,math,science Alice,78,85,92 Bob,95,90,88 Charlie,89,76,82 Diana,91,94,87 Eve,84,88,79 ---------------------------------------- BONUS: EXPORT TO FILE ---------------------------------------- ✅ Data exported to 'students.csv' ---------------------------------------- METHOD 3: Using csv Module (Standard Library) ---------------------------------------- ✅ Data exported to 'students_module.csv' using csv module ---------------------------------------- VERIFICATION: File Content ---------------------------------------- Content of students.csv: ------------------------------ Name,Math,Science,English Alice,85,92,78 Bob,90,88,95 Charlie,76,82,89 Diana,94,87,91 Eve,88,79,84 ---------------------------------------- METHOD 4: Advanced CSV Features ---------------------------------------- ✅ Advanced data exported to 'advanced.csv' ---------------------------------------- METHOD 5: Auto-detected Fields ---------------------------------------- Mixed data with different fields: {'name': 'Alice', 'math': 85, 'science': 92} {'name': 'Bob', 'math': 90, 'english': 95} {'name': 'Charlie', 'science': 82, 'english': 89, 'history': 78} Auto-detected fields: ['english', 'history', 'math', 'name', 'science'] CSV Output with auto-detected fields: english,history,math,name,science ,,85,Alice,92 95,,90,Bob, 89,78,,Charlie,82 ---------------------------------------- METHOD 6: CSV with Summary Statistics ---------------------------------------- ✅ CSV with statistics exported to 'students_stats.csv' ============================================================ KEY TAKEAWAYS ============================================================ • Use `print(*list, sep=',')` to print CSV rows • Use `file` parameter to write to a file • Use `csv` module for more robust CSV handling • Fields are the dictionary keys • Values are extracted in field order • Strings containing commas should be quoted • `with open(...) as file:` ensures proper file closing • `csv.DictWriter` is the professional approach ============================================================

Explanation:

CSV Export Methods:

Method 1: Using print() with sep=","

# Header print(*fields, sep=",") # Row print(*values, sep=",")

Method 2: Using print() with file parameter

with open(filename, 'w') as file: print(*fields, sep=",", file=file) for row in data: print(*values, sep=",", file=file)

Method 3: Using csv module (Professional)

import csv with open(filename, 'w', newline='') as file: writer = csv.DictWriter(file, fieldnames=fields) writer.writeheader() writer.writerows(data)

Key Concepts:

  1. Fields (Headers): The dictionary keys become the CSV headers.

  2. Value Extraction: Values are extracted in the same order as fields.

  3. String Conversion: All values are converted to strings.

  4. Quoting: Values containing commas or quotes should be quoted.

  5. File Handling: Use with statement for proper file closure.

  6. Delimiter: Default is comma, but can be changed (e.g., semicolon).

CSV Module vs Manual:

Feature Manual print() csv Module
Simplicity Simple for basic needs More complex but robust
Quoting Manual handling Automatic
Delimiters Manual Configurable
Edge Cases Prone to errors Handles correctly
Professional Less professional Standard approach

Why Quote Strings?

# Without quotes: "Alice" → Alice (okay) # With comma: "Smith, John" → Smith, John (problem!) # Quoted: "Smith, John" → "Smith, John" (correct)

6. Summary Checklist (For Student Self-Review)

7. Additional Challenge: The Report Generator

Learning Objective

Write a program that generates a full sales report from user input.

Instructions:

  1. Ask the user for:
  2. For each product (1 to N), ask for:
  3. Calculate for each product:
  4. Calculate overall totals (all products combined).
  5. Print a professional report with:

Sample Output:

============================================================= ACME CORPORATION SALES REPORT - 2026-08-11 ============================================================= Product Qty Unit Price Subtotal Tax Total ----------------------------------------------------------------------- Laptop 2 $1,299.99 $2,599.98 $208.00 $2,807.98 Monitor 3 $349.50 $1,048.50 $83.88 $1,132.38 Keyboard 5 $59.99 $299.95 $24.00 $323.95 ----------------------------------------------------------------------- TOTAL: $3,948.43 $315.88 $4,264.31 ============================================================= Report generated on 2026-08-11 14:30:25

Hint: Use loops, lists to store product data, and f‑strings with alignment for the table.

Previous | Tutorial index | Next