Debugging with Python Part 2

Debugging with Python Part 2

Debugging with Python - Part 2

Debugging Techniques - Part 1

Refer this article for Debugging with Python - Part 1.

Now that we know about errors, let’s try to fix them or prevent them from happening. This process of identifying and resolving errors in the program is known as Debugging. Debugging is a common concept In every programming language and following concepts are common despite the language. Moreover, Python offers a variety of Python specific tools and techniques with regard to these common debugging techniques. Let’s explore these common concepts in debugging and available Python specific tools for each concept.

In order to rectify compile errors, we discussed how to interpret error messages. Additionally, we can use tools like linters for code quality checks and benefit from code reviews for collective insights.

To find and fix runtime errors, we could use tools and techniques like logging, exception handling, debuggers, and unit testing for effective error detection and resolution.

To resolve logical errors in code, we may use print statements for debugging, logging for tracking, debuggers for in-depth examination, and unit testing for identifying logical issues. Moreover, code reviews remain crucial for catching logical errors through collaborative analysis.


1. Code Linters:
Code linters are tools that analyze the code to detect potential compile and runtime errors and stylistic incompatibilities. Hence, linters are highly beneficial to enhance the overall quality of software programs by way of improving the readability and consistency. pylint and flake8 are two of the most common Python specific linters.

2. Print Statements
The simplest debugging technique involves strategically placing print statements in our code to inspect variable values and execution flow. This helps in identifying the logical errors of the code and understanding the behavior of the program.

Let’s look at the code snippet below which defines a function to calculate square numbers of all the elements for a given list. We have placed the print(i, nums[i]) statement to see the flow of the for loop and check if the loop produces the result as intended.

def square_numbers(nums):
    length = len(nums)

    for i in range(0, length):
        nums[i] = i ** 2

    return nums
    

print(square_numbers([1, 2, 3, 4, 5]))

The above code outputs the following in the terminal.

[0, 1, 4, 9, 16]

3. Ice Cream Module
Using Print statements is not a best practice when it comes to working on large projects. However, if we are working on a smaller code example or a code snippet and would like to quickly check the code logic, Python has another more convenient debugging technique to replace the conventional print statements. icecream is a Python package which provides for injecting print statements with minimal code modification.

Let’s rewrite the above code snippet with using icecream module. We have imported ic function form the module, which can be used to check the output, compared to the given input. Moreover, we can disable and enable the ic() functions just by using ic.disable() or ic.enable()functions.

from icecream import ic


def square_numbers(nums):
    length = len(nums)

    for i in range(0, length):
        nums[i] = i ** 2

    return nums


ic(square_numbers([1, 2, 3, 4, 5]))

The above code outputs the following in the terminal and lets us compare the input values with the output values easily.

ic| square_numbers([1, 2, 3, 4, 5]): [0, 1, 4, 9, 16]

4. Logging Module
Python’s built-in logging module allows us to track events when a program is executing and write status messages to the terminal or to a separate file. This is another flexible alternative for print statements, as we can choose what level of messages to show and it is easy to turn off logging.



The above techniques are some basic debugging techniques. In the next article we will go a step further and learn about more professional techniques of debugging, i.e. exception handling, debuggers, unit testing and code reviews.

Comments

Popular posts from this blog

OOP with Python - Part 2

Data Structures - Part 2

OOP with Python - Part 1