Skip to main content

ChatGPT for Developers: Complete Coding Guide

What You'll Learn

By the end of this guide, you'll know how to write better prompts for code generation, debug with AI help, refactor existing code, and generate test coverage. The examples are real — adapt them to your own projects.


Day 1: Foundations

Understanding ChatGPT's Strengths & Weaknesses

What ChatGPT Does Well:

  • ✅ Explaining code concepts
  • ✅ Generating boilerplate
  • ✅ Debugging logic errors
  • ✅ Writing tests
  • ✅ Code translation between languages

What ChatGPT Struggles With:

  • ❌ Very new libraries (post-2023)
  • ❌ Company-specific code
  • ❌ Complex system design
  • ❌ Security-critical code (review needed)

Your First Prompt

❌ Bad Prompt:

write a login function

✅ Good Prompt:

Create a secure login function in Python using Flask and SQLAlchemy.

Requirements:
- Hash passwords with bcrypt
- Return JWT token on success
- Handle errors (user not found, wrong password)
- Include input validation
- Add docstring with examples

Use type hints and follow PEP 8.

ChatGPT Output:

from flask import jsonify, request
from werkzeug.security import check_password_hash
from models import User
import jwt
import datetime
from typing import Tuple, Dict
import re

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

def login_user(email: str, password: str) -> Tuple[Dict, int]:
"""
Authenticate user and return JWT token.

Args:
email: User's email address
password: Plain text password

Returns:
Tuple of (response_dict, http_status_code)

Example:
>>> login_user('user@example.com', 'password123')
({'token': 'eyJ0eXAiOiJKV1...'}, 200)

Raises:
ValueError: If email format is invalid
"""

# Input validation
if not email or not password:
return {'error': 'Email and password are required'}, 400

if not validate_email(email):
return {'error': 'Invalid email format'}, 400

# Find user
user = User.query.filter_by(email=email).first()

if not user:
return {'error': 'Invalid credentials'}, 401

# Verify password
if not check_password_hash(user.password_hash, password):
return {'error': 'Invalid credentials'}, 401

# Generate JWT token
token = jwt.encode({
'user_id': user.id,
'email': user.email,
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=24)
}, app.config['SECRET_KEY'], algorithm='HS256')

return {
'token': token,
'user': {
'id': user.id,
'email': user.email,
'name': user.name
}
}, 200

Practice Exercise

Generate a function for your project using the good prompt pattern:

  1. Specify language and framework
  2. List requirements
  3. Request error handling
  4. Ask for documentation
  5. Specify code style

Day 2: Debugging with ChatGPT

Debugging Pattern

Template:

I'm getting this error:
[paste error message]

Here's my code:
[paste relevant code]

Context:
- Language/Framework: [e.g., React 18 + TypeScript]
- What I'm trying to do: [brief explanation]
- What I've tried: [list attempts]

Please explain what's wrong and how to fix it.

Real Example: React Infinite Render

Your Code:

function UserProfile({ userId }) {
const [user, setUser] = useState(null);

useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setUser);
}); // Bug: missing dependency array

return <div>{user?.name}</div>;
}

Error:

Warning: Maximum update depth exceeded. This can happen when a component
calls setState inside useEffect without a dependency array.

Prompt to ChatGPT:

I'm getting "Maximum update depth exceeded" error in React.

Code:
[paste code above]

Context:
- React 18 + TypeScript
- Trying to fetch user data on component mount
- Error appears immediately on page load

Please explain and fix.

ChatGPT Response:

The problem is the missing dependency array in useEffect.

Current code:
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setUser);
}); // Runs after EVERY render

What happens:
1. Component renders
2. useEffect runs, fetches data
3. setUser() causes re-render
4. useEffect runs again (because no dependency array)
5. Infinite loop!

Fix:
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setUser);
}, [userId]); // Only run when userId changes

Complete improved version:
useEffect(() => {
let cancelled = false;

const fetchUser = async () => {
try {
const res = await fetch(`/api/users/${userId}`);
if (!res.ok) throw new Error('Failed to fetch user');

const data = await res.json();
if (!cancelled) setUser(data);
} catch (error) {
console.error('Error fetching user:', error);
// Handle error state
}
};

fetchUser();

return () => {
cancelled = true; // Cleanup to prevent state update on unmounted component
};
}, [userId]);

Practice Exercise

Debug a real issue from your codebase using the template above.


Day 3: Learning New Technologies

Learning Pattern

Instead of reading docs for hours, use ChatGPT as a tutor:

Phase 1: Overview (5 min)

Explain [Technology] in simple terms for an experienced developer.

Include:
- What problem it solves
- Key concepts (5-7 most important)
- When to use it vs alternatives
- 30-second example

Example: React developer learning Vue 3

Phase 2: Hello World (10 min)

Create a simple [App Type] using [Technology].

Requirements:
- [Feature 1]
- [Feature 2]
- [Feature 3]
- Include comments explaining key parts
- Production-ready code quality

Example: Todo app with Vue 3 Composition API

Phase 3: Real-World Patterns (15 min)

Show me best practices for [Specific Task] in [Technology].

Include:
- Modern approach (2024)
- Error handling
- Performance considerations
- Common pitfalls to avoid
- Code example

Example: State management in Vue 3

Real Example: Learning FastAPI

Prompt 1:

Explain FastAPI for an Express.js developer.

Include:
- Key differences from Express
- Main advantages
- When to choose FastAPI
- 30-second example

ChatGPT gives clear comparison:

# FastAPI (Python) vs Express (JavaScript) - Key Differences

1. Type Safety: FastAPI uses Python type hints for automatic validation
2. Auto Documentation: Built-in Swagger UI (no extra setup)
3. Async: Native async/await support
4. Performance: Fast as Node.js (due to Starlette/Uvicorn)

When to use FastAPI:
✅ Python ecosystem (ML, data science)
✅ Need automatic API docs
✅ Strong typing important
❌ Node.js ecosystem required
❌ Team only knows JavaScript

# 30-second example
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
name: str
email: str

@app.post("/users")
async def create_user(user: User):
# Type validation automatic!
# API docs automatic!
return {"id": 123, **user.dict()}

# Run: uvicorn main:app --reload
# Docs: http://localhost:8000/docs (auto-generated!)

Prompt 2:

Create a REST API for blog posts using FastAPI.

Requirements:
- CRUD operations (create, read, update, delete)
- SQLite database with SQLAlchemy
- Pydantic models for validation
- Error handling
- Include all necessary imports

Result: Complete working API in 2 minutes

Practice Exercise

Learn a new framework/library in 30 minutes:

  1. Get overview prompt
  2. Build hello world prompt
  3. Implement real feature prompt

Day 4: Code Refactoring

Refactoring Pattern

Refactor this code to improve [specific aspect]:

[paste code]

Requirements:
- [Improvement 1]
- [Improvement 2]
- Keep functionality identical
- Add comments explaining changes

Context:
- [Framework/language details]
- [Performance requirements if any]

Real Example: Cleaning Messy React Component

Original Code:

// 300-line component with everything mixed together
function Dashboard() {
const [users, setUsers] = useState([]);
const [products, setProducts] = useState([]);
const [orders, setOrders] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
// ... 10 more state variables

useEffect(() => {
// 100 lines of data fetching logic
fetch('/api/users').then(...)
fetch('/api/products').then(...)
fetch('/api/orders').then(...)
// ... more fetching
}, []);

// 50 lines of event handlers

return (
<div>
{/* 150 lines of JSX */}
</div>
);
}

Prompt:

Refactor this React component using best practices:

[paste code]

Requirements:
- Extract custom hooks for data fetching
- Separate into smaller components
- Use React Query for caching
- Add proper TypeScript types
- Improve loading/error states

ChatGPT Output:

// 1. Custom hook for data fetching
import { useQuery } from '@tanstack/react-query';

function useDashboardData() {
const users = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(r => r.json())
});

const products = useQuery({
queryKey: ['products'],
queryFn: () => fetch('/api/products').then(r => r.json())
});

const orders = useQuery({
queryKey: ['orders'],
queryFn: () => fetch('/api/orders').then(r => r.json())
});

return {
users: users.data,
products: products.data,
orders: orders.data,
isLoading: users.isLoading || products.isLoading || orders.isLoading,
error: users.error || products.error || orders.error
};
}

// 2. Main component (now clean)
export function Dashboard() {
const { users, products, orders, isLoading, error } = useDashboardData();

if (isLoading) return <LoadingSpinner />;
if (error) return <ErrorMessage error={error} />;

return (
<DashboardLayout>
<UsersSection users={users} />
<ProductsSection products={products} />
<OrdersSection orders={orders} />
</DashboardLayout>
);
}

// 3. Separated components
function UsersSection({ users }: { users: User[] }) {
return (
<section>
<h2>Users</h2>
<UserList users={users} />
</section>
);
}

// ... more components

Before: 300 lines, hard to test, hard to read After: 50-line main component, 5 focused sub-components, easy to test

Practice Exercise

Find a messy file in your codebase and refactor it with ChatGPT.


Day 5: Test Generation

Testing Pattern

Generate comprehensive tests for this code:

[paste code]

Requirements:
- Framework: [Jest/Pytest/etc]
- Cover happy path and edge cases
- Include setup/teardown if needed
- Mock external dependencies
- Aim for >90% coverage

Real Example: Testing API Endpoint

Code to Test:

@app.route('/api/discounts', methods=['POST'])
def calculate_discount():
data = request.get_json()

price = data.get('price')
user_tier = data.get('user_tier')
promo_code = data.get('promo_code')

if not price or price <= 0:
return jsonify({'error': 'Invalid price'}), 400

discount = 0

# Tier discounts
if user_tier == 'bronze': discount += 5
elif user_tier == 'silver': discount += 10
elif user_tier == 'gold': discount += 15

# Promo code
if promo_code == 'SAVE20':
discount += 20

final_price = price * (1 - discount / 100)

return jsonify({
'original_price': price,
'discount_percent': discount,
'final_price': final_price
})

Prompt:

Generate pytest tests for this Flask endpoint:

[paste code]

Requirements:
- Test all user tiers
- Test with/without promo code
- Test edge cases (negative price, invalid tier, etc.)
- Test promo code stacking with tiers
- Use pytest fixtures for app setup

ChatGPT Output:

import pytest
from flask import Flask
from decimal import Decimal

@pytest.fixture
def app():
"""Create Flask app for testing"""
app = create_app('testing')
return app

@pytest.fixture
def client(app):
"""Create test client"""
return app.test_client()

class TestDiscountCalculation:
"""Test discount calculation endpoint"""

def test_no_tier_no_promo(self, client):
"""Test base case: no discount"""
response = client.post('/api/discounts', json={
'price': 100,
'user_tier': None,
'promo_code': None
})

assert response.status_code == 200
data = response.get_json()
assert data['original_price'] == 100
assert data['discount_percent'] == 0
assert data['final_price'] == 100

@pytest.mark.parametrize('tier,expected_discount', [
('bronze', 5),
('silver', 10),
('gold', 15),
])
def test_tier_discounts(self, client, tier, expected_discount):
"""Test each tier discount level"""
response = client.post('/api/discounts', json={
'price': 100,
'user_tier': tier,
'promo_code': None
})

data = response.get_json()
assert data['discount_percent'] == expected_discount
assert data['final_price'] == 100 - expected_discount

def test_promo_code_alone(self, client):
"""Test promo code without tier"""
response = client.post('/api/discounts', json={
'price': 100,
'user_tier': None,
'promo_code': 'SAVE20'
})

data = response.get_json()
assert data['discount_percent'] == 20
assert data['final_price'] == 80

def test_tier_plus_promo_stacking(self, client):
"""Test that tier and promo discounts stack"""
response = client.post('/api/discounts', json={
'price': 100,
'user_tier': 'gold', # 15%
'promo_code': 'SAVE20' # 20%
})

data = response.get_json()
assert data['discount_percent'] == 35 # 15 + 20
assert data['final_price'] == 65

def test_invalid_price_zero(self, client):
"""Test error handling for zero price"""
response = client.post('/api/discounts', json={
'price': 0,
'user_tier': 'gold'
})

assert response.status_code == 400
assert 'error' in response.get_json()

def test_invalid_price_negative(self, client):
"""Test error handling for negative price"""
response = client.post('/api/discounts', json={
'price': -50,
'user_tier': 'gold'
})

assert response.status_code == 400

def test_missing_price(self, client):
"""Test error when price not provided"""
response = client.post('/api/discounts', json={
'user_tier': 'gold'
})

assert response.status_code == 400

def test_invalid_promo_code(self, client):
"""Test that invalid promo codes are ignored"""
response = client.post('/api/discounts', json={
'price': 100,
'user_tier': 'silver',
'promo_code': 'INVALID'
})

data = response.get_json()
# Should only apply tier discount (10%)
assert data['discount_percent'] == 10

def test_large_price(self, client):
"""Test with large price values"""
response = client.post('/api/discounts', json={
'price': 999999.99,
'user_tier': 'gold',
'promo_code': 'SAVE20'
})

assert response.status_code == 200
data = response.get_json()
# 35% off 999999.99
expected = 999999.99 * 0.65
assert abs(data['final_price'] - expected) < 0.01

Coverage: 95%+ with all edge cases

Practice Exercise

Generate tests for a function you wrote recently.


Day 6: Advanced Prompting Techniques

Technique 1: Chain of Thought

Ask ChatGPT to explain its reasoning:

[Your coding question]

Please think step-by-step:
1. Analyze the requirements
2. Consider edge cases
3. Choose the best approach
4. Implement the solution
5. Explain trade-offs

Example:

Design a rate limiting system for an API.

Think step-by-step about:
1. Different rate limiting algorithms
2. Where to store rate limit data
3. Edge cases (distributed systems, clock skew)
4. Implementation approach
5. Trade-offs of each decision

Technique 2: Iterative Refinement

[Initial request]

# After seeing output:
"Great! Now improve it by [specific change]"

# Then:
"Add [feature]"

# Then:
"Optimize for [goal]"

Technique 3: Role-Based Prompting

Act as a senior [role] with 10 years experience.

Review this code and provide:
- What a junior would miss
- Best practices specific to [domain]
- Production readiness checklist

Code:
[paste code]

Example:

Act as a senior DevOps engineer.

Review this Dockerfile and provide:
- Security issues
- Performance optimizations
- Production readiness checklist

Dockerfile:
FROM python:latest
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD python app.py

ChatGPT (as DevOps expert):

# Issues found:

1. SECURITY: Using 'latest' tag (unpredictable)
2. SECURITY: Running as root (default)
3. PERFORMANCE: Installing all deps every build (no caching)
4. PERFORMANCE: Large image size (python:latest ~900MB)
5. RELIABILITY: No health check
6. DEBUGGING: No logging configuration

# Improved Dockerfile:

FROM python:3.11-slim as builder # ✅ Specific version, smaller base

# Create non-root user
RUN useradd -m -u 1000 appuser

# Install dependencies (cached layer)
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy app code
COPY --chown=appuser:appuser . .

# Switch to non-root user
USER appuser

# Health check
HEALTHCHECK --interval=30s --timeout=3s \
CMD python -c "import requests; requests.get('http://localhost:8000/health')"

# Expose port
EXPOSE 8000

# Run app
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8000", "app:app"]

# Production checklist:
# ✅ Specific base image version
# ✅ Non-root user
# ✅ Dependency caching
# ✅ Small image size (~150MB vs 900MB)
# ✅ Health check
# ✅ Production WSGI server (gunicorn)
# ✅ Proper logging (gunicorn logs to stdout)

Day 7: Building Your Workflow

Create Your Prompt Library

Save effective prompts for reuse:

# prompts.md

## Code Review
Act as a senior developer. Review this [language] code for:
1. Bugs and logic errors
2. Performance issues
3. Security vulnerabilities
4. Code style and readability
5. Missing edge cases

Provide specific line numbers and fixes.

---

## Documentation
Generate comprehensive documentation for this code:
- Purpose and overview
- Parameters with types
- Return values
- Usage examples
- Edge cases and error handling

Format: [JSDoc/docstring/etc]

---

## Refactoring
Refactor this code following [framework] best practices:
- Improve readability
- Reduce complexity
- Optimize performance
- Add proper types
- Follow [style guide]

Explain each major change.

Keyboard Shortcuts / IDE Integration

VS Code Extension: ChatGPT - Genie AI

  • Select code → Right click → "Ask ChatGPT"
  • Keyboard shortcut: Ctrl+Shift+G

Command Line:

# Create alias
alias askgpt='function _ask(){ curl -X POST https://api.openai.com/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer $OPENAI_API_KEY" -d "{\"model\":\"gpt-4\",\"messages\":[{\"role\":\"user\",\"content\":\"$1\"}]}" | jq -r ".choices[0].message.content"; }; _ask'

# Usage
askgpt "Explain this regex: ^[\w\.-]+@[\w\.-]+\.\w+$"

Daily Workflow Integration

Morning:

  • Review overnight errors with ChatGPT
  • Plan day's tasks (architecture questions)

During Coding:

  • Generate boilerplate
  • Debug errors as they occur
  • Explain unfamiliar code

Before Commit:

  • Generate tests
  • Write commit message
  • Review changes

Code Review:

  • Get AI review before human review
  • Explain complex changes for PR description

Pro Tips

1. Always Verify AI Code

# Don't trust blindly!
# ❌ Bad: Copy-paste without reading
# ✅ Good: Read, understand, test

ai_generated_code = get_from_chatgpt()

# Read it
understand(ai_generated_code)

# Test it
run_tests(ai_generated_code)

# Review for security
check_security(ai_generated_code)

# Then use it

2. Use ChatGPT to Learn, Not Just Get Answers

# ❌ Bad: "Fix my code"
# ✅ Good: "Explain why this doesn't work and teach me the concept"

3. Combine with Documentation

# Best workflow:
1. Read official docs (15 min)
2. Ask ChatGPT for clarification (5 min)
3. Try implementation (20 min)
4. Debug with ChatGPT if needed (10 min)

Total: 50 min to learn new concept

4. Track Cost (GPT-4)

# If using API
import openai

def count_tokens(text):
# Approximate: 1 token ≈ 4 characters
return len(text) // 4

prompt = "Your prompt here"
tokens = count_tokens(prompt)
cost = tokens * $0.03 / 1000 # GPT-4 pricing

print(f"Estimated cost: ${cost:.4f}")

Common pitfalls

1. Hallucinated Functions

ChatGPT might invent functions that don't exist:

# ChatGPT might suggest:
result = pandas.magic_function(df) # ❌ Doesn't exist!

# Always verify in docs

2. Outdated Information

Training data cutoff (Jan 2024 for GPT-4):

# ❌ ChatGPT doesn't know about:
- Libraries released after 2024
- Latest API changes
- Recent security vulnerabilities

# ✅ Solution: Provide documentation in prompt

3. Over-Engineering

ChatGPT tends to suggest complex solutions:

# You asked: "Store user preferences"

# ChatGPT suggests: Redis + RabbitMQ + Kafka + Microservices

# Reality: JSON file is fine for your use case

# Always question: "Is this complexity necessary?"

After 7 days

You'll have a set of prompt patterns that work for your stack, and you'll know when ChatGPT is useful vs. when you need to just read the docs.


Next steps

Once you have the basics down, try combining ChatGPT with an IDE integration like Copilot or Cursor — chat plus inline suggestions work well together. Beyond that, use it on real problems.


Resources


Last Updated: 2025-11-09 | Difficulty: Beginner to Advanced | Time: 7 days

Want to explore other AI coding tools? Check our Complete Comparison Guide.