Avid readers of our main page certainly heard of our terms “Slack Week” and/or “Slack Friday”, a day where we dedicate time to invest in our creativity and work on side projects. This post details one of these adventures and in the process shows you a neat, lightweight Python GUI library called Remi.
Starting point
One of my Slack projects entailed the migration to Remi of the UI library of my over six years old Bachelor project written in Python. One might wonder: Why would you even do that? The answer is simple: Said Bachelor project helps tormented algorithm students understand said algorithms better. However, the program has one big downside: AlgoVisualizer was created during a time when Python 2 was still very popular. The main issue was that it used Gtk3 for the visualization under the hood, which required native code for the host operating system. In fact, AlgoVisualizer was not even running on my M1 Mac anymore… Time for a change! During this process, I also changed the name to a shorter one: Al-Vi.
What is Al-Vi?
As the original name (i.e., AlgoVisualizer) suggests, Al-Vi animates the execution of an algorithm written in Python. The execution model is similar to a symbolic step-by-step debugger and with the help of annotations (by supplying an annotation file or directly above/beside the line in question as a comment) Alvi’s users can control which variables, loops, arrays, array indices or dicts to visualize and how to display the visual cues.
Al-Vi is split into three parts: Entry-point visualizer.py
that handles two subprocesses stepper.py
(logic for stepping through code) and remi_visualizer.py
(visualization with the help of the library Remi).
Here an example execution of the insertion sort algorithm:
Problems encountered
When working on multiple years old code there is one commodity that saves you a lot of time (and nerves): documentation. Never make the mistake of thinking you are wasting time by writing your docs! One good starter is how to execute the program. My past self didn’t completely fail me here, I indeed wrote a guide on how to start the execution and install dependencies. I also remember refactoring the visualization component (previously called gtk_visualizer.py
) of Al-Vi which ended up being the most readable one (visualizer.py
doesn’t count since it has only 53 lines).
What was I missing? Well, documenting the code itself, how to create annotations (e.g., for specifying which variable and elements you want to display), and… some questionable naming choices, for example the tiny, little fact that when I used a variable called current_line
I was instead referring to the next line that was about to be executed. Before starting this Slack project I made a time estimate of how long it would take me (including this blog post), but I underestimated how long I needed to learn to use the program again. The fact that it wouldn’t run anymore on my CPU didn’t help but made the migration more urgent.
Then there were other issues such as choosing a new visualization library, testing different libraries, and learning the new library in more detail to be able to perform the migration. Ideally, I would find a library that didn’t require native code (e.g., written in C). Apart from having a less cumbersome installation, the Python version of these libraries usually also had a very restricted “Read the docs” documentation where I often found myself looking into the underlying C code to understand what’s possible and how to use them.
Writing this blog post itself also involved some learning and problems (although no Python this time)! I dove into Ruby, why you shouldn’t touch the one installed on a Mac (no, sudo
is not the way) and to use either chruby
(my choice, simply because I discovered it earlier) and rubyenv
. Furthermore, I also learned why the Visual Studio Code terminal is evil (some strange caching happens which you don’t want if you need an up-to-date PATH
variable) and also learned how to create a blog in Jekyll with tag search.
The vscode shell terminal issue was indeed particular: My which ruby
command and gem install
would use different versions of Ruby until I decided to use a real shell terminal (that didn’t cache my stuff and never updated it again, even after being closed).
M1 Macs being “well” supported as they are, I of course also run into issues with the eventmachine
dependency where you had to fix some ldflags
.
Remi
Let’s talk more about the chosen one: Remi (ReMote Interface). Remi was my winner for the visualization because it didn’t involve installing native code and the GUI opened in your local (friendly) web browser, making the app useable for most devices and installation not a hassle. I had a glimpse of the example projects to get an idea of how to get started. At first, I wasn’t convinced, the UI looked basic, the docs even more (yeah, back to “Read the docs”) and I wouldn’t be able to customize this friend how I wanted (i.e., similar look and feel to the old version of Al-Vi).
…Until I learned how to add/remove CSS classes and write your own custom CSS file to create your own custom styles! For some reason, you need to create a res
directory with the Remi CSS in it that you have to grab from the repo. The Remi documentation forgot to mention that you need to grab Remi’s fonts and other resources too if you decide to use your own res
directory since Remi doesn’t give you the possibility to extend, but only to override your resources dir.
Although Remi gives you a lot of power with control over the whole CSS, there is a limitation: Remi uses some witchcraft for responsiveness, so adding margins/padding on the outside containers led to enlargening the page which wasn’t the same behavior you would get on a normal HTML page. That aside, having a responsive app was a nice plus!
One other issue was the debugging experience at the beginning. The errors were not telling me why stuff didn’t work as expected (spoiler: I had a lot of initializations done in __init__
in my GTK version, however, Remi calls __init__
multiple times).
After that was fixed, the migration worked out swiftly. I was able to structure the visualization components way cleaner than with GTK since all the components were also HTML elements. Back then, my arrays were limited to one inside visual cue and one outside visual cue, but with Remi, I could just add another container in a container with its border however much I liked if my array needed more than 2 indices.
Also, to give Al-Vi the same look and feel as back then, I could even replicate the same visuals:
I’m confident that Remi is the way to go for a modern GUI written in Python. Flexx might be Remi’s competitor and is more powerful, but also more complicated to use. If you need a large-scale project, I recommend Flexx, otherwise Remi.