Python String Formatting

Master advanced string formatting techniques for professional Python development

šŸŽØ String Formatting Mastery

String formatting is essential for creating dynamic, readable output in Python. From simple variable insertion to complex formatting patterns, mastering these techniques will make your code more professional and maintainable.


# Modern f-string formatting
name = "Alice"
age = 30
message = f"Hello {name}, you are {age} years old!"
print(message)  # Hello Alice, you are 30 years old!
                                    
3
Methods
Modern
F-Strings
Powerful
Formatting

String Formatting Methods

1ļøāƒ£

% Formatting (Legacy)

Python 2 style - still works but not recommended

"Hello %s" % name
2ļøāƒ£

.format() Method

Python 2.7+ and 3.x - powerful and flexible

"Hello {}".format(name)
3ļøāƒ£

f-Strings (Recommended)

Python 3.6+ - fast, readable, and powerful

f"Hello {name}"

F-Strings: The Modern Way

F-strings (formatted string literals) are the most readable and efficient way to format strings in Python 3.6+.

F-String Basics

šŸ”¹ Basic Variable Usage

# Basic f-string usage
name = "Alice"
age = 30

greeting = f"Hello, {name}!"
print(greeting)  # Hello, Alice!

šŸ”¹ Working with Multiple Variables

city = "New York"
info = f"{name} is {age} years old and lives in {city}"
print(info)  # Alice is 30 years old and lives in New York

šŸ”¹ Expressions in F-strings

# Math and comparisons
print(f"{name} will be {age + 1} next year")
print(f"Is {name} an adult? {age >= 18}")
print(f"Name length: {len(name)} characters")

šŸ”¹ String Methods

# Using string methods
print(f"Uppercase name: {name.upper()}")
print(f"City in lowercase: {city.lower()}")

šŸ”¹ Math Operations

# Basic calculations
x, y = 10, 20
print(f"Sum: {x} + {y} = {x + y}")
print(f"Average: ({x} + {y}) / 2 = {(x + y) / 2}")

šŸ”¹ Conditional Formatting

# Using if-else in f-strings
status = "Adult" if age >= 18 else "Minor"
print(f"{name} is an {status}")

šŸ”¹ Mixed Data Types

# Numbers and currency
price = 19.99
quantity = 3
total = price * quantity
print(f"Item: ${price}, Quantity: {quantity}, Total: ${total}")

šŸ”¹ Boolean Values

# Working with booleans
is_student = True
print(f"Student status: {is_student}")
print(f"Discount eligible: {'Yes' if is_student else 'No'}")

Advanced F-String Formatting

Number Formatting
import math

# Decimal places
pi = math.pi
print(f"Pi: {pi}")                    # Pi: 3.141592653589793
print(f"Pi (2 decimals): {pi:.2f}")   # Pi (2 decimals): 3.14
print(f"Pi (4 decimals): {pi:.4f}")   # Pi (4 decimals): 3.1416

# Percentage formatting
ratio = 0.1234
print(f"Ratio: {ratio:.1%}")          # Ratio: 12.3%
print(f"Ratio: {ratio:.2%}")          # Ratio: 12.34%

# Scientific notation
large_number = 1234567890
print(f"Scientific: {large_number:.2e}")  # Scientific: 1.23e+09

# Thousands separator
salary = 75000
print(f"Salary: ${salary:,}")         # Salary: $75,000
print(f"Salary: ${salary:,.2f}")      # Salary: $75,000.00

# Binary, octal, hexadecimal
number = 255
print(f"Decimal: {number}")           # Decimal: 255
print(f"Binary: {number:b}")          # Binary: 11111111
print(f"Octal: {number:o}")           # Octal: 377
print(f"Hex: {number:x}")             # Hex: ff
print(f"Hex (uppercase): {number:X}") # Hex (uppercase): FF

# Padding and alignment
value = 42
print(f"Zero padded: {value:05d}")    # Zero padded: 00042
print(f"Space padded: {value:5d}")    # Space padded:    42

# Sign formatting
positive = 42
negative = -42
print(f"Always show sign: {positive:+d}")  # Always show sign: +42
print(f"Always show sign: {negative:+d}")  # Always show sign: -42
print(f"Space for positive: {positive: d}") # Space for positive:  42
String Alignment and Padding
# String alignment examples
name = "Python"
print(f"Original: '{name}'")

# Left alignment (default for strings)
print(f"Left aligned: '{name:<15}'")      # Left aligned: 'Python         '

# Right alignment
print(f"Right aligned: '{name:>15}'")     # Right aligned: '         Python'

# Center alignment
print(f"Center aligned: '{name:^15}'")    # Center aligned: '    Python     '

# Custom padding character
print(f"Custom padding: '{name:*^15}'")   # Custom padding: '****Python*****'
print(f"Dash padding: '{name:-^15}'")     # Dash padding: '----Python-----'

# Truncation (limiting string length)
long_text = "This is a very long string"
print(f"Truncated: '{long_text:.10}'")    # Truncated: 'This is a '

# Creating formatted tables
print("\nšŸ“Š FORMATTED TABLE EXAMPLE:")
print("="*50)

# Sample data
employees = [
    {"name": "Alice Johnson", "dept": "Engineering", "salary": 95000},
    {"name": "Bob Smith", "dept": "Marketing", "salary": 65000},
    {"name": "Carol Davis", "dept": "HR", "salary": 55000},
    {"name": "David Wilson", "dept": "Sales", "salary": 70000}
]

# Table header
print(f"{'Name':<15} {'Department':<12} {'Salary':>10}")
print("-" * 40)

# Table rows
for emp in employees:
    print(f"{emp['name']:<15} {emp['dept']:<12} ${emp['salary']:>9,}")

print("="*50)

Date and Time Formatting

DateTime Formatting with F-Strings
from datetime import datetime, date, time

# Current date and time
now = datetime.now()
today = date.today()

print("šŸ“… DATE AND TIME FORMATTING")
print("="*40)

# Basic date formatting
print(f"Current date: {today}")
print(f"Current datetime: {now}")

# Custom date formats
print(f"US format: {now:%m/%d/%Y}")           # 12/25/2024
print(f"European format: {now:%d/%m/%Y}")     # 25/12/2024
print(f"ISO format: {now:%Y-%m-%d}")          # 2024-12-25
print(f"Long format: {now:%B %d, %Y}")        # December 25, 2024
print(f"Short format: {now:%b %d, %Y}")       # Dec 25, 2024

# Time formatting
print(f"24-hour time: {now:%H:%M:%S}")        # 14:30:45
print(f"12-hour time: {now:%I:%M:%S %p}")     # 02:30:45 PM
print(f"Time only: {now:%H:%M}")              # 14:30

# Day and month names
print(f"Full day: {now:%A}")                  # Wednesday
print(f"Short day: {now:%a}")                 # Wed
print(f"Full month: {now:%B}")                # December
print(f"Short month: {now:%b}")               # Dec

# Week and year information
print(f"Week number: {now:%U}")               # Week number (Sunday start)
print(f"Day of year: {now:%j}")               # Day of year (1-366)
print(f"Year: {now:%Y}")                      # 2024
print(f"Short year: {now:%y}")                # 24

# Custom datetime formatting
birthday = datetime(1990, 5, 15, 14, 30, 0)
print(f"\nšŸŽ‚ BIRTHDAY EXAMPLE:")
print(f"Birthday: {birthday:%A, %B %d, %Y at %I:%M %p}")
# Output: Tuesday, May 15, 1990 at 02:30 PM

# Age calculation with formatting
age_days = (now - birthday).days
age_years = age_days // 365
print(f"Age: {age_years} years ({age_days:,} days)")

# Creating timestamps
print(f"\nā° TIMESTAMPS:")
print(f"Timestamp: {now:%Y%m%d_%H%M%S}")      # 20241225_143045
print(f"Log format: {now:%Y-%m-%d %H:%M:%S}") # 2024-12-25 14:30:45
print(f"Filename safe: {now:%Y-%m-%d_%H-%M-%S}") # 2024-12-25_14-30-45

The .format() Method

While f-strings are preferred, the .format() method is still widely used and offers some unique features.

.format() Method Examples
# Basic .format() usage
name = "Alice"
age = 30

# Positional arguments
print("Hello, {}! You are {} years old.".format(name, age))

# Indexed arguments
print("Hello, {0}! You are {1} years old. {0} is awesome!".format(name, age))

# Named arguments
print("Hello, {name}! You are {age} years old.".format(name=name, age=age))

# Mixed arguments
print("Hello, {0}! You are {age} years old.".format(name, age=age))

print("\n" + "="*50)

# Number formatting with .format()
pi = 3.14159265359
salary = 75000

print("Pi: {:.2f}".format(pi))                    # Pi: 3.14
print("Pi: {:.4f}".format(pi))                    # Pi: 3.1416
print("Salary: ${:,}".format(salary))             # Salary: $75,000
print("Salary: ${:,.2f}".format(salary))          # Salary: $75,000.00

# Percentage
ratio = 0.1234
print("Ratio: {:.1%}".format(ratio))              # Ratio: 12.3%

# Alignment and padding
text = "Python"
print("Left: '{:<10}'".format(text))              # Left: 'Python    '
print("Right: '{:>10}'".format(text))             # Right: '    Python'
print("Center: '{:^10}'".format(text))            # Center: '  Python  '
print("Custom: '{:*^10}'".format(text))           # Custom: '**Python**'

print("\n" + "="*50)

# Advanced .format() features
data = {
    'name': 'Bob',
    'age': 25,
    'city': 'Boston'
}

# Dictionary unpacking
print("Name: {name}, Age: {age}, City: {city}".format(**data))

# Attribute access
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person = Person("Charlie", 35)
print("Person: {p.name} is {p.age} years old".format(p=person))

# List/tuple indexing
colors = ['red', 'green', 'blue']
print("Colors: {0[0]}, {0[1]}, {0[2]}".format(colors))

# Complex formatting template
template = """
šŸ“‹ EMPLOYEE REPORT
==================
Name: {name:<20}
Department: {dept:<15}
Salary: ${salary:>10,}
Performance: {performance:^10}
Bonus: {bonus:.1%}
"""

employee = {
    'name': 'Diana Prince',
    'dept': 'Engineering',
    'salary': 95000,
    'performance': 'Excellent',
    'bonus': 0.15
}

print(template.format(**employee))

Template Strings

Python's Template class provides a simpler way to do string substitutions, especially useful for user-generated templates.

Template String Examples
from string import Template

# Basic template usage
template = Template("Hello, $name! Welcome to $place.")
result = template.substitute(name="Alice", place="Python World")
print(result)  # Hello, Alice! Welcome to Python World.

# Using dictionary for substitution
data = {'name': 'Bob', 'place': 'the conference'}
result = template.substitute(data)
print(result)  # Hello, Bob! Welcome to the conference.

# Safe substitution (won't raise error for missing variables)
incomplete_template = Template("Hello, $name! Your score is $score.")
result = incomplete_template.safe_substitute(name="Charlie")
print(result)  # Hello, Charlie! Your score is $score.

print("\n" + "="*50)

# Email template example
email_template = Template("""
Dear $customer_name,

Thank you for your order #$order_id placed on $order_date.

Order Details:
- Product: $product_name
- Quantity: $quantity
- Total: $$total

Your order will be shipped to:
$shipping_address

Estimated delivery: $delivery_date

Best regards,
$company_name Customer Service
""")

# Email data
email_data = {
    'customer_name': 'John Smith',
    'order_id': 'ORD-12345',
    'order_date': '2024-01-15',
    'product_name': 'Python Programming Book',
    'quantity': 2,
    'total': '49.99',
    'shipping_address': '123 Main St, Anytown, USA',
    'delivery_date': '2024-01-20',
    'company_name': 'BookStore Inc.'
}

email_content = email_template.substitute(email_data)
print("šŸ“§ EMAIL TEMPLATE EXAMPLE:")
print(email_content)

print("\n" + "="*50)

# Configuration file template
config_template = Template("""
# Application Configuration
[database]
host = $db_host
port = $db_port
username = $db_user
password = $db_pass
database = $db_name

[server]
host = $server_host
port = $server_port
debug = $debug_mode

[logging]
level = $log_level
file = $log_file
""")

config_data = {
    'db_host': 'localhost',
    'db_port': '5432',
    'db_user': 'admin',
    'db_pass': 'secret123',
    'db_name': 'myapp',
    'server_host': '0.0.0.0',
    'server_port': '8000',
    'debug_mode': 'False',
    'log_level': 'INFO',
    'log_file': '/var/log/myapp.log'
}

config_content = config_template.substitute(config_data)
print("āš™ļø CONFIGURATION TEMPLATE:")
print(config_content)

Real-World Example: Report Generator

Let's create a comprehensive report generator that demonstrates various string formatting techniques:

Advanced Report Generator
from datetime import datetime, timedelta
from string import Template

class ReportGenerator:
    """Advanced report generator with multiple formatting techniques."""
    
    def __init__(self):
        self.company_name = "TechCorp Solutions"
        self.report_date = datetime.now()
    
    def format_currency(self, amount):
        """Format currency with proper symbols and separators."""
        return f"${amount:,.2f}"
    
    def format_percentage(self, value, decimals=1):
        """Format percentage values."""
        return f"{value:.{decimals}%}"
    
    def format_large_number(self, number):
        """Format large numbers with appropriate suffixes."""
        if number >= 1_000_000_000:
            return f"{number/1_000_000_000:.1f}B"
        elif number >= 1_000_000:
            return f"{number/1_000_000:.1f}M"
        elif number >= 1_000:
            return f"{number/1_000:.1f}K"
        else:
            return f"{number:,}"
    
    def create_header(self, title, width=80):
        """Create a formatted header for reports."""
        border = "=" * width
        title_line = f"{title:^{width}}"
        date_line = f"Generated: {self.report_date:%Y-%m-%d %H:%M:%S}".center(width)
        company_line = f"{self.company_name}".center(width)
        
        return f"""
{border}
{title_line}
{company_line}
{date_line}
{border}
"""
    
    def create_sales_summary(self, sales_data):
        """Create a sales summary report using f-strings."""
        total_revenue = sum(item['revenue'] for item in sales_data)
        total_units = sum(item['units_sold'] for item in sales_data)
        avg_price = total_revenue / total_units if total_units > 0 else 0
        
        # Find best performer
        best_product = max(sales_data, key=lambda x: x['revenue'])
        
        report = self.create_header("SALES SUMMARY REPORT")
        
        report += f"""
šŸ“Š EXECUTIVE SUMMARY
{'-' * 40}
Total Revenue: {self.format_currency(total_revenue)}
Total Units Sold: {total_units:,}
Average Price per Unit: {self.format_currency(avg_price)}
Number of Products: {len(sales_data)}

šŸ† TOP PERFORMER
Product: {best_product['product_name']}
Revenue: {self.format_currency(best_product['revenue'])}
Units Sold: {best_product['units_sold']:,}

šŸ“‹ DETAILED BREAKDOWN
{'-' * 40}
"""
        
        # Create detailed table
        for item in sorted(sales_data, key=lambda x: x['revenue'], reverse=True):
            market_share = item['revenue'] / total_revenue
            report += f"{item['product_name']:<25} "
            report += f"{item['units_sold']:>8,} units "
            report += f"{self.format_currency(item['revenue']):>12} "
            report += f"({self.format_percentage(market_share):>6})\n"
        
        return report

# Demo usage
def main():
    """Demonstrate the report generator."""
    generator = ReportGenerator()
    
    # Sample sales data
    sales_data = [
        {'product_name': 'Python Course', 'units_sold': 1250, 'revenue': 124987.50},
        {'product_name': 'JavaScript Bootcamp', 'units_sold': 890, 'revenue': 133490.10},
        {'product_name': 'Data Science Kit', 'units_sold': 675, 'revenue': 101250.00},
        {'product_name': 'Web Dev Bundle', 'units_sold': 1100, 'revenue': 87450.00},
        {'product_name': 'Mobile App Course', 'units_sold': 450, 'revenue': 67500.00}
    ]
    
    # Generate and print report
    report = generator.create_sales_summary(sales_data)
    print(report)
    
    # Demonstrate different formatting techniques
    print("\nšŸŽÆ FORMATTING TECHNIQUES DEMO")
    print("=" * 50)
    
    # F-string examples
    product = "Python Mastery Course"
    price = 199.99
    discount = 0.20
    final_price = price * (1 - discount)
    
    print(f"Product: {product}")
    print(f"Original Price: ${price:.2f}")
    print(f"Discount: {discount:.0%}")
    print(f"Final Price: ${final_price:.2f}")
    print(f"You save: ${price - final_price:.2f}")
    
    # .format() method example
    template = "Customer {name} purchased {product} for {price:.2f} on {date:%B %d, %Y}"
    purchase_info = template.format(
        name="Alice Johnson",
        product=product,
        price=final_price,
        date=datetime.now()
    )
    print(f"\nPurchase Info: {purchase_info}")
    
    # Template string example
    email_template = Template("""
    Dear $customer_name,
    
    Thank you for purchasing $product_name for $$price.
    Your order will be processed within 24 hours.
    
    Best regards,
    The Python Learning Team
    """)
    
    email = email_template.substitute(
        customer_name="Alice Johnson",
        product_name=product,
        price=f"{final_price:.2f}"
    )
    print(f"\nEmail Preview:{email}")

if __name__ == "__main__":
    main()

šŸ‹ļø Practice Exercise: Invoice Generator

Create an invoice generator that uses all three formatting methods:

  1. Use f-strings for calculations and basic formatting
  2. Use .format() for table creation
  3. Use Template strings for the invoice template
  4. Include proper number formatting, alignment, and date formatting
Invoice Generator Challenge
# Your task: Complete this invoice generator

from datetime import datetime
from string import Template

def generate_invoice(customer_info, items, tax_rate=0.08):
    """
    Generate a professional invoice using multiple formatting methods.
    
    Args:
        customer_info: dict with customer details
        items: list of dicts with item details
        tax_rate: tax rate as decimal (default 8%)
    """
    
    # TODO: Use f-strings for calculations
    subtotal = 0  # Calculate from items
    tax_amount = 0  # Calculate tax
    total = 0  # Calculate total
    
    # TODO: Use .format() method for table formatting
    table_header = "| {:<20} | {:>8} | {:>10} | {:>12} |"
    table_row = "| {:<20} | {:>8} | {:>10.2f} | {:>12.2f} |"
    
    # TODO: Use Template for invoice structure
    invoice_template = Template("""
    INVOICE #$invoice_number
    Date: $date
    
    Bill To:
    $customer_name
    $customer_address
    
    $items_table
    
    Subtotal: $$subtotal
    Tax ($tax_rate%): $$tax_amount
    Total: $$total
    """)
    
    # Your implementation here
    pass

# Test data
customer = {
    'name': 'John Smith',
    'address': '123 Main St\nAnytown, USA 12345'
}

items = [
    {'name': 'Python Course', 'quantity': 1, 'price': 199.99},
    {'name': 'JavaScript Book', 'quantity': 2, 'price': 49.99},
    {'name': 'Coding Bootcamp', 'quantity': 1, 'price': 999.99}
]

# Generate invoice
invoice = generate_invoice(customer, items)
print(invoice)

🧠 Test Your Knowledge

Which string formatting method is recommended for Python 3.6+?

What does f"{value:.2f}" do?

Which formatting method is safest for user-generated templates?