Table of Contents
Debugging: The Detective Work of Programming
Debugging is the process of finding and fixing errors (bugs) in your code. Every programmer spends time debugging - it's a normal and important part of programming!
What are Bugs?
Bugs are errors in your code that cause it to behave differently than expected. The term "bug" comes from an actual moth found in an early computer in 1947!
Types of Bugs
1. Syntax Errors
Mistakes in the code structure - like typos or missing punctuation.
Syntax Error Examples
// Missing closing parenthesis
print("Hello World" ❌
print("Hello World") ✅
// Misspelled keyword
funciton greet(): ❌
function greet(): ✅
// Missing quotes
name = Alice ❌
name = "Alice" ✅
2. Logic Errors
Code runs but produces wrong results because the logic is incorrect.
Logic Error Example
// Wrong: This calculates area incorrectly
function calculateRectangleArea(length, width):
return length + width ❌ (should be multiplication)
// Correct version
function calculateRectangleArea(length, width):
return length * width ✅
3. Runtime Errors
Errors that occur while the program is running, often due to unexpected conditions.
Runtime Error Examples
// Division by zero
result = 10 / 0 ❌ (causes runtime error)
// Accessing array out of bounds
numbers = [1, 2, 3]
print(numbers[5]) ❌ (index 5 doesn't exist)
// Better approach with checking
if index < length(numbers):
print(numbers[index]) ✅
else:
print("Index out of range")
Debugging Strategies
1. Read Error Messages Carefully
Error messages often tell you exactly what's wrong and where.
Understanding Error Messages
Error: NameError: name 'userName' is not defined
Line 15: print(userName)
// This tells us:
// - Type: NameError (variable doesn't exist)
// - Problem: 'userName' is not defined
// - Location: Line 15
// - Solution: Define userName or check spelling
2. Use Print Statements
Add print statements to see what's happening in your code.
Debugging with Print Statements
function calculateGrade(score, total):
print("DEBUG: score = " + score) // Check input
print("DEBUG: total = " + total) // Check input
percentage = score / total * 100
print("DEBUG: percentage = " + percentage) // Check calculation
if percentage >= 90:
grade = "A"
else if percentage >= 80:
grade = "B"
else:
grade = "C"
print("DEBUG: final grade = " + grade) // Check result
return grade
3. Rubber Duck Debugging
Explain your code line by line to a rubber duck (or any object). Often, you'll spot the problem while explaining!
4. Check Your Assumptions
Verify that your inputs and variables contain what you think they do.
Checking Assumptions
function processUserInput(input):
// Assumption: input is a number
// Let's verify this assumption
print("Input received: '" + input + "'")
print("Input type: " + typeof(input))
if typeof(input) != "number":
print("ERROR: Expected number, got " + typeof(input))
return null
// Now we can safely use input as a number
return input * 2
Testing Your Code
Why Test?
- Catch bugs before users do
- Ensure code works as expected
- Make sure changes don't break existing functionality
- Build confidence in your code
Types of Testing
1. Manual Testing
Run your program and try different inputs to see if it works correctly.
Manual Testing Checklist
// Testing a login function
Test Cases:
1. Valid username and password ✓
2. Valid username, wrong password ✓
3. Invalid username ✓
4. Empty username ✓
5. Empty password ✓
6. Very long username ✓
7. Special characters in password ✓
2. Automated Testing
Write code that tests your code automatically.
Simple Automated Test
// Function to test
function add(a, b):
return a + b
// Test function
function testAdd():
// Test case 1: positive numbers
result1 = add(2, 3)
if result1 == 5:
print("✓ Test 1 passed")
else:
print("✗ Test 1 failed: expected 5, got " + result1)
// Test case 2: negative numbers
result2 = add(-1, -2)
if result2 == -3:
print("✓ Test 2 passed")
else:
print("✗ Test 2 failed: expected -3, got " + result2)
// Test case 3: zero
result3 = add(0, 5)
if result3 == 5:
print("✓ Test 3 passed")
else:
print("✗ Test 3 failed: expected 5, got " + result3)
// Run tests
testAdd()
Common Debugging Techniques
1. Binary Search Debugging
If you have a large program with a bug, comment out half the code to narrow down where the problem is.
2. Start Simple
Test with the simplest possible inputs first, then gradually increase complexity.
3. Check Edge Cases
Test unusual or extreme inputs:
- Empty inputs
- Very large numbers
- Negative numbers
- Special characters
Edge Case Testing
function divide(a, b):
// Edge case: division by zero
if b == 0:
return "Error: Cannot divide by zero"
return a / b
// Test edge cases
print(divide(10, 2)) // Normal case: 5
print(divide(10, 0)) // Edge case: Error message
print(divide(0, 5)) // Edge case: 0
print(divide(-10, 2)) // Edge case: -5
Debugging Tools
1. Debugger
Most programming environments have debuggers that let you:
- Step through code line by line
- Set breakpoints to pause execution
- Inspect variable values
- Watch how variables change
2. Logging
Instead of print statements, use proper logging:
Logging Example
function processOrder(order):
log.info("Processing order: " + order.id)
if order.items.length == 0:
log.warning("Order " + order.id + " has no items")
return false
total = calculateTotal(order.items)
log.info("Order total: $" + total)
if total > 1000:
log.warning("Large order detected: $" + total)
return true
🎯 Debugging Practice
Find and fix the bugs in these code snippets:
// Bug 1: Find the syntax error
function greetUser(name {
return "Hello, " + name + "!"
}
// Bug 2: Find the logic error
function isEven(number):
if number % 2 == 1:
return true
else:
return false
// Bug 3: Find the potential runtime error
function getFirstItem(list):
return list[0]
Best Practices for Bug Prevention
- Write clear, readable code - easier to spot mistakes
- Use meaningful variable names - reduces confusion
- Test frequently - catch bugs early
- Handle edge cases - prevent runtime errors
- Add comments - explain complex logic
- Keep functions small - easier to debug
When You're Stuck
- Take a break - fresh eyes often spot problems
- Ask for help - explain the problem to someone else
- Search online - others have likely faced similar issues
- Read documentation - make sure you're using functions correctly
- Start over - sometimes rewriting is faster than debugging