Print Debugging
Adding temporary output to see what code is doing.
Also known as: printf debugging, console.log debugging, log debugging
Print debugging means adding temporary output to a program to see what it’s doing: which branch ran, and what the values were.
def apply_discount(order):
print("DEBUG order:", order.id, order.total, order.coupon) # what came in?
if order.coupon:
print("DEBUG coupon branch")
...
console.log("user", user);
console.table(items);
console.log({ total, tax }); // prints names with values
It’s quick, works anywhere (servers, scripts, tests, CI), and needs no tools.
Making it useful
- Label what you print:
print("subtotal:", subtotal), not justprint(subtotal). - Print inputs and outputs around the suspect code, to narrow the problem (divide and conquer).
- Show types and edge values:
repr(x)shows quotes, whitespace andNone. - Add context: IDs, loop indexes, timestamps.
- Print in loops sparingly, or you’ll drown. Limit to a condition.
- Use the right stream: errors to stderr.
Remember to clean up
- Remove it before committing. Stray prints end up in production logs. Search for
DEBUG, or use a unique marker. - Never print secrets, tokens or personal data.
- For output you want to keep, use proper logging with levels, instead of prints.
Print or debugger?
Prints are great when you can’t attach a debugger, for timing-sensitive code, and when you want a record of a whole run. A debugger is better when you don’t yet know which value matters, because you can inspect everything at the pause point without re-running. Good engineers use both.
If nothing prints, the code might not be running, which is useful information too.