This article is also available on Medium.
When you’re programming, you’ll have bugs. It’s not because you’re a bad developer, or because you don’t know enough to code; it’s just a natural step for any creative process – there will be hiccups along the way. Actually, from my experience, programming is an endless chain of riddles, each one being a variation on the theme of: “how do I fix this new bug I just introduced?”.
Now, tackling these issues is by no means an easy task, and there are several ways to do it. The high-level developers dive into debuggers (like the famous
gdb [Gnu DeBugger] for C, or its Python equivalent
pdb) or prepare a series of unit tests that help with delimiting the perimeter of the search for this specific problem. Those are powerful and production-required tools.
On the other hand, let’s be honest: how many of us really use those in their everyday coding life? Debuggers are extremely interesting tools but you need to remember a new set of commands and shortcuts… putting the right prints in the right place can just as easily show you what paths your code takes while it’s executing. This is a painless way of making your code talk and tell you about its life. But! It needs to be done right, so you’re not flood in a blob of unreadable data.
And if you improve the look and feel of your prints, it can even be useful for the end user of your application! Think of all those installers like CMake, NPM or Yarn that just fill your shell with pretty icons and shiny colors whenever you add a package somewhere…
We’re not living in the stone age anymore – our terminals can do pretty amazing things with limited overhead: so here’s a few examples of catchy features to improve your Python console prints!
Printing in color with ANSI color codes
Ever wondered how those tools are able to put red crosses and green checks everywhere? How they’re able to show info logs in blue but warnings on yellow background?
ANSI escape codes are specific sequence of characters that are somewhat cross-platforms and can be embedded in your strings to modify their appearance. Instead of being simply printed to the console, those sequences are interpreted by the shell to change the font or the background color, change the font style, move the cursor around in the terminal, etc.
I’m going to focus on the colors ANSI escape codes in this tutorial. Here’s a quick example of how to use those color codes to print your message in the console with some color! I just define a very simple class (that I use like a C-style enum) and then call the various colors in my print statement:
As you can see, you surround your string with two sequences of characters that have a strange format – some backslash, some brackets, some semicolons… But in the end, all of this is interpreted by the terminal and sets a variable in the shell so it outputs the text in a given color. Also, note that it’s important to reset the color at the end of the print, or else you’re going to keep this color in your shell even after you’ve finished executing the line…
And as I mentioned before, ANSI color codes can even change the background color or the style of the font!
To combine two or more transformations, simply print the escape codes one after the other (you only need one reset, though). And for a more detailed list of possible ANSI color codes written in Python format, you can check out this Github snippet.
So, are you ready to give some life to your terminal? 😉
Making nice progress bars with the
Progress bars are a very user-friendly way of showing the evolution of some in-progress task. It can be related to a fundamental UI/UX rule: you should always give feedback to your users so they know when something is happening. This is particularly crucial when the user just performed an action in your application – you have to tell her that the action has been taken into account and that there is an on-going process so she don’t retry it again and again. In some cases, it’s even “reassuring” for users to see the action takes time, because it taking longer gives it more importance.
Of course, Python can print progress bars “natively”, just by adding characters to the standard output stream and using the carriage return (
\r character). However, the
tqdm module is a really sweet step-up. As you can see in this small demo I made, you simply wrap up an iterable (for example a basic range, or a list) with the
tqdm method and it will automatically show:
- a line of blocks that slowly fills up
- the current iteration and the total number of iterations, if known
- the time already spent in this enumeration and a prediction of the remaining time
- the enumeration “speed”, i.e. the time spent on each iteration
You can use the
bar_format option to specify what you want to show, choose the
color you prefer or even use direct integrations with top-notch modules like Keras, Dask or Pandas. The big advantage of this lib is that is has a very small overhead (according to the authors), meaning that it won’t slow down your actual computation just to display it more prettily 🙂
Adding pretty icons 🚀
These past few years, it’s become more and more of a norm to put icons everywhere. Icons are small but (if designed properly) they convey a strong and clear meaning. It’s important to remember that this meaning is much more implicit than with text – it’s more of a subtle contract between you and the user that you speak this same language and that, for you both, a gear is going to mean “settings”, a little circle on a triangle is going to mean “user”, etc. And just like there are dictionaries to give you the definition of words, there are now online encyclopedias to teach you the meaning of emojis and icons.
With this over-representation of icons and emojis in apps, mobile UIs, newsletters or text messages, this new language has gradually entered the mainstream of popular culture and is even being used for ad campaigns or as the central theme of movies. There are even some articles to help you choose the best emoji for your next ad.
All this is to say: icons are here, now. There’s no point denying it. Rather, let’s add some to our prints just like Yarn’s installer (see the video at the beginning of this article) 🛠
The most “native” way to put icons in your Python prints is to use their unicode value. Unicode is the standard that has extended and essentially replaced ASCII in most modern applications and that defined the whole repertoire of available characters on computers. It contains way more possibilities than ASCII, and in particular it allows people to write all alphabets currently in existence (latin, cyrillic, arabic, etc.) and, since 2010, emoticons!
To add icons to your prints, you’ll simply need to find the unicode matching the icon you want. You can enter the unicode directly, or you can copy an icon from somewhere:
Note: as explained in this article, you can also use the CLDR short name of the icons or the
Misc tips & tricks
- In Python 3, there was a breaking change with
print()function. For most of us, it only meant that you were now forced to put parenthesis around the things you were printing. But in truth, it also allows you to pass in additional keyword arguments, among which the
endargument. This lets you define what character will be outputted at the end of your print: by default, it’s a new line, but you can choose an empty string or a space if you want all your results to be outputted on the same line, for example.
- You can very easily have an auto-indentation of your recursion levels in your prints by adding a
indentvariable in your calls and prefixing your outputs with this number of spaces or tabs. Remember that strings can be multiplied by integers if you want to repeat them a number of times:
- I really encourage you to check out this cheatsheet on Python string formatting: from left/right-align to specific length padding and variables injection, this page sums up all you can do with the old ‘%-style formatting’ or the new
format()method (and, starting from Python 3.6+, the f-strings)
What about you? Do you have some Python printing tricks to share? 🙂