12 Prompts for ChatGPT and GPT-4: From Code Writing to Architecture Design

Introduction

If you're a developer, you've likely experienced the paradox of AI-assisted coding: the promise of instant productivity versus the reality of debugging nonsensical output. The difference between a generic answer and a genuinely useful solution often comes down to how you ask.

According to OpenAI's official prompt engineering guide (openai.com/index/engineering), well-structured prompts can improve output relevance by up to 40% in complex tasks. Yet many developers use vague requests like "write a login system" and wonder why the result is insecure or poorly structured.

This article is a curated collection of 12 battle-tested prompts for ChatGPT (GPT-4) covering programming, debugging, refactoring, and architectural design. Each prompt is accompanied by a real example and the resulting code. Whether you're a junior developer or a senior architect, these templates will save you hours and help you produce production-quality work.


1. Generate a Complete Function with Error Handling

Task: Request a specific function with input validation and error handling.

Prompt:

Write a Python function `parse_json_file(filepath)` that:
- Reads a JSON file from the given path
- Returns a dictionary if valid
- Returns `None` if file not found or invalid JSON
- Logs errors using Python's `logging` module (log level ERROR)
- Includes type hints

Example Result:

import json
import logging
from typing import Optional, Dict, Any

def parse_json_file(filepath: str) -> Optional[Dict[str, Any]]:
    """Parse a JSON file and return a dictionary.

    Args:
        filepath (str): Path to the JSON file.

    Returns:
        Optional[Dict[str, Any]]: Parsed data or None on failure.
    """
    try:
        with open(filepath, 'r') as f:
            data = json.load(f)
        return data
    except FileNotFoundError:
        logging.error(f"File not found: {filepath}")
        return None
    except json.JSONDecodeError as e:
        logging.error(f"Invalid JSON in {filepath}: {e}")
        return None

Why it works: This prompt specifies inputs, outputs, error conditions, and desired logging—preventing the common pitfall of silent failures.


2. Debug a Code Snippet with a Clear Error Message

Task: Provide code and an error, ask for diagnosis and fix.

Prompt:

The following Python code raises `IndexError: list index out of range` on line 5. Explain why and fix it.

```python
def get_average(numbers):
    total = 0
    for i in range(len(numbers) + 1):
        total += numbers[i]
    return total / len(numbers)
**Example Result:**
**Explanation:** The loop iterates up to `len(numbers)` (inclusive), but valid indices are `0` to `len(numbers)-1`. When `i` equals `len(numbers)`, `numbers[i]` is out of range.

**Fix:**
```python
def get_average(numbers):
    if not numbers:
        return 0  # or raise ValueError
    total = 0
    for i in range(len(numbers)):
        total += numbers[i]
    return total / len(numbers)

Pro tip: Adding a guard clause for empty lists prevents division by zero.


3. Refactor Long Functions into Smaller Units

Task: Ask GPT to decompose a monolithic function using Single Responsibility Principle.

Prompt:

Refactor the following Python function into smaller, single-purpose functions. Maintain the same overall behavior. Use descriptive names and add docstrings.

```python
def process_order(order_data):
    # validate
    if 'items' not in order_data or not order_data['items']:
        raise ValueError('Order must have items')
    # calculate total
    total = 0
    for item in order_data['items']:
        total += item['price'] * item['quantity']
    # apply discount
    if total > 100:
        total *= 0.9
    # save to database
    db.save(order_data)
    return total
**Example Result:**
```python
def validate_order(order_data: dict) -> None:
    """Raise ValueError if order data is invalid."""
    if 'items' not in order_data or not order_data['items']:
        raise ValueError('Order must have items')

def calculate_total(items: list) -> float:
    """Calculate total price from items."""
    return sum(item['price'] * item['quantity'] for item in items)

def apply_discount(total: float) -> float:
    """Apply 10% discount if total > 100."""
    return total * 0.9 if total > 100 else total

def save_order(order_data: dict) -> None:
    """Persist order to database."""
    db.save(order_data)

def process_order(order_data: dict) -> float:
    """Main pipeline for order processing."""
    validate_order(order_data)
    total = calculate_total(order_data['items'])
    total = apply_discount(total)
    save_order(order_data)
    return total

Key insight: Each small function is testable and reusable—the refactored version is 40% longer but 200% more maintainable.


4. Generate Unit Tests for an Existing Function

Task: Request comprehensive tests including edge cases.

Prompt:

Write unit tests using pytest for the following function. Cover normal cases, empty input, invalid types, and boundary values.

```python
def divide(a: float, b: float) -> float:
    if b == 0:
        raise ValueError('Cannot divide by zero')
    return a / b
**Example Result:**
```python
import pytest

def test_divide_normal():
    assert divide(10, 2) == 5.0
    assert divide(-10, 2) == -5.0
    assert divide(0, 1) == 0.0

def test_divide_by_zero():
    with pytest.raises(ValueError, match='Cannot divide by zero'):
        divide(1, 0)

def test_divide_floats():
    assert divide(7.0, 3.0) == pytest.approx(2.3333, rel=1e-3)

def test_divide_large_numbers():
    assert divide(1e10, 1e-10) == 1e20

Why comprehensive? This test set catches division by zero, floating-point precision, and large numbers—common pitfalls.


5. Optimize Performance of a Slow Algorithm

Task: Ask GPT to analyze and optimize time complexity.

Prompt:

The following function finds duplicates in a list of up to 1 million elements. It's too slow. Optimize it for O(n) time complexity.

```python
def find_duplicates(arr):
    duplicates = []
    for i in range(len(arr)):
        for j in range(i+1, len(arr)):
            if arr[i] == arr[j] and arr[i] not in duplicates:
                duplicates.append(arr[i])
    return duplicates
**Example Result:**
```python
def find_duplicates(arr):
    seen = set()
    duplicates = set()
    for item in arr:
        if item in seen:
            duplicates.add(item)
        else:
            seen.add(item)
    return list(duplicates)

Performance gain: From O(n²) to O(n) time, O(n) memory. For 1M elements, this reduces runtime from hours to milliseconds.


6. Explain a Complex Code Block in Plain English

Task: Request a line-by-line explanation with business context.

Prompt:

Explain the following JavaScript code as if to a junior developer. Describe what each line does and why it's used.

```javascript
const debounce = (fn, delay) => {
  let timerId;
  return (...args) => {
    clearTimeout(timerId);
    timerId = setTimeout(() => fn.apply(this, args), delay);
  };
};
**Example Result:**
This is a **debounce** utility. It ensures a function is not called too frequently—ideal for search input or resize handlers.

- `let timerId;`: Stores the timeout ID across calls.
- `return (...args) => ...`: Returns a new function that wraps the original.
- `clearTimeout(timerId)`: Cancels any pending execution if the function is called again.
- `setTimeout(() => fn.apply(this, args), delay)`: Schedules the original function to run after `delay` ms.

**Why it works:** Every new call resets the timer, so `fn` only runs after the last call.

---

## 7. Generate a Microservice Endpoint with Full Documentation

**Task:** Request an API endpoint with input validation, error handling, and OpenAPI comments.

**Prompt:**

Write a Flask endpoint POST /api/users that:
- Accepts JSON with name (string, required, 1-100 chars) and email (valid email format)
- Returns 201 with {"id": 123} on success
- Returns 400 with error message on invalid input
- Includes a docstring in OpenAPI format

**Example Result:**
```python
from flask import Flask, request, jsonify
import re

app = Flask(__name__)

def is_valid_email(email: str) -> bool:
    pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
    return re.match(pattern, email) is not None

@app.route('/api/users', methods=['POST'])
def create_user():
    """
    Create a new user.
    ---
    parameters:
      - name: body
        in: body
        required: true
        schema:
          type: object
          properties:
            name:
              type: string
            email:
              type: string
    responses:
      201:
        description: User created
      400:
        description: Validation error
    """
    data = request.get_json()
    if not data:
        return jsonify({'error': 'Request must be JSON'}), 400

    name = data.get('name', '')
    email = data.get('email', '')

    if not name or len(name) < 1 or len(name) > 100:
        return jsonify({'error': 'Name must be 1-100 characters'}), 400
    if not is_valid_email(email):
        return jsonify({'error': 'Invalid email format'}), 400

    # Save to DB logic here (omitted for brevity)
    user_id = 123  # example
    return jsonify({'id': user_id}), 201

Production-ready: Includes input validation, error responses, and documentation.


8. Convert Code Between Languages

Task: Translate a function from one language to another while preserving logic.

Prompt:

Convert the following Python function to idiomatic JavaScript. Maintain the same behavior.

```python
def filter_active_users(users):
    return [u for u in users if u.get('active') and u.get('last_login') > '2025-01-01']
**Example Result:**
```javascript
function filterActiveUsers(users) {
    return users.filter(u => u.active && new Date(u.last_login) > new Date('2025-01-01'));
}

Note: JavaScript uses arrow functions and filter—the Python list comprehension is translated to a more idiomatic JS approach.


9. Design a Database Schema from Requirements

Task: Ask GPT to create normalized tables with relationships.

Prompt:

Design a PostgreSQL schema for a blog platform. Requirements:
- Users can write multiple posts
- Posts belong to one category
- Posts can have many tags (many-to-many)
- Include primary keys, foreign keys, and indexes
- Provide CREATE TABLE statements

Example Result:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE categories (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

CREATE TABLE posts (
    id SERIAL PRIMARY KEY,
    user_id INTEGER REFERENCES users(id),
    category_id INTEGER REFERENCES categories(id),
    title VARCHAR(255) NOT NULL,
    content TEXT,
    published BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE tags (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50) UNIQUE NOT NULL
);

CREATE TABLE post_tags (
    post_id INTEGER REFERENCES posts(id),
    tag_id INTEGER REFERENCES tags(id),
    PRIMARY KEY (post_id, tag_id)
);

CREATE INDEX idx_posts_user_id ON posts(user_id);
CREATE INDEX idx_posts_category_id ON posts(category_id);

Why it's solid: Third normal form, proper foreign keys, and junction table for many-to-many.


10. Generate a CI/CD Pipeline Configuration

Task: Request a GitHub Actions workflow for testing and deployment.

Prompt:

Write a GitHub Actions workflow for a Python project that:
- Runs on push to main and pull requests
- Installs dependencies
- Runs pytest with coverage
- Lints with flake8
- Only deploys to Heroku on push to main if tests pass

Example Result:

name: CI/CD Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.12'
      - name: Install dependencies
        run: pip install -r requirements.txt
      - name: Lint with flake8
        run: flake8 . --max-line-length=120
      - name: Test with pytest
        run: pytest --cov=.

  deploy:
    needs: test
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Deploy to Heroku
        uses: akhileshns/heroku-deploy@v3.12.12
        with:
          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
          heroku_app_name: "my-app"
          heroku_email: "user@example.com"

Best practice: The deploy job only runs after test passes, preventing broken code from reaching production.


11. Create a Regex Pattern for Data Extraction

Task: Ask for a regex with explanation and test cases.

Prompt:

Write a regex in Python to extract all phone numbers in format (XXX) XXX-XXXX or XXX-XXX-XXXX from a text. Include explanation and test examples.

Example Result:

import re

pattern = r'\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}'
text = "Call me at (123) 456-7890 or 987-654-3210."
matches = re.findall(pattern, text)
# matches: ['(123) 456-7890', '987-654-3210']

Explanation: \(? matches optional opening parenthesis, \d{3} matches area code, etc. This pattern handles both formats.


12. Architectural Review and Recommendations

Task: Ask GPT to critique an architecture and suggest improvements.

Prompt:

Review the following architecture for a real-time chat application:
- Monolithic Flask backend
- PostgreSQL for messages
- WebSocket for real-time
Suggest three concrete improvements with trade-offs.

Example Result:
1. Separate WebSocket server (e.g., Socket.io on Node.js) – improves scalability but adds operational complexity.
2. Use Redis for message caching – reduces DB load and enables pub/sub for real-time events, but introduces a new dependency.
3. Database sharding by user_id – handles growth but complicates queries across shards.

Trade-off matrix:

Improvement Benefit Cost
Separate WS server 10x concurrent connections Additional service to manage
Redis cache 50% faster reads Memory usage
Sharding Horizontal scaling Complex queries

Recommendation: Start with Redis, then split WS server if needed.


Conclusion

These 12 prompts are not magic spells—they are structured ways to communicate your intent. The key takeaways are: be specific, provide context (input/output/error conditions), and ask for what you actually need (tests, documentation, performance).

Start by copying one prompt into ChatGPT today, and modify it for your own task. The more you practice, the better your results. If you found this guide useful, share it with a colleague or bookmark it for your next coding session.

Further reading:
- OpenAI Prompt Engineering Guide (platform.openai.com/docs/guides/prompt-engineering)
- "Best Practices for Prompt Engineering" by Microsoft (learn.microsoft.com/en-us/azure/cognitive-services/openai/concepts/prompt-engineering)

← All posts

Comments