One of the things I've learned from the book I've mentioned in the previous post is that the different types of brackets have different names in British and American English. I've used these names interchangeably until now, so I'll start paying more attention.
While looking again at some code I wrote quite some time ago to animate a graph with OpenGL in PyQtGraph, I learned that some OpenGL libraries (including PyQtGraph) still use the Fixed Function Pipeline. Apparently, VisPy is a good replacement as it is based on the more modern shaders instead.
I haven't looked at any other Python OpenGL packages yet, but I might give VisPy a try.
Today I discovered that it's possible to use cubic Bézier curves to specify the speed curve of an animation. I was not entirely satisfied with the result I was getting with the various ease functions and I was looking for something more flexible; that's when I discovered cubic-bezier.
This is an example of how to use this type of curve with animation:
Although I am not new to Bézier curves, I found the tool on https://cubic-bezier.com to be pretty useful as it's very intuitive and CSS-specific. It has a nice “Preview & compare” feature to compare the configured curve with any of the other available animation functions.
I am more and more impressed with the amount of features that modern CSS has to offer.
While I was looking for a cool font to use, I have come across Datalegreya. I really like its original look, and the idea of using ligatures and contextual alternates to add another layer to characters is really intriguing.
Datalegreya is based on Alegreya Sans SC, a beautiful sans-serif small caps font. The interesting twist is the use of character combinations such as d|2a|1t|3a|2 to overlay a line chart (or a variation of one) onto standard characters. You can try this on Font Library itself.
The basic format is as follows:
Type the character you want to style, for example d.
Add a combination of | (pipe) and a number between 0 and 3 to determine the height of the line after it crosses the character (by default it starts with 0 before the first character).
Continue until the end of the text.
There are other features including the x-axis and y-axis legend, a min/max value indicator, and neutral spaces, all described in the README file included with the fonts.
If you plan to use this font as a Web font, be careful as the OTF files are quite large; anyway, when converted to the WOFF2 format, their size reduces significantly. I am not sure this is a good use of the font, anyway, since the text itself is hardly readable if the font is not correctly loaded for any reason; nevertheless, I find it undoubtedly cool.
I have just learned that f-strings have become much more flexible in Python 3.12.
Before Python 3.12, the following snippet would fail with a SyntaxError:
d = {"key": 42}
print(f"{d["key"]}")
File "<stdin>", line 1
print(f"{d["key"]}")
^^^
SyntaxError: f-string: unmatched '['
Starting from Python 3.12, it just works. This is quite neat.
The Python launcher for Windows
Since I write code for more than 90% of my time on Linux or on a Unix-based OS, it has only come to my attention today that there is a Python launcher in Windows called py.
What is interesting about it is that you can use it to launch different (installed) versions of Python with just a version parameter. In fact, to try out the code above, I've run this command to launch Python 3.12:
A quick thing I have learned today, which I thought was more difficult and it would take more time to get right than it actually does.
Do you know that effect when you click on a link to a section in a page (say from the nav) and the page smoothly scrolls until said section? Well, it is just a CSS property called... scroll-behavior with value... smooth. Duh.
Example:
html {
scroll-behavior: smooth;
}
There are many other scroll-related properties related to snap points and margins, but this one alone goes a long way already.
A couple days ago, I was looking at the WriteFreely logs to find out why a follower was not being counted in the Stats page. While investigating the WriteFreely API later on, I was somewhat surprised that such information was not being exposed.
It turns out that the next version of WriteFreely will have both an endpoint and a detailed page to view the subscribers (I've just looked at the related PR). In the meantime, I decided to take a look at the database.
The following SQL query shows the public ID and URL of the followers (assuming the database is the one WriteFreely uses):
SELECT actor_id, url FROM remoteusers;
I've also found another interesting table that contains the users' public keys:
SELECT id, public_key FROM remoteuserkeys;
This of course got my interested in some more technical details of the ActivityPub format. I want to experiment a little with my own profile, but at the moment it is still unavailable so I'll hold off until I restore it.
Today, while messing around with WriteFreely configuration and logs, I have become aware of the API endpoints. I did know about the API before, but I never set to actually look at what is possible to do.
The most useful open endpoint is probably /api/collections. Every user on a WriteFreely instance has a collection (of posts) associated with its username; in my case, this is /api/collections/nick. Under this path, the /api/collections/nick/posts endpoint retrieves some meta information and the 10 latest posts (if the blog uses the “Blog” display format):
A tool like jq can be useful for a quick inspection from the command line. For example, you can retrieve the title of the blog and the total number of posts with the following command:
Since the page size is set to 10 (and apparently it cannot be changed), you can calculate the number of pages and then paginate the result using the page parameter:
While reading the docs on Voilà, I've come across Voici, then JupyterLite, and finally Pyodide.
Each projects has its own merits:
Voici aims to make it easy to build a static Web application from a Jupyter notebook, meaning that a dashboard can be built and deployed without a running Python environment.
JupyterLite is a Web-native version of JupyterLab, meaning that it is designed to run entirely in the browser without a Python environment.
Pyodide is a Python distribution based on WebAssembly, meaning it is also designed to run entirely in the browser as a Python environment; in fact, it provides a base for a browser-based kernel that JupyterLite uses.
I've tried Voici right after trying out Voilà, but I couldn't manage to make it run because of bugs I didn't have time to investigate; I'll try again later on. I haven't tried JupyterLite as such yet, but I did try Pyodide and, at a first sight, it really looks powerful. With Pyodide you can run Python code and use external packages in a Web page: how cool is that?
I was thinking of something like Pyodide when I first read about a WebGL port of Panda3D based on Emscripten (a compiler that supports compiling a host of languages into WebAssembly, which Pyodide actually uses), and then I found it by coincidence serendipity! Full example of integration with JavaScript coming soon.
While looking at the latest additions to the Jupyter project, I've come across marimo.
marimo is a different kind of Python notebook, not based on any existing Jupyter components but rebuilt from scratch. Its main strengths are the built-in reactivity of the widgets (which you need to link and coordinate explicitly in Jupyter Widgets with functions like link and observe) and the ease of turning a notebook into a standalone Web application (the objective of projects such as Voilà).
I have installed it and tried the tutorial, which by the way is a nice developer experience: just pip install marimo and then marimo tutorial intro. The interface looks modern and sleek, and the widgets do update at a variable change without any extra code, which is neat when there are many or when several widgets are interconnected. I haven't tried the conversion to a Web app yet, but it is also meant to be easy via the command line – just a marimo run away.
I am not sure I will replace my use of Jupyter with marimo soon, but I'll definitely keep an eye on its development, and will keep experimenting with it.