From Legacy to Lovely: 15 AI Prompts That Turn Messy Python into Masterpiece Code

Let's be honest: your codebase has skeletons. That 2,000-line process_data() function? The one with 14 nested ifs and a variable named tmp2? It's been haunting you for months. You know it needs a refactor, but the thought of untangling that spaghetti is enough to make you open LinkedIn and browse "Senior Python Developer" roles instead.

But here's the thing: you don't have to do it alone anymore. I've spent the last year using AI copilots (ChatGPT, Claude, and GitHub Copilot) to refactor everything from small scripts to a 200k-line Django monolith. The results? Honestly, they've been game-changing. I've cut refactoring time by 70% and, more importantly, I've eliminated the fear of touching legacy code. The key isn't just throwing code at an AI and hoping for the best—it's about crafting precise, context-rich prompts that turn the AI into a senior engineer who's laser-focused on your specific problem.

This isn't a list of generic "improve this code" prompts. These are battle-tested, real-world prompts I use daily. Each one targets a specific refactoring goal, from breaking down god functions to introducing type hints and optimizing algorithms. I'll show you the exact prompt, a before/after example, and why it works. By the end, you'll have a toolkit that turns your messy, legacy Python into code you're actually proud to show off.

The AI Refactoring Playbook: 15 Prompts That Deliver Results

1. The God Function Butcher

Goal: Break a monolithic function into smaller, single-responsibility functions.

Why it works: This prompt gives the AI a clear role, a specific problem (code smell), and constraints (preserve behavior, suggest names). It forces the AI to think like a human architect, not just a code formatter.

Prompt:

You are a senior Python developer. Analyze the following function for the "God Object" code smell (too many responsibilities). Break it down into smaller, focused functions. Each new function should have a single responsibility and a descriptive name. Preserve the original behavior exactly. Provide the refactored code with comments explaining the purpose of each new function. Also suggest where to place these functions (e.g., as private methods of the class, module-level functions).

```python
def process_customer_data(data):
    # 200 lines of: validation, parsing, DB calls, sending emails, etc.

**Before:** One function, 200 lines.
**After:** `validate_data()`, `parse_customer()`, `save_to_db()`, `send_welcome_email()`.

### 2. Type Hint Injector

**Goal:** Add type hints to an untyped codebase.

**Why it works:** This prompt uses the `typing` module correctly and even suggests `TypedDict` for complex dicts—a sign the AI understands modern Python typing.

**Prompt:**

You are a Python expert. Refactor the following code to include comprehensive type hints. Use modern Python features from the typing module (e.g., Optional, List, Dict, Union, TypedDict). For complex data structures, suggest creating TypedDict classes. Ensure that the type hints are accurate and improve code readability without changing runtime behavior.

def get_user_data(user_id, db_connection):
    # code here

**Before:**
```python
def get_user_data(user_id, db_connection):
    cursor = db_connection.cursor()
    cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
    return cursor.fetchone()

After:

from typing import Optional, TypedDict

class User(TypedDict):
    id: int
    name: str
    email: str

def get_user_data(user_id: int, db_connection: Connection) -> Optional[User]:
    cursor = db_connection.cursor()
    cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
    row = cursor.fetchone()
    if row:
        return User(id=row[0], name=row[1], email=row[2])
    return None

3. The Duplication Detective

Goal: Find and eliminate duplicate code.

Why it works: This prompt asks for a report first, ensuring you understand the duplication before making changes. It also suggests appropriate abstractions, like a base class or utility function.

Prompt:

You are a code quality specialist. Scan the following code files for duplicate code blocks (similar logic repeated in multiple places). For each instance, provide:
1. The file and line numbers of the duplicates.
2. A similarity percentage.
3. A suggestion for refactoring: extract to a utility function, create a base class, or use a decorator.
Implement the refactoring, showing the new code.

```python
# file1.py
# file2.py

### 4. The Performance Tuner

**Goal:** Optimize slow Python code.

**Why it works:** This prompt encourages the AI to think about algorithmic complexity and suggests using built-in functions or libraries before resorting to micro-optimizations.

**Prompt:**

You are a Python performance optimization expert. The following code is slow. Profile it and suggest optimizations. Consider:
- Algorithmic complexity (e.g., O(n^2) to O(n log n))
- Using built-in functions or libraries (e.g., itertools, collections.Counter)
- Avoiding unnecessary computations in loops
- Using list comprehensions vs. explicit loops
Provide the optimized code and explain each change.

def find_duplicates(items):
    duplicates = []
    for i in range(len(items)):
        for j in range(i+1, len(items)):
            if items[i] == items[j] and items[i] not in duplicates:
                duplicates.append(items[i])
    return duplicates

**Before:** O(n^2) with nested loops.
**After:** Use `collections.Counter` to get counts, then filter items with count > 1 — O(n).

### 5. The Readability Refactor

**Goal:** Improve code readability without changing functionality.

**Why it works:** This prompt focuses on naming, structure, and comments. It actively discourages vague names like `data2` and encourages meaningful comments.

**Prompt:**

You are a Python code readability expert. Refactor the following code to be more readable for humans. Focus on:
- Meaningful variable and function names (avoid abbreviations like tmp, x1)
- Clear control flow (e.g., use early returns to avoid deep nesting)
- Adding docstrings and comments where necessary
- Breaking long lines to follow PEP 8
Do NOT change the functionality. Show the refactored code.

def calc(a, b, c):
    t = a + b
    if t > 100:
        t = 100
    return t * c

### 6. The Exception Handling Reviewer

**Goal:** Improve error handling and add proper exceptions.

**Why it works:** This prompt guides the AI to identify bare `except:` clauses, suggest specific exception types, and implement `try-except-else-finally` patterns.

**Prompt:**

You are a Python error handling expert. Review the following code for poor exception handling. Identify:
- Bare except: clauses
- Swallowed exceptions (e.g., except: pass)
- Missing else and finally blocks where appropriate
Refactor the code to use specific exception types, log errors appropriately, and handle errors gracefully. Provide the improved code.

try:
    result = risky_operation()
except:
    pass

### 7. The Logging Improver

**Goal:** Add proper logging to replace `print()` statements.

**Why it works:** This prompt introduces the `logging` module and shows how to configure it, which is essential for production code.

**Prompt:**

You are a Python logging expert. Replace all print() statements in the following code with proper logging using the logging module. Use appropriate log levels (DEBUG, INFO, WARNING, ERROR). Configure basic logging at the start of the script. Ensure that sensitive information is not logged. Provide the refactored code.

print("Starting process")
# ...
print(f"User {user_id} not found")

### 8. The Database Query Optimizer

**Goal:** Optimize database queries and refactor code to use ORM efficiently.

**Why it works:** This prompt focuses on N+1 queries, indexing, and using ORM features like `select_related` and `prefetch_related` (for Django) or `joinedload` (for SQLAlchemy).

**Prompt:**

You are a database optimization expert. Review the following code for database performance issues:
- N+1 queries (accessing related objects in a loop)
- Missing indexes
- Fetching unnecessary columns
Refactor the code to use ORM features like select_related, prefetch_related, or joinedload to reduce queries. Show the optimized code and explain the improvements.

# Django example
for order in Order.objects.all():
    print(order.customer.name)

### 9. The Concurrency Enhancer

**Goal:** Add concurrency to I/O-bound code.

**Why it works:** This prompt suggests using `asyncio` or `concurrent.futures` for I/O-bound tasks, and explains when to use each.

**Prompt:**

You are a Python concurrency expert. The following code is I/O-bound and runs sequentially. Refactor it to use asyncio for concurrent execution. Use aiohttp for HTTP requests, or asyncio.gather for multiple async functions. Ensure error handling and graceful cancellation. Provide the refactored code and notes on when to use asyncio vs. threading.

def fetch_all(urls):
    results = []
    for url in urls:
        results.append(fetch(url))
    return results

### 10. The Design Pattern Implementer

**Goal:** Refactor code to follow a specific design pattern (e.g., Strategy, Observer, Factory).

**Why it works:** This prompt asks the AI to identify where a pattern would be beneficial and implement it correctly.

**Prompt:**

You are a software architect. The following code has a complex conditional structure that could benefit from the Strategy pattern. Refactor it to use the Strategy pattern: define a common interface, implement concrete strategies, and use a context class to select the appropriate strategy. Provide the refactored code and explain the benefits.

def calculate_shipping(order):
    if order.country == "US":
        return 5 + order.weight * 0.1
    elif order.country == "CA":
        return 8 + order.weight * 0.2
    else:
        return 15 + order.weight * 0.3

### 11. The Linter and Formatter

**Goal:** Automatically format code to PEP 8 and add type hints.

**Why it works:** This prompt leverages tools like `black` and `flake8` to ensure consistency. It also asks for manual fixes for issues that tools can't catch.

**Prompt:**

You are a Python code formatter. Run black and flake8 on the following code. Show the output of these tools, then manually fix any remaining issues (e.g., unused imports, line length). Provide the final formatted code and a list of changes.

import os, sys

def foo( ) :
    return 42

### 12. The API Layer Designer

**Goal:** Refactor a monolithic script into a clean API layer.

**Why it works:** This prompt structures the refactoring into layers: routes, controllers, services, and repositories. It's perfect for turning a script into a FastAPI or Flask app.

**Prompt:**

You are a backend architect. Refactor the following script into a clean API layer using FastAPI. Structure the code as:
- main.py - FastAPI app and route definitions
- models.py - Pydantic models
- services.py - business logic
- repositories.py - data access
Provide the code for each file and explain the separation of concerns.

# Current script: handles HTTP requests, does DB operations, etc.

### 13. The Configuration Manager

**Goal:** Refactor hardcoded values into a configuration file.

**Why it works:** This prompt encourages using environment variables and a config file (e.g., `.env`, `config.py`) to make the code more flexible.

**Prompt:**

You are a Python configuration expert. The following code has hardcoded values (e.g., database URL, API keys, paths). Refactor it to use environment variables and a configuration file. Use os.getenv or a library like python-dotenv. Provide the refactored code and an example .env file.

DB_URL = "mysql://user:pass@localhost/mydb"
API_KEY = "12345"

### 14. The Test Generator

**Goal:** Generate unit tests for existing code.

**Why it works:** This prompt asks for edge cases and uses `pytest`, the most popular testing framework. It also encourages mocking to isolate units.

**Prompt:**

You are a Python testing expert. Write pytest tests for the following function. Cover normal cases, edge cases (empty input, large input, invalid types), and test for exceptions. Use mocking where necessary to avoid external dependencies. Provide the test code and explain what each test verifies.

def calculate_discount(price, discount):
    if discount < 0 or discount > 1:
        raise ValueError("Invalid discount")
    return price * (1 - discount)

### 15. The Legacy Code Modernizer

**Goal:** Modernize old Python code (e.g., Python 2 → Python 3, using f-strings, pathlib).

**Why it works:** This prompt targets specific modernization tasks and uses tools like `2to3` to automate part of the process.

**Prompt:**

You are a Python modernization expert. The following code is written in an outdated style (e.g., Python 2, uses % formatting, os.path). Refactor it to use modern Python 3 features:
- Use f-strings instead of % or .format()
- Use pathlib instead of os.path
- Use type hints
- Replace print statements with print() function
Provide the refactored code and explain the changes.

import os
path = os.path.join("home", "user", "file.txt")
print("Path: %s" % path)

```

Putting It All Together: A Real-World Case Study

Last month, I used these prompts to refactor a legacy reporting module for a logistics company. The module was a single 1,500-line script that generated PDF reports, sent emails, and queried a database. Here's the workflow:

  1. God Function Butcher on the main generate_report() function—split it into fetch_data(), format_data(), create_pdf(), send_email(). (Prompt 1)
  2. Type Hint Injector on all new functions. (Prompt 2)
  3. Duplication Detective found 3 repeated blocks for date parsing—extracted to a parse_date() utility. (Prompt 3)
  4. Performance Tuner optimized a loop that was O(n^2) by using a set for lookups. (Prompt 4)
  5. Logging Improver replaced all print()s with logging. (Prompt 6)
  6. Test Generator created pytest tests for the core logic, covering edge cases like empty data. (Prompt 14)

Result: The module went from 1,500 lines to 800 lines across 4 files, with type hints and 95% test coverage. The AI's suggestions were spot-on, and I was able to review and merge them in about 2 hours—compared to the 2 days it would have taken manually.

Your Turn: Start Small, Gain Confidence

You don't need to refactor your entire codebase in one weekend. Pick one function that's been bugging you, try Prompt 1 or 4, and see the difference. The more you use these prompts, the better you'll get at crafting them—and the more you'll trust the AI's output. Remember, the AI is a tool, not a replacement for your judgment. Always review, test, and understand the changes.

If you want to take this further, consider using AI-powered code review tools like code-review bots or integrating these prompts into your CI/CD pipeline. And if you're curious about other ways AI can supercharge your development workflow, check out our previous articles on AI for CI/CD and Docker optimization.

Now, go forth and refactor. Your future self (and your team) will thank you.

← All posts

Comments