Chapter 23 Exercises: Software Development and Debugging

These exercises build practical AI-assisted development skills across the full workflow. Exercises are organized from conceptual to technical, with later exercises requiring Python proficiency.


Part A: Architecture and Design

Exercise 1: The Trade-off Discussion

Choose a system design problem relevant to your work or one of the following: - A caching strategy for a read-heavy web application - A data model for a multi-tenant SaaS application - A job scheduling system for a data pipeline - An event-driven architecture for order processing

Submit this prompt:

"I'm designing [your system]. Present 3 architectural approaches. For each: high-level description, key components, advantages, disadvantages, and when this approach is most appropriate."

After reviewing the three approaches: 1. Pick the one you would likely choose and explain why. 2. Ask AI to challenge your reasoning. 3. Identify one consideration AI raised that you had not thought of.

Exercise 2: Challenging Your Architectural Assumptions

Think of an architectural decision in your codebase (current or past) that you are confident about. Submit it to AI with the explicit request:

"I've made this architectural decision: [describe decision and reasoning]. Challenge my reasoning as vigorously as possible. What am I potentially underweighting? What failure modes have I not adequately considered?"

Evaluate the challenge: are there objections you find genuinely compelling? Are there objections you can refute? What is your confidence in the decision after the challenge?

Exercise 3: Mermaid Diagram Generation

Describe a system you work with or have recently designed. Ask AI to generate a Mermaid sequence diagram showing the key data flow or request lifecycle.

If your documentation platform supports Mermaid (GitHub, Notion, GitLab), paste the output and verify that it renders correctly and accurately represents the system. Identify any inaccuracies and correct the diagram.


Part B: Implementation

Exercise 4: The Explain-Then-Generate Technique

Choose a small, self-contained feature you need to implement (or create a hypothetical one). Use the explain-then-generate sequence:

  1. Submit a prompt asking AI to describe the implementation approach without writing code.
  2. Review the proposed approach. Identify at least one thing you would change or clarify.
  3. Submit the revised approach with your changes and ask AI to now generate the code.
  4. Review the generated code. Can you explain every line?

Compare the quality of the code generated after the explanation step to what you would have received from a direct "write me a function that does X" prompt.

Exercise 5: Convention-Following Code Generation

Find two or three examples of existing code from a real codebase (your own project, an open-source project, or a project you maintain). Ask AI to generate a new function in the same style:

"Here are examples of existing code from this project: [paste examples]. The code uses [describe conventions — naming style, error handling approach, logging patterns]. Generate a new function that [describe what it should do], following the exact same conventions as the examples."

Compare the generated code to the examples. Did AI follow the conventions? What conventions did it miss?

Exercise 6: Context-Sensitive Code Completion

Take a partially written function with a clear docstring and skeleton structure. Ask AI to complete only the body of the function — not to change the signature, docstring, or structure. Review: - Does the implementation match the docstring contract? - Are the edge cases described in the docstring handled? - Would you need to change anything to merge this?


Part C: Code Review

Exercise 7: Structured Self-Review

Write a small function (20-50 lines) or use an existing piece of code you have written recently. Submit it for the structured multi-dimensional review from Section 4:

Review this code with separate passes for: SECURITY, PERFORMANCE,
CORRECTNESS, READABILITY, and TEST COVERAGE. Report under separate headers.

Evaluate each finding: - Mark each as: Valid concern | Overcautious | Incorrect - For valid concerns, identify which you would fix and which you would accept as acceptable trade-offs - Note any security findings that surprise you

Exercise 8: Security-Focused Review

Submit a piece of code that handles any of the following: user authentication, input from external sources, database queries using user-provided values, or file operations based on user input.

Use the security-focused review prompt from Section 4. For each finding: 1. Is it a real vulnerability or a false positive? 2. If real, how severe is it? 3. What is the appropriate fix?

Exercise 9: Finding What AI Misses

Review a piece of code using AI, then review the same code yourself manually. Document: - What did AI find that you might have missed? - What did you find that AI missed? - What business logic issues are present that AI could not detect because it lacks business context?


Part D: Debugging

Exercise 10: The Structured Debug Prompt

Find a bug in your own code (or use the following buggy code snippet). Use the build_debug_prompt function pattern from Section 5 to structure your debugging request:

def calculate_discount(price: float, discount_percent: float) -> float:
    """Calculate the discounted price."""
    if discount_percent > 1:
        discount_percent = discount_percent / 100
    return price - (price * discount_percent)

# Bug: calculate_discount(100, 0.1) returns 90.0 instead of 99.9
# The function assumes values > 1 are percentage points, but 0.1 is decimal

Structure a debug prompt with: error description, code snippet, expected behavior, and actual behavior. Evaluate: does the structured prompt produce a better debugging response than an unstructured one?

Exercise 11: Stack Trace Interpretation

Find a stack trace from your own code, from a project you maintain, or generate one by intentionally triggering an error. Submit it with the stack trace interpretation prompt from Section 5:

"Explain this stack trace. Tell me: what error occurred and where, the call sequence that led to the error, the most likely cause, and what information I should gather to debug further."

Evaluate: how accurate is AI's interpretation? Does it correctly identify the relevant application code versus framework boilerplate?

Exercise 12: Intermittent Bug Hypothesis Generation

Think of an intermittent bug you have encountered (or create a realistic hypothetical). Describe the symptom pattern and what you have already ruled out. Submit it for hypothesis generation using the pattern from Section 5.

Evaluate the hypotheses: which are most plausible given your knowledge of the system? Which can you eliminate immediately? How would you test the remaining hypotheses?

Exercise 13: Rubber Duck Conversation

Find a bug you are currently unable to solve or have recently spent more than an hour on. Use the rubber duck prompting approach from Section 5:

"I'm going to explain a bug to you and I want you to ask clarifying questions until you understand the system well enough to suggest what might be wrong. Do not suggest fixes until you fully understand the context."

After the conversation: did the act of answering AI's questions lead you to the insight, regardless of what AI suggested? Reflect on how articulation affected your understanding.


Part E: Testing

Exercise 14: Comprehensive Unit Test Generation

Write a function (or use an existing one) that has at least three distinct code paths and some edge case complexity. Submit it for comprehensive unit test generation using the prompt from Section 6. Then evaluate:

  1. What happy paths are tested?
  2. What edge cases are tested?
  3. What edge cases were missed?
  4. Are the tests actually correct — do they test what they claim to test?

Add at least two tests that AI missed.

Exercise 15: Edge Case Audit

Take an existing test suite for a function or module you have written. Submit the function and tests with the edge case audit prompt from Section 6:

"What edge cases have I missed? Think about: numeric boundaries, string edge cases, collection edge cases, type edge cases, concurrency edge cases, and time/date edge cases."

Implement at least two of the suggested edge case tests. Do any of them fail? If so, fix the underlying code.

Exercise 16: AI-Generated Tests for AI-Generated Code

Generate a function using AI. Then ask the same AI model to generate tests for it. Run the tests. Now review both the code and the tests critically: - Do the tests cover the important cases? - Are there cases where both the code and the tests have the same incorrect assumption? - What tests would you add that AI did not generate?

Reflect: what are the risks of having AI generate both code and tests for the same feature?


Part F: Documentation

Exercise 17: Docstring Generation and Accuracy

Take a module with undocumented or poorly documented functions. Generate docstrings using the prompt from Section 7. Review each generated docstring: - Is the summary accurate? - Are the arg types and descriptions correct? - Are the raises entries correct — does the function actually raise what is documented? - Are the examples correct and runnable?

For any inaccuracy you find, fix the docstring and note what AI got wrong.

Exercise 18: README Generation

Generate a README for a project you are working on or for a hypothetical project you describe to AI. Evaluate: - Is the installation section accurate for your actual system requirements? - Are the usage examples correct and runnable? - Is there anything missing that a new contributor would need? - Is there anything present that is incorrect?


Part G: Security and Trust Calibration

Exercise 19: The "Can I Explain This?" Test

Take a piece of AI-generated code you have used in a project. Go through it line by line and, for each non-trivial line or block: 1. Can you explain what it does and why? 2. If not, look it up until you can. 3. Are there any lines you cannot fully explain even after investigation?

If you find lines you cannot explain after investigation, that is a signal to rewrite that section until you understand it.

Exercise 20: Dependency Verification Practice

Take a piece of AI-generated code that imports any external packages. For each imported package: 1. Verify the package name is spelled correctly and is the intended package (check pypi.org) 2. Check for known security vulnerabilities (check advisories.python.org or your organization's dependency scanner) 3. Verify the version is not deprecated or near end-of-life 4. Check the license is compatible with your project

Document any issues you find. Reflect: how often do AI-generated imports require this kind of verification?

Exercise 21: Security Anti-Pattern Recognition

Review the following code snippet and identify every security issue before submitting it to AI for review:

import sqlite3
import hashlib

def authenticate_user(username: str, password: str, db_path: str) -> bool:
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Query user from database
    query = f"SELECT password_hash FROM users WHERE username = '{username}'"
    cursor.execute(query)
    result = cursor.fetchone()

    if result is None:
        return False

    stored_hash = result[0]
    # Check password
    input_hash = hashlib.md5(password.encode()).hexdigest()

    conn.close()
    return input_hash == stored_hash

After identifying issues yourself, submit to AI for security review. Compare your findings to AI's findings. Did AI find everything you found? Did AI find anything you missed?

(This code has at least three significant security vulnerabilities. Count yours before checking AI's.)


Instructors: Exercise 21 (Security Anti-Pattern Recognition) is recommended as a classroom exercise done in small groups before revealing AI's analysis. This surfaces student assumptions about what "looks secure." Exercise 16 (AI-Generated Tests for AI-Generated Code) makes a strong point about correlated blind spots and is worth discussing in class. Exercise 4 (Explain-Then-Generate) builds the single most important habit change for AI-assisted development and should be reinforced throughout the course.