Do Not Use Print For Debugging In Python Anymore
source link: https://towardsdatascience.com/do-not-use-print-for-debugging-in-python-anymore-6767b6f1866d
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Do Not Use Print For Debugging In Python Anymore
A refined “print” function for debugging in Python
What is the most frequently used function in Python? Well, probably in most of the programming languages, it has to be the print()
function. I believe most of the developers like me, would use it to print messages into the console many times during the development.
Of course, there is no alternative that can completely replace the print()
function. However, when we want to output something for debugging purposes, there are definitely better ways of doing so. In this article, I’m going to introduce a very interesting 3rd party library in Python called “Ice Cream”. It could create lots of conveniences for quick and easy debugging.
A Bad Example
Let’s start with a relatively bad example. Suppose we have defined a function and we want to see whether it works as expected.
def square_of(num):
return num*num
This function simply returns the square of the number passed in as an argument. We may want to test it multiple times as follows.
print(square_of(2))
print(square_of(3))
print(square_of(4))
This is OK for now. However, we will have much more lines of code in practice. Also, there could be many print()
functions that print different things into the output area. In this case, sometimes we may be confused about which output is generated by which print()
function.
Therefore, it is a good manner to add some brief description to the content of the print()
function to remind us what it is about.
print('square of 2:', square_of(2))
print('square of 3:', square_of(3))
print('square of 4:', square_of(4))
It is much better now, but it is too tiring to do this every time. Also, when we finish the development, very likely have to remove most of the debugging prints.
Basic Usage — Inspect Variables
Let’s have a look at the Ice Cream library. How it solves the problems that were mentioned above?
First of all, we need to install it from the PyPI repository simply using pip
.
pip install icecream
Then, let’s import the library as follows.
from icecream import ic
Now, we can use it for everything we want to print as debug information.
Call a Function
We can directly use ice cream to print a function just like what we have done using the print()
function previously.
ic(square_of(2))
ic(square_of(3))
ic(square_of(4))
Great! We never specify anything in the ic()
function, but it automatically outputs the function name and argument together with the outcome. So, we don’t have to manually add the “brief description” anymore.
Access a Dictionary
Not only calling a function, but Ice Cream can also output everything verbose that is convenient for debugging purpose, such as accessing a key-value pair of a dictionary.
my_dict = {
'name': 'Chris',
'age': 33
}ic(my_dict['name'])
In this example, I have defined a dictionary and try to access a value in it from its key. The Ice Cream output both the variable name of the dictionary and the key that I was accessing.
Access Attributes of an Object
One more example, let’s define a class and instantiate an object from it.
class Dog():
num_legs = 4
tail = Truedog = Dog()
Now, let’s use Ice Cream to output an attribute of it.
ic(dog.tail)
Debug in If-Condition
The Ice Cream library is not only useful for inspecting a variable, but also in a control statement such as an if-condition. For example, let’s write a simple if-else condition as follows.
input = 'Chris'if input == 'Chris':
ic()
else:
ic()
We just put the Ice Cream function in the if and else blocks, see what happen.
Although the if-else statement does nothing at the moment, the ic()
function still tells us where and when it has been called, as well as the line number.
BTW, I’m using Python Notebooks for this demo. If this is running in a “.py” file, it will also tell us the file name that it was called from.
Let’s consider a more practical usage as follows.
def check_user(username):
if username == 'Chris':
# do something
ic()
else:
# do something else
ic()check_user('Chris')
check_user('Jade')
The function will do something for different user. For debugging purposes, we always want to know which is the current user. Then, the ic()
function will always tell us that.
Insert Into Existing Code
This cool feature of the Ice Cream library needs to be highlighted in my opinion. That is, the ic()
function will not only output the verbose information but also pass the value through so that it can be a wrap of anything. In other words, we can put the ic()
function to anything in our code without affecting it.
Let’s keep using the sqaure_of()
function that we defined in the previous section.
num = 2square_of_num = square_of(ic(num))
In this example, suppose we have a variable num
and we want to calculate its square. Instead of square_of(num)
, I put the ic()
function out of the variable num
. Therefore, the value of the variable num
is printed, and the result assigned to square_of_num
will not be affected.
We can test the result as follows.
if ic(square_of_num) == pow(num, 2):
ic('Correct!')
Therefore, square_of_num
equals to the square of the variable num
. Also, in this if-condition, I also used the ic()
function without affecting the purpose, but the variable square_of_num
is printed for debugging!
Disable Ice Cream
One of the biggest issue when using the print()
function for debugging is that there are too many of them. It is very common that we have them everywhere when we finished the development. Then, it would be a disaster if we want to clean our code to remove them.
If we’re using the Ice Cream library for debugging, what we need to do is simply disable it.
ic.disable()
After that, all the ic()
function will stop output anything. For example, the code below will output nothing.
You may ask that how about the variable square_of_num
? Will it still be passed through if we disabled the Ice Cream function? Don’t worry, the disabling feature will only disable the output, we don’t need to worry about any other features.
if ic(square_of_num) == pow(num, 2):
print('Correct!')
If we change the output back to the print()
function, it still can be output. That means the ic(square_of_num)
still equivalent to square_of_num
.
Of course, if we want to go back to the debug mode, the Ice Cream can be re-enabled.
ic.enable()
Customising Ice Creame Output
The Ice Cream can also be customised for its output. The most commonly used customisation would be changing the prefix. You may have noticed that the default output always has the prefix ic |
. Yes, we can customise it.
For example, we can change it to Debug |
which makes more sense for its debugging purpose.
ic.configureOutput(prefix='Debug | ')
ic('test')
In fact, rather than a static string, the prefix can also be set to a function. For example, let’s define a function that returns the current timestamp in a formatted string.
from datetime import datetimedef now():
return f'[{datetime.now()}] '
Then, we can set that function as the Ice Cream prefix.
ic.configureOutput(prefix=now)
ic('test')
Summary
In this article, I have introduced an awesome 3rd party library for Python called “Ice Cream”. It enhanced the regular print()
function of Python with verbose output. Therefore, it makes debugging very convenient.
The Ice Cream library will never replace the print()
function, because it is designed for debugging purposes. Also, it does not mean to replace the logging system as well. In my opinion, it is in between these two. Check out and try it out!
Life is short, use Python!
Recommend
-
45
PySnooper - Never use print for debugging again PySnooperis a poor man's debugger. You're trying to figure out why your Python code isn't doing what you think it should be doing. You'd love to use a...
-
6
Thank God, We Are Not a Flat Org Anymore Our team was like magic. Every Friday we sat down for an hour to our usual how-we-work ritual, when the six of us discussed how we should do things at wor...
-
4
Trying out this newsletter thing… It’s sort of astonishing to think about how much value I’ve gotten from Twitter over the last few years. At its best, my Twitter feels like spending a leisurely afternoon at a cafe where computing en...
-
3
Node.js console.log and console.error This built-in console module in Node.js lets you write log messages to stdout and stderr using the log and error functions. It might appear simple and te...
-
38
How to do print debugging in SwiftUI 14 Aug 2021 ⋅ 3 min read ⋅ SwiftUI ...
-
4
Tips for debugging with print()Adam Johnson Home | Blog |
-
5
Photo by David Clode on UnsplashPure Print-Style Debugging in Ha...
-
4
A Couple Lines To Improve Print-Based Debugging In Loops 2022-05-30 • Raphael There are a lot of simple ideas that float about in programming. Many that are conceptually simple, yet end up being...
-
3
Hello! We released The Pocket Guide to Debugging back in December, and here’s a final update: the print copies are done printing and they’ve arr...
-
5
JS Party – Episode #281 Is print debugging good enough? YepNope: Jerod & KBall vs Amal & Eric...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK