Debugging

Debugging and testing exist because the proof covered in the previous topic is the gold standard for certainty, but writing a full proof for every real program is rarely practical, so most software is instead debugged and tested against specific cases until it can be trusted. Finding errors starts with noticing a symptom: the `calculate_total_size` function from programming fundamentals might report a folder is larger than it actually is, and debugging is the process of working backward from that wrong output to the specific line of code responsible for it. Tracing execution means following a program step by step, the same instruction-by-instruction spirit as the fetch-decode-execute cycle from the very first topic in this series, except done by a person instead of a CPU: printing out the value of `total` after every loop iteration shows exactly where it starts growing by the wrong amount, which immediately narrows the search from "somewhere in this function" down to one specific line, often the moment a subdirectory's own size gets added in by mistake instead of being skipped. An assertion is a statement that must be true at a specific point in a program, written directly into the code and checked automatically every time that point is reached — `assert total >= 0` after the loop is a logical proposition in exactly the sense the previous topic described, and if it's ever false the program stops immediately with a clear signal of exactly where things went wrong, rather than continuing to run and producing a silently incorrect answer somewhere downstream. A test case is a specific input paired with the output it's already known to produce, run against the function to check whether it still behaves correctly: calling `calculate_total_size` on an empty folder should return 0, calling it on a folder containing one 10-byte file should return 10, and calling it on a folder containing a subdirectory should return only the sizes of the actual files, not the subdirectory itself — and this is precisely where testing and proof diverge, since a test case only confirms the function is correct for the specific inputs actually tried, while a proof would confirm it for every possible input at once, which is why a thorough set of test cases is the practical, achievable substitute for a proof that usually isn't. Running the fixed function against all three of those test cases after the bug is found and corrected is what actually confirms the fix worked, and keeping those same test cases around afterward catches the exact same bug immediately if it is ever accidentally reintroduced later.

A bug is reported: the wrong total comes back
the symptom, not yet the cause
Trace execution step by step
print total after every loop iteration
Find the exact line responsible
a subdirectory's size got added in by mistake
Fix it, then run the test cases
empty folder, one file, folder with a subdirectory
Keep the test cases and an assertion in place
catches this exact bug automatically if it ever comes back
Tracing Finds the Exact Line Printing the running total after every step narrows the search fast step 1: entry = notes.txt (10 bytes) total = 10 step 2: entry = report.pdf (40 bytes) total = 50 step 3: entry = Photos (a subdirectory, 500 bytes) total = 550 expected after step 3: total should stay 50 total = 50 the trace shows exactly where the value diverges from what was expected the condition skipping subdirectories is missing or wrong on that one line without the trace, only the final wrong number of 550 would be visible
Assertions Catch It Live, Tests Catch It Every Time Two different safety nets, checked differently An assertion, inline assert total greater than or equal to 0 checked every time the program runs stops immediately if it's ever false Test cases, run on demand empty folder expects 0 one 10-byte file expects 10 folder with a subdirectory expects only the files' sizes a test case confirms correctness for the inputs actually tried a proof would confirm it for every possible input at once a good set of test cases is the practical substitute for a proof

Take debugging further

Ask the copilot about this term, or have our engineers assess it against your process.