5 Useful hacks to Debugging in Python Code

Debugging in Python is one of the most crucial and essential skills for every developer. Remember that writing code is only half the journey, but ensuring that your code runs correctly, efficiently, and yields the desired result is the real challenge in coding. Even experienced and professional coders encounter errors regularly.  The primary difference between professional coders and newcomers is the ability to detect, analyze, and resolve errors encountered. 

Types of errors that might occur

  1. Logical Error.
  2. Syntax Error 
  3. Import Error
  4. Type Error.
  5. Dependency and version conflicts
  6. Performance bottlenecks 
  7. Production error handling 
  8. Multi-threading and concurrency issues.

Errors are a natural part of coding.  No matter how skilled you are, errors are inevitable.

Debugging in Python

Why is debugging in Python necessary?


Python is typed differently from languages like Java or C++; thus, you don’t need to state the variable type directly.
Python is more unique and powerful due to its flexibility, but it is also riskier because it may produce type-related problems like combining numbers and strings. Any language’s developers can swiftly identify these flaws before they become more serious by using debugging techniques.

				
					Age= 35
print(Age+5) 
				
			

The above print statement will generate a TypeError: can only concatenate str (not “int”) to str. 

👉🏻The Python rule of indentation can be tricky. 

Python enforces indentations as part of its strict syntax. So, in case you miss a small spacing mistake, it won’t let your code run.  Debugging in Python ensures that such errors are identified and fixed efficiently.

Built in Python tools to catch errors.

Python provides powerful and simple built-in tools that make it easier to detect, trace, and handle errors while writing code. 

  1. Use the print function smartly.

    One of the best and simplest ways is to use a print statement humbly. Basically, use print to display the variable value and program state; you can check what’s happening in your code at each step. 
Example 1.
				
					def calculate_total(prices):
    total = 0
    For price in prices:
        total += price
        print(f"Adding {price}, total so far: {total}")  # Debugging step
    return total

print(calculate_total([10, 20, 30]))
				
			
Example 2.
				
					x = "10"
y = 5
print("Before operation:", x, y)

# Suspected error
result = int(x) + y
print("After operation:", result)
				
			

If the conversion (int(x)) wasn’t added, the error would have been obvious in the debug points.

2. The ‘assert’ statement

The assert statements are like the main minicheckpoints inside your code. They verify whether a condition holds during execution or not.  If the condition is false, Python immediately raises an AssertionError. 

  • Catch unexpected values: works well for assumptions in your code. 
  • Writing defensive code: ensures invalid states are caught early.
				
					def divide(a, b):
    assert b != 0, "Denominator must not be zero!"
    Return a / b

print(divide(10, 2))  # Works fine
print(divide(10, 0))  # AssertionError

				
			

Useful hacks to identify Errors in python code

  1. Use Try-Except Blocks

The Try and except block to manage exceptions gracefully. When a potential error-causing or error-prone area is wrapped in try-except blocks, the program won’t crash abruptly; it can recover or show as you coded or show a helpful message.

				
					try:
    num = int(input("Enter a number: "))
    print("Square:", num * num)
except ValueError:
    print("Oops! That wasn’t a valid number.")

				
			

Instead of crashing the code, it displays the error softly, clearly as a message. 

2. Logging error effectively 

When you are working on bigger projects, it’s better to use logging instead of just printing as statements. Logging error helps you keep a record of errors without stopping the program or cluttering the output. This is the most effective way of going back and checking what went wrong earlier. 

				
					import logging

logging.basicConfig(level=logging.ERROR)

try:
    file = open("data.txt")
Except FileNotFoundError as e:
    logging.error("Error happened: %s", e)
				
			

3. Use Python built-in debugger(pbd) 

Every time use the print statement is not enough, but sometimes you need to pause the program and inspect what’s happening step by step.  Python has a built-in debugger called pdb (p for Python db for debugger) that helps the developers to do exactly that.

3.1 What is PBD? 
Pbd is an interactive Python debugging tool that lets you. 

    • Pause the code execution at a certain point. 
    • Check the value of the variable.
    • Step through the program line by line 
    • Find out exactly where things are going wrong.

Note: it comes pre-installed with Python, so you don’t need to install anything extra. 

3.2 How can I incorporate PBD into my code?

Wherever you wish to halt your program, add the line below to launch the debugger.

				
					import pdb; pdb.set_trace()

				
			

When Python reaches this line, the program will enter debug mode.

Example: 

				
					def calculate_area(length, width):
    area = length * width
    return area

length = 5
width = "10"   # Mistake: width should be an integer

import pdb; pdb.set_trace()  # Debugger starts here
result = calculate_area(length, width)
print("Area:", result)
				
			

The program will run smoothly up to width “10” when the aforementioned code is executed, pausing at pdb set_trace(). You can now type commands in the debugger.

3.3 Typical PDB commands

  • n(next): advance to the code’s subsequent line.
  • c(continue): The program is run until the subsequent breakpoint.
  • l(List): Displays the adjacent lines of code
  • p: outputs a variable’s value.
  • q(quit): To exit the debugger.
				
					(Pdb) p length
5
(Pdb) p width
'10'
(Pdb) q
				
			

4. Read and understand the stack trace.

Stack traces are the first clue that Python gives you when something went wrong, but many beginners and even some experienced coders find them intimidating.  At first glance, it might look overwhelming — but it’s actually Python’s way of telling.  It is a report that Python generates when an error occurs.

It shows: 

  • A sequence of function calls that led to an error.
  • The file name and line number where the error happened.
  • The type of error and the error message. 

You should think of it like a map showing the exact location for you to reach.

Let’s see how to read it. You can use the Online IDE to run the code: Replit, Google Colab, and Programmiz, etc.

Example:

				
					def divide(a, b):
    return a / b

def calculate():
    x = 10
    y = 0
    return divide(x, y)

print(calculate())
				
			

Output: 

				
					Traceback (most recent call last):
  File "example.py", line 9, in <module>
    print(calculate())
  File "example.py", line 7, in calculate
    return divide(x, y)
  File "example.py", line 2, in divide
    return a / b
ZeroDivisionError: division by zero
				
			

Understanding: 

  1. Traceback (most recent call last):
    • This tells you that Python is about to show the sequence of calls that led to the error.
  2. File “example.py”, line 9, in <module> → print(calculate())
    • Shows that the error started when we called calculate() in the main program.
  3. File “example.py”, line 7, in calculate → return divide(x, y)
    • The problem continued inside the calculate() function.
  4. File “example.py”, line 2, in divide → return a / b
    • Finally, Python pinpoints the exact line where the error happened: dividing by zero.
  5. ZeroDivisionError: division by zero
    • The actual error type and message.
  1. Use Linters and code Formatters

Python has a way to catch the errors, even before you run the code. The method to check is checking the style issues, unused variables, or common mistakes. You can use Linters and code formatters; they act like a spell-checker for your Python code. 

5.1 What is a Linter?

A Linter analyzes your code and highlights: 

  • Syntax errors ( like  missing colons or brackets)
  • Style issues ( like extra spaces or bad variable names) 
  • Unused imports or variables
  • Potential bugs

Some popular Python linters are: 

  • Pylint
  • Flakes8
  • Pyflakes

5.2 How to use Pylint?

Start by creating a .py file and then add the code to it and save it.

				
					# buggy_code.py
def add(a,b):
  return a+ b

print(add(2,3))
				
			

If you run: 

				
					Pylint buggy_code.py 
				
			

You might see warnings about spacing or naming. This helps you fix the issues before they cause problems.

Previous>>                                                                                                                                                                                                                                               <<Next