Debugging
Design Well A careful design limits the necessary debugging - think “top-down” Write comments as you go, especially invariants –You can test the invariants in your code
Test Early and Often Have test cases ready as part of your design Write code in pieces, and test each independently –Usually software engineering “modules” –Also useful “in the small” Write & test I/O before algorithm, eg.
Test Cases Examples from the problem, but also… Boundary conditions Unusual inputs (but legal ones) Random test cases (if you can tell if the program was right) Small known cases, then large random ones Exhaustive, if possible (auto-generate!)
Two Kinds of Debugging Online - using IDE Offline - using output
Online Debugging Set break points Trace functions Step (“into” vs. “over”) Examine the call-stack Check values of variables Some environments save information after a crash
Offline Debugging Copious print statements Give variable name, value and location Comment out when “done” –Too much output hurts –But you might need those statements later
“Scaffolding Code” Print statements for debugging Functions to nicely print internal data structures Test case generators
Miscellaneous Don’t mix line and token I/O –In C++, this means use getline or cin<<, not both Make arrays bigger than they need to be or use self-expanding data structures Use string and other library classes when possible Java must be Main.class, no public classes
Collection Data Structures Stack (push, pop - last in first out) Queue (enqueue, dequeue - first in first out) Hash table or “map” - use, but don’t create List (linked), Vector (array-based)