Pretty cool video on the complexity of one of the greatest songs in Sesame Street. It's amazing just how intricate the musicianship is in this!


Sep 17, 2023

The latest Smarter Every Day video is engineering on an entirely different level. The math, software, and other challenges this company face are tremendously complex. It's amazing that people get to do this for a living! I bet we hear a lot more about this technology in the future; this seems like a promising area of development and manufacturing.

Here's another thing that linting taught me recently: Python's str.startswith() method, and str.endswith() as well, takes a tuple as the first parameter! This makes checking for multiple options really simple:

# Verbose way of writing it
if (mystring.startswith('c.') or mystring.startswith('m.') or mystring.startswith('s.')):

# Easier way
if (mystring.startswith(('c.', 'm.', 's.'))):

I didn't realize the language allowed this!

As I mentioned previously, I'm now using Ruff to lint my Python projects. Several linter warnings continually crop up in my code, which I find interesting, so I thought I'd highlight a few of them (there are plenty that I'm leaving out; I apparently write fairly crude code by these linters' standards).

This is a common recurrence in places where I'm setting up a dict for something:

mydict = {
    'posts': some_queryset.all(),
    'today':  # Missing a trailing comma

This pops up on occasion for me, though not terribly often. I apparently easily forget about the not operator.

return False if self.errors else True

# The above is a little more legible if we use:
return not self.errors

I was surprised that this occurred so often in my code. Removing these cases flattens the code somewhat, which is a new practice I'm trying to engrain into my programming habits.

if (is_ajax_request(request)):
    return HttpResponseForbidden('Forbidden')
else:  # This isn't needed
    return redirect(reverse('home'))

# The above looks better as:
if (is_ajax_request(request)):
    return HttpResponseForbidden('Forbidden')

return redirect(reverse('home'))

This warning taught me something I didn't know about f-strings; namely that explicit conversion flags are available. Also that the conversions I was making were mostly not necessary in the first place.

error = f"Part not owned by {str(self.part_owner)}!"

# Better:
error = f"Part not owned by {self.part_owner!s}!."

# Best:
error = f"Part not owned by {self.part_owner}!."

Again, I was surprised by how often I do this. Base types can (and often are) subclassed, so it's better to use isinstance() than type is.

if (type(loader) is list):
    return error_response(loader)

# Better:
if (isinstance(loader, list)):
    return error_response(loader)

Running the linting frameworks has taught me a fair amount about my programming habits, and has also informed me about various aspects of the language. I recommend running linters if you don't already, and I highly recommend Ruff!

Linting With Ruff

Sep 7, 2023

I enjoy using linting frameworks for the code I write, primarily employing flake8 for my Python code, which is about 90% of what I write these days. Recently, however, I saw news on Ruff, a new linting framework written in Rust that is orders of magnitude faster. It's so fast that the entire CPython repository, which contains over 1200 files, can be linted from scratch in only 0.29 seconds. Several testimonial quotes in Ruff's README attest to this blazing speed:

Ruff is so fast that sometimes I add an intentional bug in the code just to confirm it's actually running and checking the code. - Sebastián Ramírez, creator of FastAPI

Just switched my first project to Ruff. Only one downside so far: it's so fast I couldn't believe it was working till I intentionally introduced some errors. - Timothy Crosley, creator of isort

Another benefit on top of its speed is the near-parity it brings with Flake8, which is nice. There are still a number of formatting rules from the pycodestyle package that haven't been implemented, which is an annoyance, but there's an active issue tracking the progress on that front.

To top it all off, Ruff includes rules from dozens of Flake8 plugins, most of which I've never run. Enabling all of them in my projects has been humbling, to say the least, but I'm learning a ton of improved practices from doing so. I don't always agree with some of the rules, and have disabled a number of rule sets that annoy me, but it's been an interesting learning process.

In the coming days I'll be writing about a few of the sloppy practices that this framework has pointed out in my code, so stay tuned.

My wife made these the other night for a dinner with neighbors and they turned out terrific. In fact, they're likely better than the snickerdoodle recipe that I posted several years ago! The cookies in this recipe end up way softer, and are just as flavorful. Highly recommended! Note that this recipe was taken from an external website, which I'm transcribing here for both simplicity and posterity.

Makes 36 cookies in about 20 minutes.


  • 2-3/4 cups all-purpose flour
  • 2 tsp cream of tartar
  • 1 tsp baking soda
  • 1/2 tsp salt
  • 1 cup unsalted butter, just softened
  • 1-1/2 cups sugar
  • 2 eggs
  • 1 tsp vanilla extract


  • 1/3 cup sugar
  • 2 tbsp cinnamon


  1. Preheat oven to 350 degrees F.
  2. In a large bowl, mix together flour, cream of tartar, baking soda, and salt together. Set aside.
  3. In a stand mixer, cream together butter (barely softened) and sugar. Add eggs and vanilla and blend well.
  4. Add dry ingredients to wet ingredients and mix well.
  5. In a small bowl, combine remaining ⅓ cup sugar and 2 tablespoons cinnamon.
  6. Use a small cookie scoop to scoop out dough, roll into a ball and then roll into the cinnamon sugar mixture- twice.
  7. Place 2 inches apart on an ungreased cookie sheet.
  8. Bake for 8 – 10 minutes. Let sit on the cookie sheet for a few additional minutes before removing to a wire rack to cool.

Until recently, I knew next to nothing about Alice Cooper's music. I'd heard School's Out and No More Mister Nice Guy on the radio, but that was the extent of my knowledge. Alice is back in the news with a forthcoming album, so I figured I'd check out some of his music. I'm glad I did! Lots of his albums are particularly good, including Killer (I can't embed the videos here on this site, stupidly, so the link to the album playlist will have to suffice). There are some great tracks on this album: Halo of Flies (my favorite), Under My Wheels, and Dead Babies.

Billion Dollar Babies is an equally as good (if not better) album, as is his first solo effort Welcome to My Nightmare. I recommend checking them all out if you're not familiar.

The Operations Room

Apr 30, 2023

The Operations Room channel on YouTube has been killing it for a while now. Their top-down, animated videos show some of the most important battles and events in history. I've learned a ton about events in World War 2, Vietnam, the Gulf war, and even interesting isolated events. Their latest video, on the battle of Alligator Creek at Guadalcanal, is fascinating and I've linked it below. This is definitely a channel to follow; there's lots of terrific content.

We recently bought a new home and have been doing a number of updates. One thing in dire need of updating are the thermostats, which are original to the house (1992). The existing units were clunky, not very user friendly, and not particularly sensitive to temperature change.

I decided to purchase the ecobee smart thermostat, and was particularly motivated when our energy provider recently offered a deep discount on the units. I picked up a couple of them and updated the upstairs unit earlier today (I'll tackle the downstairs unit another day).

Because my setup didn't have a C-wire (for continuous power), the install process required that I installed a power-extender kit, which comes in the box. This involved adjusting the thermostat wires inside the HVAC unit, which was a little daunting at first. This process, however, turned out to be easier than I initially thought.

The entire install process took about an hour or so do, and I now have a modern, easy to use setup. One of the benefits of these units is that they have optional sensors you can buy to place in other rooms, which help the thermostat better control the temperature across the whole house. I plan on picking up one of these eventually to put in our bonus room, which seems to be hotter than the rest of the house on average.

I'm enjoying the DIY aspect of home ownership these days. I've learned a lot, am gaining new skills, and I'm saving a little on having to hire someone to do the work.

Magnet Sweeper

Apr 11, 2023

We recently had our roof replaced, which resulted in a ton of debris in the yard. One of our primary concerns with this was the number of loose nails and screws, which pose a hazard to both our car tires and our feet. Scanning through Home Depot's website, I found this magnet sweeper, which only set me back $12.

The second photo above shows just how many nails, screws, and other debris I was able to pick up with this thing. Wow! There are a few drawbacks to this tool. First, the handle is a little short for my taste. Second, the magnets could stand to be stronger, but they did a decent job. And third, a wider magnet head would have been nice. But for only $12, I'm willing to sacrifice some of the niceties of other, pricier tools. If you ever find yourself in need of something like this, I recommend this model, despite its shortcomings. I can see this tool being useful in other situations (i.e. when I drop a screw or nut in the garage and it rolls out of reach).

On Keeping Records

Mar 21, 2023

My wife and I are in the process of purchasing a new home. The current owners of the property we're buying have kept meticulous records. They have a spreadsheet detailing:

  • The type of home update
  • When the update was made
  • Who did the service (or where it was purchased from)

This information is surprisingly useful to know, and has helped us make some decisions on what to update and what not to update. It also gives us a good picture of the relative ages of each home system (e.g. hot water heater, HVAC units, etc.).

While discussing the selling of our current home with our realtor, I figured I could provide dates for when some of the similar updates here were done. I assumed that I had emails on these items, but it turns out I don't. Maybe I paid for some of these things via a check? And maybe the receipt they sent was a hard-copy? Regardless, I am unable to pinpoint when our hot water heater was installed, for example (this kind of thing is useful to know when selling a home, it turns out).

It's frustrating to know that I had work done to my home but cannot locate the invoice showing me who did it or when it was done. Had I kept better records, this wouldn't have been a problem. Going forward, I intend to do a better job.

The Future of AI

Feb 13, 2023

Today's Tom Scott video feels very prescient. I too have had the feeling that we are standing on the cusp of something big; though I'm not sure if that something is good or bad. The problem Tom was trying to solve was also interesting (who knew that subtle quirk about GMail's labels?!?).

My text editor of choice when I'm in Linux-land is Vim. One of its most powerful features is the ability to use regular expressions when searching. This capability makes hunting through giant log files so easy. However, I ran into a problem today that I wasn't sure how to work around.

I was looking through a large log file, trying to find the lines that included the text Internal Server Error. Making this difficult, however, were hundreds of such entries that were calling a known failing case. I wanted to weed out these known cases, and with regular expressions, I was able to. The known case I wanted to ignore looked something like the following:

[02/Feb/2023 16:06:14] ERROR [] Internal Server Error: /api/v1/some_bad_endpoint/

This endpoint is the only one in the /api root, so I wanted to ignore /api as a part of my search. The magic is through negative look-ahead assertions, the syntax for which I was unfamiliar (\@! being the key). My search command in Vim ended up being:

/Internal Server Error: \/\(api\)\@!

Using this regular expression helped me jump to every instance of the Internal Server Error text that wasn't a call to the known-failing /api root. So handy!

I learned this morning that The New Yankee Workshop is now posting full episodes of the show to YouTube! The woodworker in me is freaking out just a little bit at this news; there are so many good episodes of this classic show! Below is a small message from Russell Morash, the producer of the show (and the owner of the shop where they shot the show). It's a neat walk down memory lane.

The story in this Essential Craftsman video is truly remarkable; it's well worth its 10 minutes.