
Cloître Saint-Trophime, Arles, France
Cloître Saint-Trophime, Arles, France
View of the river from Pont du Gard, France
Pont Neuf and Square du Vert-Galant, Paris
Boats along the Seine
New growth
Scooter in the rain
I had the “pleasure” of visiting the DMV this week to apply for a driving permit for my oldest kid. By a miraculous sequence of events, we got the permit in a single visit, but it was a close call.
Because the permit will eventually turn into a driver’s license and therefore a REAL ID, the application required two different documents to provide proof of address. There is a long list of valid documents, such as utility bills and property tax bills, and furthermore the DMV recognizes that not everyone living at an address receives such bills:
What if I do not have one of the above residency documents?
You can use a relative’s (parent, child, spouse/domestic partner) residency document if you live at the same address and provide a document (such as a birth or marriage certifcate [sic]) that shows that relationship.
It all seems reasonable enough, but the rules are implemented like a poorly-written computer program.
The question is, can I use my driver’s license (together with a birth certificate) as proof of my teen’s residency? In theory, this should count as definitive proof of address, since they required me to show two address documents in order to receive the license in the first place. At the very least, it should count as one of the two factors, at least as valid as a SoCalGas bill that anyone with a basic PDF editor could easily doctor.
In practice, as you have probably guessed, it counts as nothing. Why? Because the main list of documents is written assuming that they are in the name of the applicant, and this “relative’s residency document” special case is tacked on at the end. And of course, it would be silly to say that you could use your current REAL ID as proof of address to get a REAL ID, so thus you cannot use a relative’s REAL ID as proof of address to get your REAL ID.
Being a paranoid person, I brought two documents in addition to my driver’s license, but even that was almost not enough. See, my address can be written as either 221B Baker St or 221 Baker St #B. The two bills that I brought didn’t match, which (1) was apparently a problem and (2) my driver’s license wasn’t going to get me out of it. The only thing that saved me (this is the miraculous part) was that one of the two bills had the address written both ways.
(For completeness, two other miracles. One, that my kid passed the ridiculous written exam on the first try. A test that did have a question about NEVs without explaining the acronym, and is known for questions like “In which of these locations is it illegal to park? (a) blocking an unmarked crosswalk (b) in a bicycle lane or (c) within three feet of a driveway.” The answer is (a). Nobody knows why. The second miracle is that my teen even got to take the test in the first place, because the DMV shut down the testing center at 4:30 on the dot, sending away everyone who was in line at the time. Credit for this miracle goes to the employee who processed our application, because she shut down her station and went over to the photo station to clear out the queue, getting us through and into the testing center with less than a minute to spare. At the time, we had no idea that we were up against a clock, but I’m pretty sure that she knew and intervened.)
Anyway, now it is time for 50 hours of supervised (by me) driving practice. Wish us luck!
I have a 5-year-old Brother Scanner (the ADS-1700W) that serves me pretty well. It is small enough to keep on my desk, fast, and has a Wi-Fi connection. But getting scans from the scanner to the computer is sometimes bothersome. My primary way of using it is to scan to a network folder on my home server, which is great for archiving things, but not so great for family members or when I need something right away.
My preferred way to get a quick scan is by email. You immediately have it on whatever device you are using, and you have it saved for later if you need it. The Brother Scanner has a scan-to-email function, but it is buggy. Specifically, it sends slightly malformed emails that Fastmail accepts but Gmail returns to sender.
But since network scanning is rock solid, last year I wrote a program to watch a set of folders and send by email whatever files it finds. I was on a bit of a Go kick at the time, and I think Go works pretty well for the task.
Here is the relatively short program that I wrote. It is meant to be running as a daemon, and as long as it is running, it will email you all the files that it finds. Since the interesting parts are at the end and I don’t think anyone will read that far, I’ll show you the program in reverse order, starting with the main
function.
|
|
We start up, print a nice message and make a channel, which is a Go structure that allows us to pass data, in this case integers, between different threads of the program. We call it changes
because it will notify us every time there has been a filesystem change.
The go
keyword on line 99 starts waitForChange
on a separate thread, which is a good thing for us, because you will later see that it runs an infinite loop. We pass it the channel so that it can notify us when it sees a change.
On line 101 we get a Ticker
channel, which will receive a signal every five minutes. Since I don’t completely trust that I will be notified every time a file changes, every once in a while we want to look through the directories to see if we find anything.
Starting at line 102, we have an infinite loop here in the main thread. This starts by mailing out any files that are waiting. Then we get to the select
statement, which pauses and listens to both the changes
channel, and the ticks
channel. The somewhat strange arrow syntax means that we are attempting to read values from the channel. If we wanted, we could assign the values we read to a variable and do something with them, but we don’t care what is on the channels. As soon as another thread writes to one of these channels (whichever channel comes first), we write the corresponding log statement and then continue back to the top of the for
loop, which mails out any files we find, and then goes back to waiting for action on the channels.
By having the two channels, we have programmed the logic to walk the filesystem every time we see a change and every 5 minutes, but, crucially, never more than once at a time. In reality, the change watcher is very reliable, and the email generally arrives seconds after the paper comes out of the scanner.
|
|
Here is the waitForChange
function, which just calls inotifywait
. This in turn runs until someone writes a file and then exits. At this point, our function writes 0
into the channel, which kicks the main thread into action. Meanwhile this thread calls inotifywait
again, to begin waiting for the next change.
|
|
This sendFile
function is called on every file in the directory tree. This is where Go gets annoyingly verbose. So much error handling! But fairly straightforward. As we walk the tree, we skip directories, send out emails if we have a file, and then delete the file after we send it.
|
|
This fileIsOpen
function wasn’t there at first, but my early tries sent out files that were still being uploaded. Live and learn.
|
|
It is relatively simple to send an email using this third-party gomail
package. And it isn’t malformed like the scanner’s attempts to send email!
|
|
This is a relatively simple function that decides who to email to based on the folder that the file is in. This is the abbreviated version; my older kids also have emails configured here.
|
|
Finally, the most boring part of all, the import section.
I bought a new computer. The Beelink U59 Mini PC 11th Gen 4-Cores N5105 cost me $120 from Amazon. It has a somewhat recent Intel Processor, 8GB RAM and a 500 GB SSD. It came with Windows installed, but I erased it and installed Debian with no GUI. It came with instructions to configure autoboot on power failure so I can hide it away in a closet.
This fills a gap I’ve had for some time. My house has been laptop-only for several years now, which leaves me nowhere to run always-on automation things. I have a Synology that I use for storage, but it is very low powered and somewhat hard to configure. My blog is served from a Linode virtual server, which can also fill this gap, but it is also resource-limited, less secure, and far from most of my data.
It has been fun to play with. I migrated some things from Linode to my home server and downsized the Linode. I set up a reverse proxy for my printer and scanner so that I can access the admin pages from outside of my house. I set up a Gitea server for some of my personal things. We will see what other useful purposes it can serve.
On Sunday, I was reading a page on Wikipedia, when this quote caught my attention:
The Gregorian leap cycle, which has 97 leap days spread across 400 years, contains a whole number of weeks (20871).
This is somewhat surprising to me, since I assume that this was by accident and not by design, which means there was only a 1-in-7 chance of it happening.
One result of this is that the calendar for 2000 is the same as the calendar for 2400, which makes a perpetual calendar such as this one quite a bit easier to specify.
Another consequence is that not every calendar is equally likely, which I captured in this silly Mastodon post:
Did you know that October 8 is 3.5% less likely to fall on a Sunday than a Saturday? Enjoy your rare day!
I have few followers, but I was pretty sure my old internet pal Dr. Drang would take the bait (he did).
If I were more patient, I could have waited until next February 29, which falls on a Thursday. Since leap days are more rare than non-leap days, the disparity is greater, and my 3.5% could have been 14%. Wednesday is the more common day for February 29, which again reminds us that we are currently on one of the less common paths through the perpetual calendar.
But calendars are fun to think about, so I didn’t stop there.
A year is about 365.24219 days long. The Julian calendar has a leap year every 4 years, for an average year length of 365.25 days. The error, of course, adds up relatively quickly, as we eventually noticed.
The Gregorian calendar skips leap years on years divisible by 100, unless they are also divisible by 400, leaving the 97 leap years per 400 years quoted above. This makes a year on average 365 + 97/400 = 365.2425 days long, which is closer! It takes 3,225 years before you drift a day, which I guess is good enough?
At this point, I stumbled upon the Revised Julian calendar, which skips leap years on years divisible by 100, unless they are also either 200 or 600 mod 900. This makes a year 365 + 218/900 = 365.24222 days long, which is even better. Now it takes over 30,000 years before you drift a day. The rule is much more confusing, though, although it has the benefit (by design) that it matches the Gregorian calendar exactly for the years 1600-2799. This lets you claim you are following a more accurate calendar without really making a fuss. Also, 900 years of the Revised Julian calendar is not a whole number of weeks, so the Revised Julian perpetual calendar would actually have a 6,300-year cycle.
Finally, I spent some time thinking about what I would have done to handle the leap year problem if I ran the world. The answer is so obvious that it makes you doubt the wisdom of our ancestors. The Julian calendar drifts by 1 day every 128 years. We could have had a calendar (could I call it the Griggorian?) that had leap years every year divisible by 4 except those also divisible by 128. This gets you a year with an average length of 365 + 31/128 = 365.2421875 days, which would mean one day of drift every 400,000 years.
I admit that computing divisibility by 128 is harder (for a human) than 400, but otherwise the rule is clearly simpler. The other downside is that 128 years of this calendar is not a whole number of weeks, which means that the perpetual calendar would have a 896-year cycle. But as long as I’m in charge, we might as well solve that by starting every year on a Sunday.
Balcony on a foggy morning
The Bloc, DTLA
Sihlberg Castle, Zurich
Leg