Introducing IceCream: Never Use Print() To Debug Your Python Code Again

Why I stopped using print() statements for debugging and why you should too

Avi Chawla
Towards Data Science

--

Photo by bryn beatson on Unsplash

Motivation

Errors are almost inevitable while programming. In fact, it is rightly said that a programmer spends a significant amount of their time debugging to make their code error-free.

While debugging, using print() statements to understand the flow of the pipeline and spot unexpected behavior is undoubtedly the most widely adopted approach.

However, using print() has numerous caveats, such as:

  • Print statements are usually intended to display an output to the user. If the programmer uses print() to debug, after debugging is over, the programmer should be cautious of removing only those specific print() statements that were intended for debugging.
  • Often, during debugging, you may print multiple variables one after the other. In such cases, the programmer has to manually format the output to enhance its readability.

Above, we print two variables. Although here we know that the first variable is var_1 and the second is var_2, as the number of variables increases, it might require you to look back and forth between the code and the output to figure out which output corresponds to which variable.

Of course, we can print more details, like below, but that just adds to your work.

  • Sometimes, the programmer might also be interested in printing the line number, the name of the function and its input, etc., which adds to the complexity of writing long/many print() statements.
  • In most situations, the codebase is not restricted to just one file. Instead, there are multiple files that form the pipeline. In such cases, one may be interested in displaying the name of the file as well during debugging, which can be a hassle with print().

The above reasons make print(), at least for me, the worst option for debugging.

Thankfully, there is an excellent alternative in Python.

Introducing IceCream 🍦!

IceCream

IceCream is a Python library that makes debugging effortless and readable with minimal code.

Its popular features include printing expressions, variable names, function names, line numbers, filenames, and many more — which we will discuss in this blog.

Installing IceCream

You can install the icecream library using pip.

Import IceCream

The standard convention for using this library is to import the ic module as follows:

Getting Started With IceCream

Using the IceCream library is as simple as the print statement. You need to replace print() with ic(). That’s it.

Notice the difference! ic() prints not only the value but also the name of the variable passed.

IceCream is not just restricted to a variable. Rather, you can use it on functions, classes, etc.

How cool! It prints the name of the method (func), the argument passed (3) and the output (6).

Every expression that goes in the ic() method gets printed along with the value of the expression, as illustrated below.

Icecream prints the expression and its value both (Image by author)

Debugging with IceCream can be applied to the common Python data structures as well. An example of a Python dictionary is shown below.

Inspecting Execution

Many-a-times, programmers use print() to display meaningful (or sometimes random) statements to determine the flow of the program. This is shown below:

IceCream lets you get rid of those bizarre statements too.

Just call ic() and you're done. It will print the file name, line number, and other details (like function name, if any) and the time. Simple.

Using IceCream Project Wide

Next, you might wonder that does one need to import the library in every python file? Of course not!

To make the methods available in all project files, import the install module from icecream in the root file, as shown below:

With install, ic() gets available project-wide.

Adding a Custom Prefix

If you noticed above, the output of the ic() statements begin with “ic|”. That’s the default prefix IceCream provides.

However, if for some reason, you wish to replace that with a custom prefix, you can do that too. This is done by specifying the prefix argument in the ic.configureOutput() method as shown below:

Deleting IceCream Statements After Debugging

Once you have debugged your code, you may want to remove all the unnecessary debugging statements.

As ic() statements are syntactically different from print(), you can search for the pattern “ic(” in your editor and remove the statements, as shown below:

Removing ic() statements from code (Gif by author)

Alternatively, you can use ic.disable() to stop ic() from printing. If you wish to use them again, use ic.enable().

Conclusion

Debugging with print() statements is a messy and inelegant approach. It is confusing to map the output to its corresponding debug statement. Moreover, it requires extra manual formatting to comprehend the output.

As discussed above, the IceCream library in Python is an excellent alternative to this. It makes debugging effortless and readable, with minimal code.

Read more about IceCream here.

Thanks for reading!

🚀 Subscribe to the Daily Dose of Data Science. Here, I share elegant tips and tricks on Data Science, one tip a day. Receive these tips right in your inbox daily.

🧑‍💻 Become a Data Science PRO! Get the FREE Data Science Mastery Toolkit with 450+ Pandas, NumPy, and SQL questions.

✉️ Sign-up to my Email list to never miss another article on data science guides, tricks and tips, Machine Learning, SQL, Python, and more. Medium will deliver my next articles right to your inbox.

I like to explore, experiment, and write about data science concepts and tools. You could connect with me on LinkedIn.

--

--

👉 Get a Free Data Science PDF (550+ pages) with 320+ tips by subscribing to my daily newsletter today: https://bit.ly/DailyDS.