Farer Resolute II 36mm

Sometimes you buy a watch because it’s just right. Proportions, dimensions, luminosity, legibility, price, movement, style. This one preoccupied me for a couple of months and arrived last week.

Really enjoying wearing it.

Downsides so far – the lumed numerals blur in the dark into blobs, so the initial legibility decreases a bit. I miss having a date available. Since it has unidirectional winding, there’s noticeable rotor spin that you can feel and hear.

Overall strong positive. At 36 by 10.8, it’s super comfortable. I love the design and style. Legibility is excellent as is timekeeping. At 1100 with bracelet (always buy the bracelet!) the value is good for a Swiss made watch this well detailed and finished.

There’s a larger 38mm version, but for me, with the all-dial case, 36 is perfectly sized.

Farer page is here. No relationship, just a happy customer.

The electrical cost of gasoline is 8.6kWh

A friend of mine did an interesting bit of research and data gathering that I’ve not seen elsewhere and I thought I’d share here.

If you read about energy and markets, you might have read about EROEI: Energy return on energy invested. E.g: It might take 20 gallons of oil to extract a 55g barrel of oil.

So what’s the energy cost to refine a gallon of gasoline?

To get an answer, my friend found the government page showing the energy used by “Petroleum Administrative for Defense District 5. Basically, west-coast refineries.”. It’s here. A snapshot graph:

Next, you need to know how much they refined (oil in, gasoline etc out). That’s here. And the refining capacity is here.

If you do the math (to tip my hat to a scientist I admire), the result is 8.6kWh/gallon. To get that number, you

  • take the annual electricity purchased by the refinery (X)
  • Calculate the proportion of gasoline vs total refined output (Y) (19.45 gallons gas per 44.77 gallons refined output)
  • Divide X/Y

That’s more than I would have guessed. Our 2018 Chevrolet Bolt EV holds about 60kWh and can drive around 180 miles, by way of comparison. So the refining energy could power an average EV sedan 34 miles. Which is higher than the average EPA mileage of a comparable ICE sedan.

Food for thought. As my friend put it, “charging an EV will always require less energy than an equivalent gasoline powered vehicle, and would always be cheaper for the end user if not for subsidies to the petroleum industry.”

WordPress and self-hosted sites broken on iOS

If you run your own self-hosted WordPress and would like to, you know, blog now on it, you too may have gotten the maddening error “Unable to read the WordPress site on that URL”

This, though their help page does not tell you, is a filthy lie. Do the following whilst cursing their late-stage-capitalist bastard hearts:

Append “/xmlrpc.php” to the URL. That’s all that it takes.

So example.com becomes example.com/xmlrpc.php

Of course, this is only broken on self-hosted sites. Bastards, like I said.

Whisper and WhisperX for podcast transcription

I just realized that I hadn’t posted this. Several months ago, I read about whisper.cpp and started playing with it. To quote from their docs, whisper.cpp is a

High-performance inference of OpenAI’s Whisper automatic speech recognition (ASR) model:

  • Plain C/C++ implementation without dependencies
  • Apple Silicon first-class citizen – optimized via ARM NEON, Accelerate framework, Metal and Core ML
https://github.com/ggerganov/whisper.cpp

In other words, a fast and free speech transcription app that runs on your laptop. Damn!

In fact, it’s so efficiently written that you can transcribe on your iOS phone. Or browser. Haven’t tried those yet.

Anyway, that gave me an idea: a couple of friends of mine run a podcast called TGN. They’ve been at it for a few years, and have around 250 episodes of an hour each. Could I use whisper.cpp to produce a complete set of episode transcripts? If I did, would that be useful?

(Insert a few months of side project hacking, nights and weekends.)

It works, pretty well. For podcasts, however, you end up with a wall of text because Whisper doesn’t do what’s called ‘speaker diarization,’ that is, identifying one voice or another. It’s on their roadmap, though.

I was sharing the progress on the TGN slack when an employee of the company OctoML DM’d me. They have a WhisperX image that does diarization, and he offered to help me use it for the project.

(More nights and weekends. Me finding bugs for OctoML. Adding a second podcast. Getting help from a couple of friends, including the a-ha mkdocs idea from David.)

Voila! May I present:

The key useful bits include

  • Full text searching
  • Local mirrored copies of the podcast MP3, raw transcript text and (in progress attempts) to mirror the episode web page.
  • Using mkdocs to build static websites that look OK, and can render Markdown into HTML.

Lots of features yet to build but it’s been a really fun side project. Source code is all on GitHub, right now I’m in the prefect branch, trying out a workflow rewrite using Prefect.

Internet manners – download if newer

If you’re a developer, sooner or later you’ll need to poll a website or URL, looking for information. There are good and bad uses of this, (looking at you, Ticketmaster and scalpers) and I want to be good. (This was inspired by reading Rachel’s post about her rate limiter.)

As part of my podcast speech-to-text project I am downloading a chunk of XML from their RSS feeds. These are commercial and can handle lots of traffic, but just the same why not be smart and polite about it? My goal is to have a cron job polling for new episodes, and I don’t want to cost them excess hosting and traffic fees.

The HTTP spec includes a header called Last-Modified, so your first thought might be:

  • Use the HTTP ‘head’ verb to only get metadata
  • Check the Last-Modified header to see if its newer

This will not work. ‘HEAD’ doesn’t include Last-Modified. Instead, you need the ‘ETag’ header! It’s roughly (see that link for details) a file hash, so if the RSS updates the ETag should as well. Simply save the ETag to disk and compare the version returned in the ‘HEAD’ metadata. Fast, polite, simple. Here’s the Python version from the project:

def podcast_updated(podcast: Podcast) -> bool:
    # Based on our saved last-updated time, are there new episodes? If not, don't
    # hammer their server. Internet manners. Method - call HEAD instead of GET
    # Note that HEAD doesn't include a timestamp, but does include the cache ETag, so
    # we simply snapshot the etag to disk and see if it differs.
    filename = podcast.name + '-timestamp.txt'
    try:
        r = requests.head(podcast.rss_url)
        url_etag = r.headers['ETag']
        file_etag = open(filename, 'r').read()

        if file_etag == url_etag:
            log.info(f'No new episodes found in podcast {podcast.name}')
            return False
    except FileNotFoundError:
        log.warning(f'File {filename} not found, creating.')

    open(filename, 'w').write(url_etag)
    return True

It adds a local file per URL, which is a bit messy and I need to rework the code a bit, but it’s working and runs quite fast.

Another idea would be to try the requests-cache module, which does this plus local caching of content. I’ve read their docs but not tried it yet.

P.S. Yes, I also shared this on StackOverflow. 😉

Goddamn WordPress

So I pay for WordPress to host this blog. Money well spent at 48/year. I also run a private blog. The WordPress iOS app as well as their new Jetpack app both refuse to log into the self hosted instance.

Why? I’m guessing fuck you, pay me. The BlogPost app kind of works but I need to work on its image uploading.

Had to rant. Guessing there are lots of others in this predicament.

Wonderful performance of JS Bach

I’m a fan of JS Bach in general and of his pipe organ work in particular. My mom was sometimes a church organist, so I’ve memories of reading while she practiced, though always with synths and not a full organ. I did get to hear the instrument at Cordiner Hall many times while working there, complete with hunchbacking down a five foot tall tunnel underneath the seats while it was played… anyway.

This is an excellent performance, a bit different than my favorite by Marie-Claire Alain, but its well recorded and definitely wonderful. Good headphones recommended, otherwise the pedal tones don’t come through as they should. That final chord resolution, singing through the hall, just goosebump inducing. Enjoy.