You are on page 1of 7

Stop Using Print to Debug in Python.

Use
Icecream Instead
Are you Using Print or Log to Debug your Code? Use Icecream instead.

Khuyen Tran

Photo by Kenta Kikuchi on Unsplash

Motivation
If you are using print to debug your code, you might find it confusing to look at many
lines of output on your terminal and then try to figure out which code each output
belongs to.

For example, running the script below

1 num1 = 30
2 num2 = 40
3
4 print(num1)
5 print(num2)

icecream_example.py hosted with ❤ by GitHub view raw


will give you

30
40

Which one of these outputs is num1 ? Which one of these outputs is num2 ? Two outputs
might not be so bad to figure out, but what if there are more than 5 different outputs? To
try to find the source code that is responsible for the output can be time-consuming.

You might try to add text to the print statement to make it easier to figure out:

1 num1 = 30
2 num2 = 40
3
4 print('num1', num1)
5 print('num2', num2)

icecream_example.py hosted with ❤ by GitHub view raw

num1 30
num2 40

The output is easier to read, but again, it is time-consuming to write out the text. Is there
a way to print the code that is responsible for the output without additional text like
below?

1 num1 = 30
2 num2 = 40
3
4 ic(num1)
5 ic(num2)

icecream_example.py hosted with ❤ by GitHub view raw

ic| num1: 30
ic| num2: 40

That is when icecream comes in handy.


What is icecream?
Icecream is a Python library that makes print debugging more readable with minimal
code.

To install icecream, use

$ pip install icecream

Let’s try it out by print the output of a Python function.

1 from icecream import ic


2
3 def plus_five(num):
4 return num + 5
5
6 ic(plus_five(4))
7 ic(plus_five(5))

icecream_example.py hosted with ❤ by GitHub view raw

By using ic , we do not only see the output but also see the function and its arguments!
How convenient! The color in your terminal will also be as colorful as the outputs shown
above.
Inspect Execution
To locate where the code was executed, you might do something like what is shown
below to find which statement was executed

1 def hello(user:bool):
2 if user:
3 print("I'm user")
4 else:
5 print("I'm not user")
6
7 hello(user=True)

icecream_example.py hosted with ❤ by GitHub view raw

I'm user

Icecream makes it easier for you to do something like the above by simply running ic()

without additional text

1 from icecream import ic


2
3 def hello(user:bool):
4 if user:
5 ic()
6 else:
7 ic()
8
9 hello(user=True)

icecream_example.py hosted with ❤ by GitHub view raw


Now you know that the code at line 5, which is in function hello , was executed while
the code at line 7 was not.

Custom Prefix
If you would like to insert a custom prefix such as the time the code was executed to
your print statement, icecream also allows you to do so.

1 from datetime import datetime


2 from icecream import ic
3 import time
4 from datetime import datetime
5
6 def time_format():
7 return f'{datetime.now()}|> '
8
9 ic.configureOutput(prefix=time_format)
10
11 for _ in range(3):
12 time.sleep(1)
13 ic('Hello')

icecream_example.py hosted with ❤ by GitHub view raw

Now the time that the code is executed is automatically shown in the output! How cool
is that?

Can I get more context?


Besides knowing the code that is responsible for the output, you might also want to
know which line and file the code was executed from. To know the context of the code,
add includeContext=True to ic.configureOutput()

1 from icecream import ic


2
3 def plus_five(num):
4 return num + 5
5
6 ic.configureOutput(includeContext=True)
7 ic(plus_five(4))
8 ic(plus_five(5))

icecream_example.py hosted with ❤ by GitHub view raw

Now you know that the first output was executed by the function plus_five from the
file icecream_example.py at line 7.

Delete All Icecream after Finish Debugging


You can use icecream solely for debugging while using print for other purposes such as
pretty printing

1 from icecream import ic


2
3 def plus_five(num):
4 return num + 5
5
6 ic(plus_five(4))
7 ic(plus_five(5))
8
9 for i in range(10):
10 print(f'****** Training model {i} ******')

icecream_example.py hosted with ❤ by GitHub view raw


Since you can distinguish between debugging print and pretty print, it is much easier for
you to search and delete all the ic statements after debugging.

After deleting all debugging prints, your code is clean!

Conclusion
Congratulations! You have just learned how to make print debugging more readable
using icecream. Icecream has been a great debugging tool for me, and I hope you will
find it useful as well.

You might also like