What you will learn
  • Specify inputs, outputs, and exceptional cases before requesting code.
  • Ask for a minimal change instead of an unexplained rewrite.
  • Use an error message and small reproducible example in a debugging prompt.
  • Check generated code with normal and boundary cases.
  • Explain each important line before accepting the solution.

Before you begin

Complete Python variables, conditions, and functions before this lesson. Use Python 3 in an existing local environment; the example needs no external libraries.

Describe behavior before asking for code

You want to average a short list of sensor readings. An assistant can generate a function quickly, but it still needs decisions from you. What happens when the list is empty? Are the readings already numbers? Should missing values be ignored or rejected? These are requirements, not syntax details.

Write a small specification: input is a nonempty list of numeric readings; output is their arithmetic mean; an empty list should raise a clear error. For this teaching example, reject missing data before calling the function. A larger program may handle it differently, but the behavior should be explicit.

A specification lets you test the output independently. For readings 20, 22, and 24, the mean must be 22. For a single reading of 19, the mean must be 19. Decide these expectations before running generated code. Otherwise you risk treating whatever appears on screen as the intended result.

Ask for a small, explainable solution

Weak prompt: ‘Write my sensor app.’ The request mixes data collection, storage, calculations, interface design, and hardware. A large response can hide errors that a beginner cannot yet identify.

Improved prompt: ‘Write one Python 3 function named mean_reading. It accepts a nonempty list of numeric readings and returns their arithmetic mean. Raise ValueError for an empty list. Use only built-in Python features. Include three example calls covering several readings, one reading, and an empty list. Explain each important line and do not add hardware or file access.’

The following small implementation is suitable for inspecting the requested behavior. Python’s built-in sum adds numeric items, len counts them, and raise reports an invalid input. These language features are documented in the Python built-in functions reference. No package installation is needed.

python
def mean_reading(readings):
    if not readings:
        raise ValueError("At least one reading is required")
    return sum(readings) / len(readings)

print(mean_reading([20, 22, 24]))
print(mean_reading([19]))
try:
    mean_reading([])
except ValueError as error:
    print(error)

The function checks the empty-list case before dividing. The return line adds the readings and divides by their count. The try/except block demonstrates how a caller can catch the intended error without terminating the demonstration.

Expected result: Expected output is 22.0, then 19.0, then At least one reading is required, each on its own line. This draft’s example has been manually traced; local execution is still required before publication.

Read an error as evidence

A traceback is Python’s report of where an exception occurred and how the program reached that point. It is not a judgment of your ability. Read the final error type and message, then inspect the referenced line in your own code. The assistant can help explain the report if you provide the relevant function and exact input.

Suppose you pass the strings ‘20’ and ‘22’ rather than numbers. The intended function does not convert text, so adding these values as numeric readings fails. The correct next step depends on the specification: convert validated text at the input boundary, or reject it. Blindly adding a conversion everywhere can conceal data-quality problems.

Follow-up prompt: ‘The caller passes ["20", "22"] but the function expects numbers. Explain the mismatch. Show a separate input-conversion step and how it should handle a value such as "unknown". Do not change the calculation’s documented contract.’ This requests a diagnosis and a bounded change, not a complete rewrite.

Test the behavior, not the assistant’s confidence

Verification: Predict the output for [18, 24] before execution; it should be 21. Check a single value and the empty list. Then test a negative reading if your domain allows it. A test should target a behavior that could fail, rather than merely repeat the code’s own logic.

For a bug fix, keep the input that exposed the bug and rerun it after the change. Also rerun earlier valid cases. This guards against regressions, where a repair breaks behavior that previously worked. Keep changes small enough that you can explain why they affect the failing case.

Passing these tests does not prove the function handles every possible object. It supports the stated numeric-list contract. If you later accept files, network data, or hardware readings, new validation requirements arise. Update the specification and tests together instead of assuming a small example is a finished production system.

Use AI to strengthen your own debugging

Ask the assistant to explain unfamiliar syntax, suggest a smaller reproducer, or propose a hypothesis you can test. A reproducer is a short program and input that still show the problem. Removing unrelated code makes both human and AI diagnosis easier.

Do not paste passwords, private keys, or unrelated personal data into a debugging prompt. Replace them with clearly marked dummy values while preserving the structure needed to reproduce the issue. Review proposed installation commands and file operations before running them; generated commands can have consequences beyond the example.

Before accepting a change, explain its input, output, failure behavior, and dependencies in your own words. If you cannot, request a smaller version or review the prerequisite concept. AI assistance is most useful when each interaction leaves you better able to inspect the next piece of code.

Important terms

Specification
A description of required program behavior.
Exception
A reported condition that interrupts normal program execution.
Traceback
Python’s report of the calls and lines associated with an exception.
Reproducer
A small program and input that demonstrate a problem.
Regression
A change that breaks previously working behavior.

Mini project: Debug a small mean calculator

  1. Write the expected behavior for multiple readings, one reading, and an empty list before running the example.
  2. Execute the code in Python 3 and compare all output lines with your predictions.
  3. Pass a list containing a nonnumeric string. Read the traceback and ask for a diagnosis using the exact code and input.
  4. Decide where conversion or rejection belongs. Finish when you can explain the decision and all intended cases pass.

Common mistakes and debugging

  • Requesting a whole application before defining behavior: start with one testable function.
  • Pasting only ‘it does not work’: include the exact error, input, and smallest relevant code.
  • Accepting a rewrite you cannot explain: request the smallest change and its rationale.
  • Testing only ordinary inputs: include empty, boundary, and invalid cases appropriate to the contract.

Independent challenge

Specify a function that reports the minimum, maximum, and mean of readings. Decide its empty-input behavior before asking for code, and design three tests independently.

Check your understanding: 10 questions

  1. Why define empty-list behavior before coding?

  2. What does a traceback help identify?

  3. What should mean_reading([18, 24]) return?

  4. Why rerun valid examples after fixing a bug?

  5. Does passing three tests prove universal correctness?

  6. In your own words, what does “Specification” mean?

  7. In your own words, what does “Exception” mean?

  8. In your own words, what does “Traceback” mean?

  9. In your own words, what does “Reproducer” mean?

  10. In your own words, what does “Regression” mean?

Quiz answers

Reveal all 10 answers after your attempt
  1. The program needs an explicit policy for an input that cannot produce a mean by ordinary division.
  2. The exception type, message, and relevant calls or lines where the failure occurred.
  3. 21.0, because the sum is 42 and there are two readings.
  4. The fix may introduce a regression in behavior that worked previously.
  5. No. It supplies evidence for those cases and the stated contract, not every possible input or environment.
  6. A description of required program behavior.
  7. A reported condition that interrupts normal program execution.
  8. Python’s report of the calls and lines associated with an exception.
  9. A small program and input that demonstrate a problem.
  10. A change that breaks previously working behavior.

Summary

Define behavior, request a small implementation, inspect errors as evidence, and test changes against independent expectations. Keep each accepted solution explainable.

Continue learning

Continue with USE07 to apply precise feedback and revision to writing rather than code.

Choose a connected learning path

Sources and further reading

Prepared 2026-09-18. Draft; code manually traced. Python execution and exact runtime recording remain pending; no hardware test is claimed.

GO DEEPER

Extra reading & source documents

Optional reading alongside the lessons. These sources do not add to your course lesson count.

Explore the AI model guides →