Reading into this issue on Django-waffle
I learned that Django uses pickle to store objects in its cache but does not guarantee that these objects
will remain valid between versions, so it raises a RuntimeWarning
when you access potentially stale objects.
The Django docs recommend clearing the cache on upgrade, and this Stackoverflow post discusses ways of doing that.
A pattern I enjoy with Copilot or other AI coding tools is something I'm calling "Language bridging":
Language bridging : Write code to solve a problem in a language you know well, then use an AI to translate the code into the language you want or need to use.
Read Full Post
There's this myth we tell ourselves about "Real developers" and especially "this is why I am not a Real developer". It got me thinking - is there actually a useful definition out there?
Here is my best try:
*A 'Real Developer' is someone who writes code or other instructions for a computer which run successfully and get something useful or delightful done in the real world
Read Full Post
Looking back on 2024 here are some personal highlights:
Early in 2024 I took over maintenance of the very useful Python package pye57 for
reading and writing e57 format pointcloud files. I have been using it at work for several years and was
worried that it was not being maintained, blocking upgrade of our project to Python 3.11.
I had already started working on an alternative library, cleverly titled e57
- essentially I got in touch with
the project maintainer, providing some evidence that I was a real human being not a sham account,
many thanks to David Caron for creating the library and maintaining it for so many years, and for trusting
me to carry it on.
Read Full Post
See the xml portion from the end of an .e57
pointcloud file. This contains information like the bounding box of the
pointcloud, the number of points and how the points and other information are organised in the file.
I wrote it with a bit of help from Claude ai by describing what I wanted and pasting a description of the e57 file format before doing a lot of debugging to get the entire xml section and then integrating it with my blog.
I find the e57 file format a bit wierd - it starts with a header including a file version number and an offset to the XML portion, which comes at the end of the file so you need to read both ends of the file before you can understand the middle bit. So if you download the file you have to wait for it to finish downloading - you can't start to interpret or display the points and other data whilst streaming data.
This tool is written in JavaScript and runs in your browser - no files are uploaded to any server (in fact this blog has no backend server - it is a static web site - it is downloaded and runs entirely in your browser).
My version of YAGNI - "You Ain't Gonna Need It" - is a rule of three: only spend time refactoring your code when you have repeated yourself 3 times. Don't aim for truly DRY code devoid of all repetition.
I'm not saying not to apply SOLID design principles from the start - I definitely try to separate concerns, giving a single responsibility to a class or function and avoid, for instance, a single method handling file reading, data transformation and reporting. This simplicity will make it much easier to refactor the code later.
I am saying to avoid using sophisticated design patterns, architecture or abstractions before you have used of your code enough to know what is likely to change (and require encapsulation) and what will stay constant (creating a useful abstraction).
Read Full Post
I love The Zen of Python - one of the delights of the language is typing import this
in a REPL and discovering this gem:
>>> import this
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
It neatly captures the way in which Guido van Rossum and a group of Pythonistas thought about
the language, constructed and used it, sharing thoughts on user forums in in-person meetings.
Read Full Post
In our team we started with the smallest possible shareable system - a flags namespace in our front-end code. We later adopted an existing open source library in the back end. This got me thinking - what is the smallest possible feature flag system?
Here's a Hello World example...
# greet.py print("Hello, world!")
The greatest accelerator of my team's work last year was adopting feature flags. With flags we ship features faster, more confidently and with less stress. We have fewer merge conflicts despite frequently working together on the same part of the code base.
People often say that in Python you should use exceptions - "Easier to Ask Forgiveness than Permission" (EAFP) over guard clauses - "Look Before You Leap" (LBYL), but the Result design pattern - returning an object which explicitly states whether the operation succeeded is a useful alternative where error handling is required and, as I learned by exploring in more depth, it can be compatible with both approaches.
As my design patterns repo approaches 100⭐
on GitHub I decided to add the Result design pattern to the mix
or Graham plays with GitHub Code Search
Prompted by a post on Mastodon I looked a bit more into which patterns people are using for error handling specifically for attribute lookup: I'm surprised to see twice as many references to hasattr as for "except AttributeError"
and not only for dynamic lookups but also for general attribute search, so a win for LBYL vs EAFP style with Python, despite the latter often being recommended ?