{"id":313,"date":"2022-03-20T00:00:00","date_gmt":"2022-03-20T00:00:00","guid":{"rendered":"https:\/\/tac.debuzzify.com\/?p=313"},"modified":"2023-06-24T13:12:25","modified_gmt":"2023-06-24T13:12:25","slug":"debug-skills-python","status":"publish","type":"post","link":"https:\/\/www.the-analytics.club\/debug-skills-python\/","title":{"rendered":"Debug Python Scripts Like a Pro"},"content":{"rendered":"\n\n\n

It took me some time to grasp the idea of debugging.<\/p>\n\n\n\n

I’m sure that’s common with most code newbies. As a self-taught Python programmer, locating issues and fixing them in the quickest possible way was challenging.<\/p>\n\n\n\n

But over the years, I learned several techniques to spot bugs in my scripts. Some had changed, and some I discontinued. In this post, I’ll take you through what I consider the bad, the lovely, and the intelligent ways of debugging Python code.<\/p>\n\n\n\n

Related:<\/i> You Are Not Still Using Virtualenv, Are You?<\/i><\/b><\/a><\/p>\n\n\n\n

Check out the book, Debug It!: Find, Repair, and Prevent Bugs in Your Code<\/b><\/a> because great programmers aren’t the ones who come without any bugs. But they know how to find and fix them quickly.<\/p>\n\n\n\n

Let’s begin with the bad.<\/p>\n\n\n\n

Print statements<\/h2>\n\n\n\n

Perhaps ‘print’ is the most used Python function of all.<\/p>\n\n\n\n

Naturally, anyone who wants to know what’s happening in their code uses print statements. Because that’s the easiest and most widely available choice, it also seems to work fine for smaller scripts.<\/p>\n\n\n\n

Use it to test whether your code reaches a point or check a variable’s value at a specific topic. And also if it’s only for one time.<\/p>\n\n\n

\n
\"A<\/figure><\/div>\n\n\n

But as your code grow bigger, you’re in trouble. Print statements are going to be on all over the project. You’ll quickly lose track of which printed line corresponds to your code’s print statement.<\/p>\n\n\n

\n
\"Multiple<\/figure><\/div>\n\n\n

It gets more complicated if your project executes codes parallel or asynchronous. And it’s not uncommon these days to use parallel execution, either.<\/p>\n\n\n\n

An immediate solution to this problem is to use a description in every print statement.<\/p>\n\n\n

\n
\"Use<\/figure><\/div>\n\n\n

But this is going to suck the soul out of a developer. There’s a better way of doing this. That’s our following technique on the list.<\/p>\n\n\n\n

Related:<\/i> 5 Python GUI Frameworks to Create Desktop, Web, and even Mobile Apps.<\/i><\/b><\/a><\/p>\n\n\n\n

Icecream<\/h2>\n\n\n\n

Printing statements are a tedious, time-consuming process. Icecreams make debugging sweet.<\/p>\n\n\n\n

Icecream is a Python package that lets you inspect variables at different points in your script. In a nutshell, it sometimes prints the value of variables, the function executed, and the line number and file names.<\/p>\n\n\n\n

Here’s how to use Icecream<\/a> to debug your Python code.<\/p>\n\n\n\n

Step I: Install Icecream using pip.<\/p>\n\n\n\n

<\/circle><\/circle><\/circle><\/g><\/svg><\/span><\/path><\/path><\/svg><\/span>
pip<\/span> <\/span>install<\/span> <\/span>icecream<\/span><\/span><\/code><\/pre>Bash<\/span><\/div>\n\n\n\n

Step II: Import Icecream to your Python script<\/p>\n\n\n\n

<\/circle><\/circle><\/circle><\/g><\/svg><\/span><\/path><\/path><\/svg><\/span>
from<\/span> <\/span>icecream<\/span> <\/span>import<\/span> <\/span>ic<\/span><\/span><\/code><\/pre>Bash<\/span><\/div>\n\n\n\n

Step III: Wrap your function calls and statements with ic<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n\n

Icecream makes the life of a developer easy by automatically adding context to every log it creates. That’s a lovely way to debug Python code.<\/p>\n\n\n\n

But this still is additional work.<\/p>\n\n\n\n

Modern IDE like PyCharm and VSCode allows you to stop the code at a specific line and inspect all the local and global variables.<\/p>\n\n\n\n

Here’s the smart way of debugging.<\/p>\n\n\n\n

Related:<\/b> This Is How I Create Dazzling Dashboards Purely in Python.<\/i><\/b><\/a><\/p>\n\n\n\n

How to debug Python code in a modern IDE<\/h2>\n\n\n\n

Live to-debug is a way to speak with your code when running.<\/p>\n\n\n\n

Some of us started coding in Notepad apps. Later we switched to Notepad++<\/a>. Then came the revolutionary Sublime Text<\/a> and Atom<\/a> editors. They are great tools of their times.<\/p>\n\n\n\n

Some of us started with PyCharm<\/a>. I was one of them who fell in love with this excellent IDE. Yet, I switched to VSCode, because it’s free, and its community was (and still is) skyrocketing.<\/p>\n\n\n\n

To my surprise, debugging with\u00a0VSCode<\/a>\u00a0is easy for beginners. That’s what the remainder of this post is about. Let’s break this section into three: debugging with breakpoints, configuration for popular frameworks, and debugging data frames.<\/p>\n\n\n\n

Related:<\/i> How to Create Stunning Web Apps for Your Data Science Projects<\/i><\/b><\/a><\/p>\n\n\n\n

Related:<\/i> How to Create Progressive Web Apps (PWA) in Python?<\/i><\/b><\/a><\/p>\n\n\n\n

Debugging Python scripts with breakpoints in VSCode.<\/h3>\n\n\n\n

You can start a debugger in just three steps. Here’s how:<\/p>\n\n\n

\n
\"Debugging<\/figure><\/div>\n\n\n
    \n
  1. Click on the debugger on the sidebar. It’s this play button with a bug on it.<\/li>\n\n\n\n
  2. Create breakpoints in your code. You can do it by clicking before the line number. A red indicator will appear for every breakpoint you create.<\/li>\n\n\n\n
  3. Start the debugger by clicking the “Run and Debug” button and selecting “Python file” in the dropdown.<\/li>\n<\/ol>\n\n\n\n

    As you do this, VSCode will spin up a thread to run your script and stop where you have your first breakpoint. The screen will appear as follows:<\/p>\n\n\n

    \n
    \"Live<\/figure><\/div>\n\n\n

    As it stopped in the breakpoint you created, you can now see the line is highlighted, the sidebar has changed, and a new toolbar appears on the top right (this location may differ in your window) corner.<\/p>\n\n\n\n

    The toolbar is the controller for your debugger. The play button will ignore the breakpoint and move on to the next. The stop button will stop the debugger, and the refresh button will restart the debugger all over again.<\/p>\n\n\n\n

    I find the step-in button extremely useful. It’s the down arrow key on the debugger toolbar. Please see the below recording to understand how it works and how useful it is.<\/p>\n\n\n\n

    \"VSCode<\/figure>\n\n\n\n

    My first breakpoint was on line number 14. This line calls a function called ‘sum_odd_numbers.’ As I click the step-in key, the interpreter moves to the following line but stops there. It is within the process I call (line number 4.)<\/p>\n\n\n\n

    Pay attention to the variables section in the sidebar. As we are now within the function, the scope changes. Under the ‘local’ area, we see the value of n is 100. The value of v is available because the interpreter hasn’t executed line number 4 yet.<\/p>\n\n\n\n

    But as you keep clicking on the step-in key. You see, the value of ‘v’ is changing as well. As we step inside the loop, you can see the value of ‘i’.<\/p>\n\n\n\n

    Notice that we get to line number 8 only when the value of ‘i’ is odd. As we execute line number 8, the value of ‘v’ increases by the value of ‘i’ at that time.<\/p>\n\n\n\n

    Great, we could narrate everything line by line while our script was running. That’s why live debugging is the more brilliant way to find and fix issues in your code.<\/p>\n\n\n\n

    Configuring VSCode to debug popular Python frameworks.<\/h3>\n\n\n\n

    VSCode supports popular frameworks such as Django, Flask, FastAPI, and Pyramid out of the box. In most cases, you don’t have to configure anything special for these frameworks. When starting the debugger, you only have to select the framework in the dropdown.<\/p>\n\n\n\n

    \n

    If this is the first time you’re working on a Django project, you can install django with <\/i>pip install django<\/i><\/code> and create a django project using the command <\/i>Django startproject <project_name><\/i><\/code><\/p>\n<\/blockquote>\n\n\n\n

    But in certain conditions, you will have to override the defaults. For instance, if another process blocks the 8000 port, Django needs a different one to start. You can give additional information to the debugger using a launch.json file.<\/p>\n\n\n

    \n
    \"Configuring<\/figure><\/div>\n\n\n

     Go to the debugger window and select the “create a launch.json file” option. In the dropdown, choose the framework you’re using. I’ve chosen Django for this illustration.<\/p>\n\n\n\n

    You’ll see a new JSON file open up with some familiar options.<\/p>\n\n\n

    \n
    \"Configuring<\/figure><\/div>\n\n\n

    \u00a0The above file runs the ‘manage.py’ file in the ${workspacefolder} (the root of the project you’ve opened in VSCode). In addition, it takes a command-line argument, ‘runserver.’<\/p>\n\n\n\n

    What it means is it’s about execute\u00a0python manage.py runserver<\/code>\u00a0when the debugger starts.<\/p>\n\n\n\n

    I’ve added another argument by extending the ‘args’ list. In line number 11, I configured the Django dev server’s port to be 5000 instead of its default 8000. This modification will let the debugger run python manage.py runserver 5000<\/code> .<\/p>\n\n\n\n

    Go to a new line and press the space holding your ctrl (or command) key to see your other options. As shown in the figure above, a list of options will pop up.<\/p>\n\n\n\n

    Related: <\/b>How to Execute Shell Commands With Python?<\/i><\/b><\/a><\/p>\n\n\n\n

    Let’s see the debugger in action.<\/p>\n\n\n\n

    Replace the content of \/urls.py with the following content.<\/p>\n\n\n\n