During our daily code writing process, we will inevitably write various errors, which may be syntax errors, logic errors or runtime errors. The most complex answer we can use is to detect errors. You can also detect errors by carefully reading backtracking, using debugging tools, using linters for static analysis, and running tests to ensure that problems are identified before and during runs.
1. Use print statement for debugging
Debugging with print statements is like putting signposts on the way you are going, and I personally believe this in my metaphor
Just as a road sign guides you and tells you where you are, the print statement in the code displays the current value of the variable and where the program executes.
By checking these “signs” you can determine if you are on the right path or if something goes wrong.
print(f"Hello, World!\n");
Insert print() statement at key points in the code to output variable values and track execution flow. This can help you understand what is happening at different stages.
For example:
We use the print statement in the line as a signpost on the path (code flow) to tell you where you are and what is happening. If something goes wrong, you can use these checkpoints to find out where the path (code) leads you astray.
def hiking_trip(start, destination): print(f"from{start}Start hiking。") # Road Sign 1 midpoint = (start + destination) / 2 print(f"Arrive at the midpoint:{midpoint}.") # Road Sign 2 if midpoint > 50: print("The midpoint is quite far!") # Road Sign 3 print(f"Continue to your destination:{destination}.") # Road Sign 4 return destination hiking_trip(0, 100)
2. Use Python's built-in pdb module
Using Python's pdb module is like pausing a movie and playing frame by frame.
Just like you can pause, rewind, or fast forward movies to see what is going on, pdb lets you pause code at any time, check what is going on, and browse the code step by step. This way, you can double-check each part of the code to find out where it might go wrong.
Use this pdb module to set breakpoints and execute the code step by step in interactive way. First insert the location where import pdb; pdb.set_trace() is to be paused.
Order
python -m pdb your_script.py
For example:
For example, by adding pdb.set_trace() to your program, the execution will stop at that line, allowing you to interact with the prompt pdb. Once the prompt is reached.
import pdb def example_function(x, y ): result = x + y pdb.set_trace() # Execution will be paused here print(f"turn out{result}") return result example_function(3, 5)
You can use various commands to debug, for example:
n: Go to the next line of code. s: Enter the function call. c: Continue to execute until the next breakpoint.
3. Utilize the IDE debugger
Using an IDE debugger is like having a remote with advanced features while watching a movie.
You can pause, skip scenes and view behind-the-scenes details, and the IDE debugger allows you to set breakpoints, check variables, and control the code flow visually.
Take advantage of built-in debuggers in IDEs such as PyCharm or VSCode. These tools provide a graphical interface for setting breakpoints, checking variables, and stepping through code.
For example:
When debugging a program in an IDE such as PyCharm or VSCode, you can set breakpoints at the key points you need in your code, similar to pausing a movie in a significant scenario. Check the variables thoroughly at any time, just like seeing the details behind the scenes of the movie. Execute one line of code at a time, just like skipping frame by frame in a movie using a remote control.
def movie_scene(start, end): scene_duration = end - start # This is the "movie length" of the code important_event = start + scene_duration // 2 #The Midpoint of "Movie" return f"The important event occurs in {important_event} seconds." movie_scene( 0 , 120 )
When the debugger pauses execution, you will be able to execute the following commands:
Check the values of start and end. See what the scene_duration evaluation results are. Span to the next row to calculate the important_event.
4. Use logging to get better insights
Using logging instead of printing statements is like saving a detailed diary instead of a sticky note.
If you need quick bookkeeping, you can use a print statement, which works like a sticky note, which provides you with quick reminders, while a diary (record) allows you to record different levels of details, from random observation to key issues.
Logging is a little more complicated. You can view them based on the importance of the logs and adjust the details you want to view, helping you track what is happening in your code more systematically.
import logging (level=) ('This is a debug message')
Replace the print() statement logging with Python's module. The log can record messages at different levels (DEBUG, INFO, WARNING, ERROR, CRITICAL) and control the amount of detailed information displayed. For example:
DEBUG: Details, used to diagnose problems.
INFO: Confirm that everything goes as expected.
WARNING: Indicates that something unexpected happened, but the program is still running.
ERROR: A more serious problem, the program may not be able to continue running.
CRITICAL: A serious problem means that the program may not continue to run.
import logging # Configure logging to display all levels(level=) def hill_log ( start, destination ): (f"from{start}Start hiking{destination}。") # INFO level for normal process midpoint = (start + destination) / 2 (f"The midpoint is{midpoint}。") # Detailed information DEBUG level if midpoint > 50 : ("The midpoint is farther than expected!") # WARNING level for potential issues if destination - start > 100 : ("This time the hike was too long!") # Error level for major issues if destination - start > 200 : ("It's impossible to walk! The destination is too far!") # CRITICAL level for serious problems return destination hill_log(0, 250)
In this example, you can see how each log level is more organized and helps you display information based on importance, just like a diary, it allows you to sort out your journey. In addition, it allows you to filter or view logs at any time, print is much more powerful than writing statements (notes) everywhere in your code. I highly recommend this for beginners!
5. Carefully check backtracking
A closer look at the backtrack is like following the map to find where you’re lost on your hike.
The map (backtracking) shows the exact path you are taking and highlights where the error is made. By carefully tracing your steps on the map, you can accurately find out where the error occurred and understand what caused the error, thus helping you get back on track.
Read the complete backtrack of the error message carefully. They provide detailed information on where and why the error occurred and help you find out where the problem is.
Traceback(most recent call last): File "", line 8, in <module> main() File "", line 5, in main result = divide_numbers(x, y) File "", line 2, in divide_numbers return a / b ZeroDivisionError: division by zero
ZeroDivisionError: division by zero–– –– The actual error message.
6. Use try and except for error handling
Using try and except for error handling is like wearing a seat belt while climbing.
The seat belt (try block) allows you to continue climbing (code execution), but if you slip (an error occurs), the seat belt will grab you (except block) and prevent falling (program crash). This way, you can safely browse the dangerous parts of your code without suddenly stopping everything.
Wrap the code that may throw an error in a try block and handle the exception using the except block. This can help you manage and understand errors without causing program crashes.
example
try: risky_code() except Exception as e: print(f"An error occurred: {e}")
7. Check with type
Just like checking that the ingredients are correct and the quantity is correct before starting cooking, type checking ensures that the variables and functions have the correct type before running the code. This can help you spot potential confusion (type-related errors) early and prevent problems from breaking your program later.
Use type prompts and tools mypy to perform static type checking and catch type-related errors before running.
Order
mypy your_script.py
8. Test with assertions
You use assertions to check if the conditions in your code are correct at a specific point. If something doesn't look natural, assertions will immediately catch it, helping you discover and fix logical errors so that they don't cause bigger problems.
Use the assert statement to verify whether the conditions for each point in the code are true. Assertions can help detect logical errors as early as possible.
example
assert x > 0, "x must be positive"
9. Use Linters to analyze the code
Using linters to analyze code is like doing a grammar check on your writing.
Just as the grammar checker highlights errors, inappropriate wording and style issues in text,
linter will scan your code for syntax errors, encoding style violations, and potential errors. This helps you clean up your code, making it more readable, more consistent, and error-free.
Use linters such as pylint or flake8 to capture syntax errors, stylistic problems, and potential errors.
Command: pylint your_script.py
10. Monitor with a code analyzer
Using a code analyzer is like using a fitness tracker to monitor your workout.
Why I'm saying this to fitness trackers, because just like fitness trackers can measure your performance, identify areas that need improvement, and provide guidance to you when needed, code analyzers can track the same work. How your program runs and highlights where it runs slower or has problems. This helps you optimize your code and improve its efficiency.
Use the analysis tool cProfile to measure the performance of your code and identify bottlenecks or areas that may cause unexpected behavior.
Command: python -m cProfile your_script.py
This is the article shared about the practical skills of Python code debugging Debug. For more related Python code debugging Debug content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!