Saturday 23 November 2019 — This is five years old. Be careful.
Like any large suite of applications, Open edX software (my day job) depends on a number of underpinnings: Django, Python, Ubuntu, MySQL, and so on. We want to stay up-to-date on those dependencies, or at least ensure we are using supported versions of each.
To help with that, I wanted to make a chart of the support windows for different versions of each dependency. I figured the simplest way to draw a chart like that was to make a spreadsheet. Google Sheets is enough for something like this, and makes it easy to share the result with others who need to refer to it.
To create the spreadsheet programmatically, I used the JavaScript scripting support. My program went through a few other iterations before landing on this technique, so it’s in kind of a strange form now: it’s a Python program that writes JavaScript, which you then paste into a spreadsheet and run.
It makes a nice result, the Support Windows spreadsheet:
The tree-named things at the top of the chart are the Open edX releases. Mostly the chart is used to reason about when we need to upgrade the dependencies in order for Open edX releases to stay on supported versions. The bolder rectangles are the currently used versions.
The program is here: barcalendar.py. It’s all in one file, though at least the code is organized from general to specific: first color utilities, then a generic BaseCalendar class, then a GsheetCalendar class, then the code specific to our software to draw the chart.
When I thought about writing this blog post, I wanted to clean up the program first. Split it into multiple files, refactor the version logic to make some utilities, and so on. It was easy to imagine making the code more reusable, more of a library. But I resisted letting the perfect be the enemy of the good. This program is useful to us, it might be useful to others. Why not share it now?
The hack of writing JavaScript code to be pasted into a spreadsheet feels slightly embarrassing: shouldn’t I at least be able to use the Gsheet API from Python to do the work?
But using the Gsheet API would mean struggling with authentication, which always seems to be difficult, and I can neatly sidestep by copying and pasting JavaScript. Not to mention, refactoring is easier this way because I can save the JavaScript output and check that the refactored code didn’t change it.
So in some ways, this is a low-tech implementation of the functional programming idea that you should separate I/O from computation. My barcalendar.py does the computation, generating a JavaScript “display list”. Then Google Sheets does the “I/O” when I run the JavaScript in the spreadsheet. Nice: I’m not an authentication-avoiding chump, I’m an insightful functional programmer!
This kind of separation is sometimes called “clean architecture.” Brandon Rhodes has a detailed talk about Clean Architecture in Python.
So enjoy barcalendar.py despite its flaws (or because of its genius). It’s working well for us. If you improve it or use it, let me know.
Comments
Add a comment: