Debugging is the process of finding why a program behaves incorrectly and correcting the defect. A useful cycle is think, code, test, debug, and repeat: understand the task, identify inputs and outputs, write a solution, check it, then improve it. section 2.5 section 36.0
Use a systematic process when a test fails:
- Start with the failing inputs and the output you expected. section 36.3
- Trace the program line by line, recording each variable’s value as though you were the computer. section 36.3
- Treat every line skeptically, including lines that look simple, and explain each step in plain English. section 36.3
- Use error messages, line numbers, print statements, or different inputs to narrow the problem. section 36.0
Test small pieces before integrating them. For example, test a file-reading function, print its returned values, then test a phone-number sanitizing function before analyzing the complete data set. Smaller code pieces create natural points for testing and debugging. section 23.3 section 19.3
Tracing a failing function
A unit test may call absolute_value(0) and reveal that execution reaches an elif n > 0 branch without returning 0. Following the variable value line by line exposes the missing case. A debugger can display these values at each step, but you must still decide why the result is wrong. section 36.3
Listing 23.4. Read names and phone numbers from a file
friends_file = open('friends.txt') #1
(names, phones) = read_file(friends_file) #2
print(names) #3
print(phones) #3
clean_phones = sanitize(phones) #4
print(clean_phones) #5
friends_file.close() #6
Follow a complete small debugging check: open a text file, run two functions, print intermediate results, and close the file. section 23.3















