Chapter 6 Code Best Practices: Generate & Review Code

6.1 The Generate-Review-Refine Workflow

Every time you ask Claude for code:

GENERATE → REVIEW → REFINE

Don’t use first answer immediately.

6.2 Phase 1: Generate

Ask Claude for code with full context:

Language: Python 3.10
Task: Function to calculate customer lifetime value

Requirements:
- Input: list of transaction amounts
- Output: single float (LTV)
- Exclude transactions: < $0, > $10000 (likely errors)
- Calculation: sum of valid transactions * 12 months

Example:
Input: [100, 150, 90, -50, 15000]
Output: 3420.0  (sum of [100,150,90] * 12)

6.3 Phase 2: Review - The Quality Checklist

After Claude generates code, ask yourself:

6.3.1 ✅ Does It Work?

# Copy the code
# Run it immediately
# Test with examples

6.3.2 ✅ Is It Readable?

Good variable names?

# GOOD
def calculate_customer_ltv(transactions):
    valid = [t for t in transactions if 0 <= t <= 10000]
    return sum(valid) * 12

# BAD
def f(x):
    y = [a for a in x if a > 0 and a < 10000]
    return sum(y) * 12

Clear logic?

# GOOD - steps are obvious
transactions = read_transactions()
valid_transactions = filter_outliers(transactions)
ltv = calculate_ltv(valid_transactions)
return ltv

# BAD - what's happening?
return sum([t for t in read_transactions() if 0<t<10000])*12

6.3.3 ✅ Does It Handle Edge Cases?

Ask yourself: - What if input is empty? → errors or returns None? - What if input is invalid type? → crashes or handles gracefully? - What if numbers are very large? → overflow issues? - What if data is missing? → NaN/None handling?

Example:

# WORSE - no error handling
def calculate_ltv(transactions):
    return sum(transactions) * 12

# BETTER - handles edge cases
def calculate_ltv(transactions):
    """Calculate customer lifetime value."""
    if not transactions:
        return None
    
    if not isinstance(transactions, (list, tuple)):
        raise TypeError("transactions must be list or tuple")
    
    valid = [
        t for t in transactions 
        if isinstance(t, (int, float)) and 0 <= t <= 10000
    ]
    
    return sum(valid) * 12 if valid else None

6.3.4 ✅ Is It Efficient?

  • Does it make unnecessary loops?
  • Could it use built-in functions?
  • Will it work with large datasets?
# INEFFICIENT
def clean_data(df):
    for i in range(len(df)):
        df.iloc[i, 0] = df.iloc[i, 0].lower()

# EFFICIENT
def clean_data(df):
    df[df.columns[0]] = df[df.columns[0]].str.lower()

6.3.5 ✅ Is It Documented?

# GOOD
def calculate_ltv(transactions: list[float]) -> float:
    """
    Calculate customer lifetime value from transaction history.
    
    Args:
        transactions: List of transaction amounts (floats)
        
    Returns:
        float: Estimated annual value (sum * 12)
        
    Raises:
        TypeError: If transactions is not a list
        
    Example:
        >>> calculate_ltv([100, 150, 90])
        4440.0
    """
    ...

# OKAY
def calculate_ltv(transactions):
    # Returns annual LTV
    return sum(transactions) * 12

# BAD
def f(x):
    return sum(x) * 12

6.3.6 ✅ Does It Follow Standards?

Check your team/project standards: - Naming conventions? (snake_case vs camelCase) - Type hints? - Comments on complex logic? - Docstring style?

6.4 Phase 3: Refine

Ask Claude to improve it:

Good start! Can you:
1. Add error handling for edge cases
2. Add type hints
3. Add docstring with examples
4. Make it more efficient
5. Add logging for debugging

6.5 Code Quality Checklist

Before shipping code, verify:

6.5.1 Functionality ✓

6.5.2 Readability ✓

6.5.3 Robustness ✓

6.5.4 Documentation ✓

6.5.5 Performance ✓

6.5.6 Maintainability ✓

6.6 Common Code Problems Claude Might Miss

6.6.1 ❌ Problem 1: Mutating Input

# WRONG - modifies input list!
def process(items):
    items.sort()
    return items[0]

# RIGHT - works on copy
def process(items):
    sorted_items = sorted(items)
    return sorted_items[0]

6.6.2 ❌ Problem 2: Hardcoded Paths

# WRONG - only works on one computer
df = pd.read_csv('/Users/name/data.csv')

# RIGHT - relative path
df = pd.read_csv('../data/customers.csv')

6.6.3 ❌ Problem 3: Missing Imports

# Claude writes code using 'os'
# But forgot to import it
import pandas as pd
# missing: import os

file_path = os.path.join('data', 'file.csv')  # ERROR!

6.6.4 ❌ Problem 4: Silent Failures

# WRONG - silently returns None if error
def get_value(data, key):
    try:
        return data[key]
    except:
        pass  # What error? Where? Lost forever.

# RIGHT - logs or raises
def get_value(data, key):
    try:
        return data[key]
    except KeyError as e:
        raise ValueError(f"Missing required key: {key}") from e

6.7 Asking Claude for Code Review

I have this function:

[paste code]

Code review:
1. Does it work correctly?
2. What edge cases am I missing?
3. How would you improve it?
4. Any performance concerns?
5. Any security concerns?

6.8 Exercise: Review Real Code

Take code Claude generated for you:

  1. Run it - Does it work?
  2. Check readability - Would others understand it?
  3. Test edge cases - Does it break?
  4. Review documentation - Is it clear?
  5. Ask Claude to improve - Iterate

Save the before/after. Notice the improvements!

6.9 Key Takeaways

✅ Generate → Review → Refine workflow
✅ Don’t use first answer immediately
✅ Check: Works? Readable? Robust? Documented?
✅ Test edge cases actively
✅ Follow your team’s standards
✅ Ask Claude to iterate