There was a nice article at the Washington Post earlier this month on the joys of YouTube's "cab-ride" train videos. They mentioned one of my favorite YouTube channels, lorirocks777, which posts videos from Switzerland and surrounding countries. Videos like this make great "background" viewing while doing other tasks (like, for me, working).

Here's the recipe for auto-authenticating in SSH with a public-private key pair. I'm recording this here because I can never remember exactly how to do this (I do it so infrequently).

Assumption: You have already created a public/private key pair to use. In Windows, this is typically done with puttygen or kittygen (or something similar).

# On the server
cd ~
mkdir .ssh
chmod 700 .ssh

# Here's the magic
ssh-keygen -i -f mykey.pub >> ~/.ssh/authorized_keys
chmod 600 authorized_keys

Once the server-side stuff is done, add the private key to the connection setup in the Kitty/Putty session configuration.

Is it just me, or has the pin density on Google Maps been upped considerably? Take a look at the following image, centered on the I-540 / I-40 interchange here in Raleigh:

Google Maps pin density example

There must be close to 50 or more pins in this (fairly zoomed out) view. The vast majority of these pins are places I've either never visited or don't care about. Maybe this is a way that places can "advertise" with Google? I would argue that this density of pins makes the map incredibly hard to read. I feel as though Google Maps used to be way less busy than this.

I stumbled upon a really interesting article last night on the history of Mahavishnu Orchestra, one of the greatest jazz-fusion bands of all time. The article points out some of the influences they had on other groups, and reveals some interesting history I didn't know (like lead guitarist John McLaughlin being asked to join Weather Report, a band that would go on to make some terrific jazz-fusion of their own). It's definitely worth a read if you're familiar with the group, or even if you aren't!

I can no longer recommend this mouse; more in this post
Logitech M585 Wireless Mouse

Since late 2017, I've used the Logictech M705 Marathon wireless mouse at work. I loved everything about this mouse. It had great battery life, even when only using 1 AA battery (it supports two batteries for even longer life, at the expense of extra weight). The weight of the mouse with one battery was terrific; not too light and not too heavy. To top it all off, it had great extended button placement at my thumb, allowing me to quickly browse back and forward in my web browser with a quick click.

This past December, however, I started noting phantom double clicks when single clicking, a problem that quickly got annoying. Searching around the internet informed me that this is a common problem with Logitech mice, and is a sign that the physical switch under the left mouse button is failing. I immediately headed to Amazon to pick up another M705 when I discovered a ton of negative recent reviews. Apparently, Logitech has actually changed that product, dropping some features and cheapening the body, while keeping the same model number (how can any company rationalize doing this, by the way?).

Persuaded to stay away from the newer model, I opted instead for the Logitech M585. Having had this new mouse for a few months now, I'm fairly pleased. The mouse is smaller physically, and not as sculpted as the M705, which is a minor drawback to me (the M705 had a real nice feel in the hand). However, this new one still fits my hand well. Pointing accuracy is dead on. The 585 supports moving between multiple machines, but it requires external software (on both systems), and that was enough of a barrier that I didn't bother.

Time will tell if the mouse holds up to daily driving, but so far so good.

Photos from Space

Mar 25, 2021

I've been following the ongoing saga of the ship stuck in the Suez canal, and I find it very interesting. It's pretty clear that we're building boats that are too big. Anyways, a post from The Verge today linked to an incredible photo taken from space. The resolution on this photo is really mind blowing. The more I think about this, however, the more I've got to believe that this capability has existed for a long, long time. The US military has likely had photographic capabilities like this since the cold-war days. I wonder what kind of photos they can take today?

Regardless, it's really amazing that you could take a photograph of stuff on the ground, from outer space, and be able to see even small details in said photo. Incredible!

Here's a fascinating video on the history of the man that started the Chef Boyardee brand. I had no idea!

One of the well known tenets of Python is:

There should be one (and preferably only one) obvious way to do it.

There are plenty of places in the Python universe where this tenet is blatantly ignored, but none tickles me quite like shutil.copy and shutil.copy2. Both methods copy files from one location to another, with one (and apparently only one) difference, as the documentation for copy2 spells out:

shutil.copy2(src, dst, *, follow_symlinks=True)
Identical to copy() except that copy2() also attempts to preserve file metadata.

I'd love to know what motivation the author of the (very poorly named) copy2 method had for adding it to the library. Was adding a preserve_metadata argument to copy() not sufficient for some reason? That's what any sane developer might have done.

Ads on YouTube

Mar 12, 2021

I watch a lot of YouTube, and I do so across a couple of different platforms: via computers and via my phone. Watching on my phone through the YouTube app has, in recent months, become nearly unbearable. Ads roll constantly on nearly every video, with no easy way to avoid them. On my various laptop computers, I have the luxury of using uBlock Origin, which keeps those ads at bay. Not so on my mobile device.

I get that Google wants to monetize their platform (and that hosting videos is expensive), but the ads are now worse than commercial television! I guess the increase in ad frequency is intended to drive people towards signing up for YouTube premium. I'm too much of a cheapskate to spring for that service, especially given that it's $12 a month, which is 33% more than a basic Netflix account costs.

Are there ad-free ways of watching YouTube on mobile?

I primarily listen to music from the 1960s, 1970s, and 1980s. There's a ton of great music from those eras, some of which goes under the radar. This is the first in a new occasional series where I share some of the gems I've found that others may overlook.

My first entry is an album I only recently stumbled upon from a band I never paid much attention to (much to my regret!). The album, from 1977, is Even in the Quietest Moments... by Supertramp. This album is terrific, wall to wall, which is a recurring theme for this group (their more popular albums Breakfast in America and Crime of the Century are also consistently excellent, and I recommend both).

The opening track from this album (Give a Little Bit) is a well known radio hit, but my favorites are the title track, as well as the epic closer Fool's Overture, which clocks in at nearly 11 minutes. Give it a listen!

Tom Scott's YouTube channel is always a delight, but his most recent video on why YouTubers have to declare ads is a real treat. It's long-ish (30 minutes), but I highly recommend it.

I ran into a problem at work today with a custom template tag I've written in a Django project. The tag works as follows:

{% if_has_team_role team "role_name_to_check" %}
<!-- block of HTML to be included if true goes here -->
<!-- otherwise, all of this is skipped -->
{% endif_has_team_role %}

I'm using a custom tag here, rather than a simple conditional, because the underlying check is more complicated than should be expressed at the template layer of my code. The problem came when I nested other conditionals in this block:

{% if_has_team_role team "role_name_to_check" %}
  {% if some_other_condition %}
    <!-- a nested element -->
  {% endif %}
{% endif_has_team_role %}

This setup was throwing an error. While searching for a solution to this issue, I stumbled upon this StackOverflow question. Reading the question, it matched the very problem I was having. At the end of the question, I noted that I was the original asker, 5 years ago; ha!

The solution I had accepted back when I asked this was, at best, a workaround. It turns out that a simple typo in the code was to blame, and fixing that typo solves the problem. It's a nice feeling to answer your own question, even if it takes five years to do it.

On Working From Home

Feb 3, 2021

We're closing in on a full year since the COVID-19 lock down took effect here in North Carolina. I've been working from home every week since the beginning of that lock down (mid-March 2020), and so far I really like it! In fact, once my employer opens its campus back up (whenever that may be), I'll likely continue to work from home for the majority of the week. Here are a few of the pros and cons that I see, in no particular order:

Pros

  • Terrific Commute: I love not having to fight traffic or traffic lights twice a day, and I'm saving about 40 minutes total per day sitting in my car.
  • Saving Money: I'm driving less, which means I put way less gas in my car (I've filled up exactly 3 times since last March). I also eat out way less, which has reduced my lunch costs considerably.
  • Home Cooked Meals: Speaking of lunch, I get to eat home cooked meals every day. I rarely took in a lunch of my own to work, so this is a nice perk.
  • Spending Time with Family: Having lunch with my wife and daughter every day is a real treat, and is time I otherwise wouldn't have with them.
  • Fewer Distractions: Distractions in my employer's open work office environment were a real nuisance, as were the interruptions from co-workers who would stop by to ask a question.

Cons

  • Home Cooked Meals: Although I love eating home cooked meals for lunch, I'm also missing a few of the places I used to visit (I haven't had a Bojangles biscuit in nearly a year; the humanity!).
  • Spending Time with Family: I miss interacting with humans other than my wife and child.
  • Separating Work from Play: When your work lives where you live, it can be difficult to separate yourself from the work world. I occasionally find myself doing work during hours of the day I would normally be doing something for pleasure. I suppose this comes down to discipline, for the most part.

Merlin Bird ID

Jan 24, 2021

One of the tools I've been using in my backyard wildlife identification efforts is the Merlin Bird ID app (I'm using the Android version). This app is aptly named, because the ID capabilities are like some sort of dark magic!

There are a fair number of useful features in this app, none more so than the photograph identification tool. You simply upload a photo of the bird you want to identify, select the date and location where you spotted the bird, and the app gives you a list of possible birds. Each entry has information on the bird itself, and a number of excellent photos to compare your candidate against. In most of the trial cases I've given the app, only two or three candidates are usually returned, a testament to just how smart the "brains" of this thing are (all of its recommendations for my photos have been spot on so far).

Another feature that I haven't used much yet is the bird-call feature. While examining details on a bird, you can listen to a number of its calls, which makes identification by ear a lot easier. I cannot recommend this app highly enough!

Backyard Wildlife

Jan 18, 2021

We've had a bird feeder in our backyard for a few years now, but I've only ever half-heartedly watched the birds that come to it. This year for Christmas, my wife requested (and received) the addition of a suet feeder. Between the cold of winter, the never ending lock-down of this god forsaken pandemic, and my general boredom, I've been spending a lot more time actually watching the birds that visit our backyard. More importantly, I've also been photographing these birds, as well as other wildlife we see around our house. This Backyard Wildlife album is the result. As an aside, this is the first public photo album I've published since 2019!

I can emphatically say that I now enjoy watching and identifying the birds that visit. Prior to this endeavor, if you had asked me how many different types of birds come to our feeder, I would have guessed 10, maybe 12. As of this writing, I have photographed 26 different species of birds in and around our house. I've seen a few more which have yet to be photographed (some birds, it turns out, are fairly difficult to shoot). As a result, this album will be a living album; I plan on adding to it as I shoot new pictures.

My self-imposed criteria for this photo album is that all photos must be taken from the area immediately surrounding my house. There will be no duplicate species photos (with the exception of variants by sex), and I will replace photos over time with improved versions as I am able (a few photos are fairly rough, due to the birds' ephemeral visits). If you have a bird feeder in your yard, take the time to watch the birds that come. You'll be surprised at what's right in your backyard! If you don't have a feeder, be sure to get one; it's great, cheap fun.

Here are a couple of teaser photos from the album:

I've been doing web development in some form or fashion since 1999 (as an aside, the Wayback Machine even has a snapshot of one of my old websites; what a world)! I probably started picking up JavaScript way back in the early 2000s, as my web developing knowledge improved. Since web browsers are generally really good at supporting the old way of doing things, my knowledge of JavaScript has been pretty stagnant for a long time.

Not too long ago, I stumbled upon The Modern JavaScript Tutorial, a terrific resource for learning how to do things the modern way. I'm working my way through reading it, even taking the time to go back over the basics. I've already learned a lot; some of what I've been doing has apparently been deprecated for a while now, which was interesting to learn.

I've also learned about features I hadn't seen before (the nullish coalescing operator being one of those). I recommend it if, like me, you're still living in the dark ages.

The Carnyx

Jan 5, 2021

I stumbled upon the following museum lecture from 2015 on YouTube, highlighting the carnyx, a Celtic war horn that was used thousands of used ago (and only recently reconstructed!). If you have 45 minutes and an interest in either history or music, I highly recommend watching.

One of my personal goals for 2021 is to increase my writing frequency here at this website. A little over 14 years ago (!) I did some analysis on my posting habits, and I thought I'd do something similar to see how my posting has changed over time. Using a quick Python script and matplotlib, the latter of which I don't use frequently enough to ever remember how to use, I came up with the following two diagrams:

Both graphs show how, in recent years, my posting frequency has really dropped off a cliff (having a kid will do that to you, I guess). Even prior to kids, however, I was posting much less frequently than I did in the beginning.

Now that I have a new publishing platform, posting has gotten easier for me. My personal goal is to post at least three times a month, which should put me on par with 2011, which is the last time I averaged that total.

Python showPath Script

Dec 27, 2020

I occasionally have a need to either view the PATH environment variable from the command line, or search the PATH for something. I wrote a small Python script to make this easy to do, adapting it from an old Perl script I wrote years ago. The script, in its entirety, is shown below (you can also download it here; just save it as a Python script). Note that this script currently has a Windows focus, but could easily be adjusted to work in Linux too.

When used by itself, the script will simply pretty-print all of the paths currently in your environment's PATH. You can pass a --sort option to sort the output, or you can supply a needle to search for. Hopefully someone else will find this as useful as I do.

#!/usr/bin/python
import argparse
import os


parser = argparse.ArgumentParser()
parser.add_argument('searchterm', default='', nargs='?')
parser.add_argument('--sort', action='store_true', default=False,
                    help='Print PATH in a sorted form')

args = parser.parse_args()

path = os.getenv('PATH').split(';')

if args.sort:
    path = sorted(path)

if args.searchterm:
    needle = args.searchterm.lower()
    print(f"\nSearching PATH for {needle}")

    matches = []
    for p in path:
        if needle in p.lower():
            matches.append(p)

    if matches:
        print(f"Found {len(matches)} result{'' if len(matches) == 1 else 's'}")
        for m in matches:
            print(m)
    else:
        print(f"Unable to find {needle} in PATH")
else:
    print("\nShowing PATH:\n")
    for p in path:
        print(p)

Django 3.1 now uses the Python pathlib module for its internal paths. This change caught me off guard when I started developing with it, as I was used to the old os.path way of doing things. Here's a look at the old way and its newer counterpart:

# Old way
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# New way
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent

Joining paths together uses a very different mechanism as well:

# Old way
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# New way
STATIC_ROOT = BASE_DIR / 'static'

# Alternate new way (which I prefer)
STATIC_ROOT = BASE_DIR.joinpath('static')

These new mechanisms feel so different since they treat paths as objects, not strings. This works well, however, since paths aren't really strings in the first place. Transitioning to this new way of thinking is taking me some time, since prior to this module, every path in Python was treated as a string. However, I can already see the utility of this module, especially when it comes to resolving relative paths.