Flying Blind

Feb 6, 2022

I love almost any video that Tom Scott puts out. His latest, from his Tom Scott Plus channel, is fantastic. The teaser: "She's blind. I'm blindfolded. We're going to fly a plane." Check it out!

Every Day Meatloaf

Feb 1, 2022

This is a recipe I've been meaning to transcribe for a while now. It's delicious and the sauce is what really makes it (we sometimes double the sauce recipe).

  • 2 slices of dry bread, broken
  • 1 cup milk
  • 1.5 pounds ground beef
  • 2 beaten eggs
  • 1 onion, diced
  • 1 tsp. salt
  • 1/2 tsp. sage
  • Dash of pepper

Soak bread in milk while assembling the other ingredients. Add meat, eggs, onion, sage, salt, and pepper to a bowl; mix well. Place in baking pan and cover with piquant sauce. Bake in a moderate oven (350 degrees F) for 45 minutes to 1 hour.

Piquant Sauce

  • 3 Tbsp. brown sugar
  • 1/4 cup ketchup
  • 1/4 tsp. nutmeg
  • 1 tsp. dry mustard

Combine ingredients in a small bowl.

This new Technology Connections video is great, and has me wanting to buy a new can opener.

Circus Peanuts

Jan 14, 2022

I am one of the few people on this planet who enjoys circus peanuts (though, given that multiple companies manufacture them, I can't be alone, right?). In fact, I bought a small bag of them tonight at the grocery store. My wife, who dislikes them immensely, tried a bit of one to remind herself of their taste. As expected, she still hated it. "It tastes like styrofoam," she said. I guess that means there's more for me!

Circus peanuts; yum!

Anderson Bruford Wakeman Howe were a progressive rock band comprising 4 of the 5 members of Yes. They only released a single, self-titled studio album, and it might as well be considered a "lost" Yes album. Released in 1989, well after the 90125 album that redefined their sound, this particular album is really nice. It has a number of great melodies, terrific musicianship, and varied musical themes. Give it a listen here on YouTube (I apparently can't embed the video, so the link will have to suffice).

I like using Google Photos, as it has nearly all of the features I care about. However, the search capability is puzzlingly lacking, especially from a company whose core foundation is based on searching for stuff. One of the features that Google touts for Photos is their AI-enhanced searching capability. For instance, if you type a color into the search box, you'll see a listing of photos that feature that color; pretty neat! However, if you search for specific text that appears in your image descriptions, it won't provide any results.

One of things I tend to do for my wildlife pictures is enter the animal's identification into the image description: for example, the description for a picture of a male northern cardinal might look something like Northern Cardinal (Male). Later, if I happen to search for "northern cardinal," no results will be returned! I'd love to be able to search the meta-data (and maybe even the comments) for my photos. It would allow me to use the photos as a database of sorts, which is as it should be.

I Hate FedEx

Dec 28, 2021

A little over a month ago, I ordered an UpLift Desk for my office. All three packages were shipped via FedEx, and it was a colossal headache. The top arrived damaged, so I had the company send me another, which they graciously did. That one also arrived slightly damaged, though not as badly as the first. I decided to use the second top, just to avoid having to deal with another support ticket (the desk, by the way, is terrific).

The FedEx tracking updates, while packages are en route, appear to be updated only once daily. Compare this to UPS or Amazon, who update their tracking information immediately. FedEx's estimations for when the packages would arrive were also all incorrect (only one of the three packages ended up arriving the day it was forecast).

Nearly a week ago, my wife's phone broke. We ordered a replacement direct from Google, and guess who it's shipping through? We ordered it December 22, and it was scheduled to be delivered December 26, by the end of the day. The last tracking update was December 23; nothing further appeared until this morning. Today's update shows that the package is in Charlotte, NC, but with this caveat: Delivery exception: Damaged, handling per shipper instructions.

I guess at least they're honest. It's not clear to me, however, what happens next. Will FedEx deliver the damaged package as is? Will it get returned to the shipper, only to have a new one shipped again? I contacted Google about it, but my support ticket is still being processed (apparently the Google support folks don't even know what happens).

FedEx has miles to go to catch up to their competition. I've never had these kind of issues with UPS or Amazon shipping. It amazes me that a company with this kind of service remains in business.

Gmail Spam Filtering

Dec 21, 2021

Is it just me, or has Gmail's spam filtering gotten worse? In the past month or so, I've had more false positives end up in the spam folder than I've ever had while using their service. Emails from all sorts of valid places:

  • My online pharmacy orders
  • Electronic receipts from The Home Depot
  • Bug reports on GitHub / GitLab
  • Notifications from NewsBlur, my RSS feed reader of choice

Every time one of these false positives occurs, I click the "Not Spam" button, but it doesn't seem to make much of a difference. Has anyone else seen anything similar? It's really rather frustrating.

Musical Output

Dec 12, 2021

I haven't yet seen the Get Back documentary about The Beatles, but I've been watching various clips of it online. One of the surprising things about what I've seen so far is the rejection of some of George Harrison's songs: specifically All Things Must Pass, which is one of George's best all-time compositions. Like many of his other songs, however, John and Paul dismiss it.

I genuinely don't understand this mindset. My best guess is that there's a lot of ego going into these decisions (and likely jealousy). As a member of a band, whose very existence relies on making music, shouldn't the group welcome every single song or idea a member comes up with? If I were in a band, I feel like I'd want to embrace every idea that came along. More ideas lead to more songs; that, in turn, leads to more albums, more sales, and more touring possibilities. It seems like a no-brainer to me. Think of all the great music the world has been denied because of petty squabbles between people in a musical group. What a shame.

How Optical Mice Work

Dec 4, 2021

I had a general idea about how optical mice work, but I didn't know the specifics. This nicely animated video gives a short, high-level overview of exactly what's happening. It's remarkably well produced.

Christmas Price Index

Nov 17, 2021

In my recent sleep-deprived state, I started to think about the Christmas song The Twelve Days of Christmas. Being a cumulative song, I've always found it funny that, technically speaking, the gift-giver ends up giving the true love 364 gifts. I got looking at the Wikipedia page for the song, and lo and behold, there's an actual economic indicator (albeit a tongue-in-cheek one) that PNC Wealth Management maintains about these gifts. It's called the Christmas Price Index, and gets used as a commodity price index. More amusing than the index itself are some of the criticisms of it that are listed in the Wikipedia article:

First, the index does not clearly define the products that comprise each of the twelve gifts. For example, the price for the eight "maids a-milking" only includes the cost of eight laborers at Federal minimum wage, while milking also requires at least a milk cow, goat, or other such animal, which is an additional cost.

Even better is this note on the index for 2020:

The 2020 index did not include nine Ladies Dancing, ten Lords-A-Leaping, eleven Pipers Piping, or twelve Drummers Drumming due to COVID-19 restrictions on live performances.

Brilliant.

CSV Parsing Woes

Nov 14, 2021

An occasional annoyance of my job is having to deal with poorly constructed data. One recent instance of this came through a collection of CSV files. In these files, certain free-form text fields sometimes included either non-escaped double quotes or an embedded newline where there shouldn't be one. Shortened examples of each are shown below:

"Samsung","ABC-12345","2.5 TB SAS 2.5" hard drive","Released","2018-06-01"
"Lenovo","DEF-88776 
PQR-66554","Mechanical chassis","Released","2020-02-22"

The first line above has an embedded double quote character which has not been escaped. The second line showcases a rogue newline character.

Parsing these problematic cases in Python gets real tricky, and the native csv module doesn't have great malformed data handling support. While thinking about how to handle these situations, it occurred to me that I could use the way the file was constructed to my advantage. These files are output by, what is to me, a black box. Under the hood it's undoubtedly a database query, the results of which are then sent into a CSV format. As a byproduct, each file has a consistent format where each field is quoted, and fields are separated by a comma. I can use the "," string (double quote, comma, double quote) as my separator, looking for the fields I expect:

previous_chunk = []
with open(infile, 'r', encoding='utf8') as csvfile:
    with open(f"{infile.stem}-clean.csv", 'w', encoding='utf8', newline='') as outfile:
        writer = csv.writer(outfile, quoting=csv.QUOTE_ALL)

        for line in csvfile.readlines():
            line = line.rstrip()  # Trim the trailing newline

            pieces = line.split('","')  # Split on our separator
            pieces[0] = re.sub(r'^"', '', pieces[0])  # Remove the first double quote
            pieces[-1] = re.sub(r'"$', '', pieces[-1])  # Remove the last double quote

            # If we don't have the number of columns we expect, merge
            if(len(pieces) != expected_columns):
                previous_chunk = merge_chunks(previous_chunk, pieces)
                if(len(previous_chunk) == expected_columns):
                    writer.writerow(previous_chunk)
                    previous_chunk = []
                elif(len(previous_chunk) > expected_columns):
                    print(f"ERROR: Overran column count! Expected {expected_columns}, Found "
                          f"{len(previous_chunk)}")
            else:
                writer.writerow(pieces)

The merge_chunks method is very simple:

def merge_chunks(a, b):
"""
Merges lists a and b. The content of the first element of list b will be appended
to the content of the last element of list a. The result will be returned.
"""
    temp = []
    temp.extend(a)

    if(a):
        temp[-1] = f"{a[-1]} {b[0]}"
        temp.extend(b[1:])
    else:
        temp.extend(b)

    return temp

I believe the only way this could potentially break is if the content, for some reason, contained the "," separator somewhere in a data field. Given the types of data fields I'm working with, this is highly unlikely. Even if it does occur, I can use the format of some of the fields to make best guesses as to where the actual dividers are (e.g. the trailing elements on each line are typically always date stamps).

This is obviously not a general solution, but it sometimes pays to step away from the built-in parsing capability in a language and roll your own scheme.

I recently had to change the URLs of some of my REST endpoints in a project at work. In so doing, I started receiving reports of users who weren't seeing the data they expected from some endpoints. My redirect seemed simple enough:

location ~* ^/rest/(report/.*)$ {
    return 302 https://$host/rest/project/$1;
}

So, I'm sending URLs like https://myhostname/rest/report/1/ to https://myhostname/rest/project/report/1/. The redirect worked, but the problem was that any additional query string that was included in the URL got dropped.

For example, https://myhostname/rest/report/1/?query=somevalue would result in https://myhostname/rest/project/report/1/. The fix for this is easy, but is something I didn't realize you had to pay attention to:

location ~* ^/rest/(report/.*)$ {
    return 302 https://$host/rest/project/$1$is_args$args;
}

The $is_args directive will return a ? if there are arguments, or an empty string otherwise. Similarly, $args will return any arguments that happened to be passed. Including these variables ensures that any query parameters get passed along with the redirect.

Here's another terrific Tom Scott video, this time showcasing a shooting range in Switzerland where you shoot over a busy road. The technology behind the electronic targets is pretty neat. One more reason why Switzerland is one of the best places on Earth!

I didn't know this, but Judy Sheindlin (of Judge Judy fame) was interviewed back in 1993 on CBS' 60 Minutes. This interview is what essentially launched her career as a television judge. It's fascinating that her personality on television is essentially the same one she used in New York's family court system. It turns out that she's pretty much herself!

Barred Owl

Oct 1, 2021

I've longed to photograph (and even just see) an owl in the wild for a long time, but they are oh-so-elusive birds. We do hear barred owls behind our house regularly, but I never see them. However, just before sundown tonight, one started calling out. I ventured into the woods to find it and, fortunately, I was able to!

Barred owl

Office Chairs

Sep 23, 2021

I've been fortunate during this pandemic to be able to work from home the entire time. It has only recently occurred to me, however, that my current setup is lousy when it comes to comfort. My desk is the same one I've had since my college days, and the chair I use is a hand-me-down from my wife (which is a step up from the crappy cheap one I used to own). Why am I putting up with this?

My ideal desk would be a standing model, if for no other reason than to provide some height adjustability; my current desk is a fixed height, and it's rather low down in my opinion. The ideal chair, however, is harder for me to pin down. Should it have a head rest? Arm rests? Mesh or padded backing?

If you're reading this, what kind of chair do you use? Where can one go to try out office chairs before you buy? I don't recall seeing these in furniture stores, and office supply stores (as I recall) only carry the cheap stuff.

This follow-up video from Technology Connections on dishwasher soap is fascinating (the video is in response to a previous one on dishwasher detergent packs). It's over 45 minutes long, so you'll need to make time for it, but I give it a high recommendation. The previous one is also well worth a watch, though he provides a very quick overview of it in this video.

For over a decade now, I have logged my daily weight using Libra Weight Manager, a great little Android app. I last wrote about this in December of 2018, so it's high time for an update. Shown below is the latest graph (click to expand):

As you can see, I've gained weight substantially. In fact, I'm now the heaviest I've ever been! The graph starts heading up in 2018, which happened to be the year our first daughter was born, though I started gaining well before she arrived. At the beginning of the pandemic in 2020, my weight started to come back down, but has since done an about-face and is increasing again.

Stress likely corresponds (to a degree) with my weight drops. The lowest point on the graph is just before I got married, and the big dip at the beginning of 2020 is pandemic related. My nightly weakness is ice cream; I have some almost every night. This, and an increase in the snacking I do in the afternoon (thanks to working from home) are definite contributing factors. Eating at home has had benefits, however, as I'm eating better meals than I used to for lunch. Prior to working from home, I ate out nearly every day.

I need to turn things around again and lose some weight. I'd certainly feel better, both mentally and physically.

Back in November of 2019, I wrote about some deformable LED lights that I picked up on Amazon for our garage. This weekend, one of them died, after only about 21 months of occasional use. I have since picked up a newer variant that claims to have a 5-year warranty. The happy part is that I got a pack of 2 of these for much cheaper than I paid for one previously.

It's disappointing to me that I didn't even get 2 years out of those bulbs, despite their having a "2-year warranty." Lots of Amazon reviews for the old model point out that the warranty is bogus; no one is available at this "company" to take your information and replace the product. Given how many clones of these there are, I'm guessing they're all pretty much bogus Chinese listings. I am unable to find any UL-listed variants of these lights, which is also disappointing. I have read about some of these melting, especially the ones with plastic bodies. Both of the ones I own have aluminum bodies, which should help with temperature control, but I'd feel a lot better if the bulbs were certified in some way.

Ultimately, I'd love to install some of the consistently-well-reviewed Barrina LED fixtures in my garage, but that would involve some rewiring work that I'm not real keen on doing.