I was delighted to learn this evening that I could install the excellent, open-source database Postgres on my Mac by downloading a simple app bundle—Postgres.app—and copying it to my Applications folder. In contrast, installing SQL Server on my Windows machine at work was a big deal.

🎮 Ori and the Will of the Wisps

Over this past week I played through Ori and the Will of the Wisps on the Nintendo Switch. It is a challenging Metroidvania with beautiful graphics and a moving story. I highly recommend it—especially if you enjoy platforming challenges. The way that Ori moves, jumps, bashes off enemies, and launches into the air is pure delight.

I had purchased the game almost two years ago when it first came out, and abandoned my save file because the game kept crashing. I had hoped the game would be patched so it no longer crashed, but that did not happen. On this play-through, the game crashed five or six times. Fortunately, I didn’t lose any progress when it did.

ETL with Python

I have been experimenting with writing ETL (extract, transform, load) scripts in Python for work. The scripts were mostly fun and easy to write, but the outcomes have been disappointing: unacceptably slow load times.

I usually work with an instance of SQL Server that runs locally on my computer. I use it for data collection, analysis, and reporting, and have never needed a shared server. In the local environment, I have always loaded .csv files to staging tables via BCP or the BULK INSERT command in T-SQL scripts; then I use T-SQL queries or stored procedures to load the data into the destination tables. This approach is very fast, but it only does “L” part of ETL (load). It also doesn’t work for remote databases, unless I have access to a filesystem that database server can read.

A Python script using a library such as PETL or Pandas, on the other hand, can do the whole thing: read a file in from just about any file format, transform the rows and columns in various ways, then load it into the database.

Lately I have been working with various databases that are stored somewhere in the cloud. They are the slowest databases I have ever worked with, and I don’t have access to the filesystem they can BULK INSERT from. Writing an ETL script lets me work around that problem easily. By far the hardest part of writing my first ETL scripts with Python was getting working SQL connection string. (I think that part would have been a cinch if our database was something open source like PostGRES.)

Unfortunately, my simple ETL script could load a table at the rate of 5 records per second, which is comically slow. At that rate, our data will take days or weeks to load. I’m not sure what the bottleneck is. It is probably slow network transfer time on top of a hugely sub-optimal data insertion method on the database side. I think that, in the end, it may not be worth figuring out. I should probably try a better tool for the job.

Dependence Day

On Independence Day, we Americans celebrate throwing off the yoke of tyranny of the British Crown and declaring that we, and all people, have certain inalienable rights under natural law.

The Supreme Court has made a mockery of this idea in its recent decision Dobbs v. Jackson. Now we are being led to believe that our natural rights are not natural at all. Instead, they depend on national tradition—specifically what the Supreme Court majority deems to be national tradition.

I refuse to believe that our rights should depend on the whims of a small group of unelected officials. It’s not much better than living under a monarchy.

📺 Stranger Things season 4 really clicked for me. Sure, it has some clumsy bits and didn’t serve half its characters with a real story, but overall I was hooked from the start and loved every minute of it.

Summer computer science

I started teaching my son Python turtle graphics this week. He’s only 5, but he is absolutely mad for computers and is thrilled to get to use them to do something.

I first learned to program using turtle graphics in Logo when I was in third grade. It was back in the 1980s, when computers were too expensive for my family to own, so it was also the first time I ever used a computer. My mom signed me up for a class at the local community college. We all used Apple IIs in the computer lab, which were probably old even then. Most of those machines had green monochrome monitors, and all of them had two 5.25” floppy drives. Now, of course, he is using my old MacBook Pro on my couch, and coding with Python in Visual Studio Code.

We have been working through some simple exercises, like finding different ways to draw a square. He understands looping already, and asked how to create an infinite loop to draw the square (and watch the turtle move) endlessly.

He and I are progressing very slowly, mostly because he asks lots and lots of questions, and partially because he is interested in doing things with turtle graphics that I was not prepared to teach him. (I had planned to teach him to draw lines and shapes. He is more interested in turning the turtle into a rocketship and moving it all around the screen.)

He is getting it. I installed Pythonista on his iPad last night, and this morning he used it to write a Python program all on his own, starting with:

from turtle import *

It’s pretty cool.

Summer math

It took a few days of cajoling, but I somehow convinced my daughter to study math with me over the summer—at least until we go on vacation in about a month. We are going through a “step up to fifth grade” packet that her math teacher gave us. I am making up my own problems based on the material and challenging her to think mathematically, too. She is an A+ student in the middle level of math in her grade, but she has been unable to pass the school’s rigorous, though largely arbitrary, criteria to gain entry into the highest level. I am hoping to be able to help her break through whatever glass ceiling the school is imposing on her. Our math studies have been a very rewarding part of our day.

I have been resting and collecting thoughts long enough. I plan to start writing blog posts again! I just need to make some time to do it.

I have not felt like I have anything to say lately. It has been a weird, intellectually empty feeling—probably born of overwork and my new, thrice-weekly exercise habit. My mind is scattered and I cannot complete a thought.

I am afraid I am becoming a workaholic. I keep returning to work or work-related stuff in the evenings now, almost every day. I feel like I can’t get enough done during the day anymore.

Today was my son’s preschool graduation. The whole family went to his very cute graduation ceremony this morning. We had a pizza party in his honor this evening, and my wife made a delicious cake to his specifications (chocolate cake, vanilla buttercream). He is very proud of himself and I am very proud of him.

I watched Apple’s WWDC keynote this afternoon. I am most excited about the new MacBooks because I have been hoping for that kind design since 2020. I really want one, but the closest I will ever get is buying one for my daughter next year to use for middle school.

Ask Micro.blog: Can anyone recommend a good PC game controller for young children? I think my kids' hands are too small for my Xbox controller. There are many choices on Amazon but many seem low quality. I’m planning to set up a retro gaming machine.

My son, the programmer

Today I showed my son how to do a couple things in Python for the first time. We only spent about half an hour on it, but it was a lot of fun. First, I showed him how to to use a Jupyter notebook in Visual Studio Code. We made Markdown and Python cells. For the Python cells, I walked him through a Hello World example. I then had him print out whatever he wanted many times in a for loop. That was the first fun thing I used to do in BASIC on the Apple ][ in school. In a short amount of time, he learned print, for, and range, which is pretty good for a five-year-old’s first lesson. I plan to get turtle graphics (maybe this, I’m not sure) installed on his machine soon.

My current Python project

I have been burning the midnight oil over the past week writing a data validator program—basically a front-end to the PETL validate function—in Python. This would be my third such program, and it is going to be the sort where it can be configured entirely, and flexibly, with configuration files. Theoretically, it should not require coding, or at least not that much coding, to set up validation rules. It has been a fun project thus far, and it is nearing the point where all the pieces will come together.

Lately I have been writing unit tests, and that has been where all the pain points have been. I used to use Python’s standard unittest framework for unit testing, but it requires so much repetitive code that I decided to use pytest instead. Pytest lets you parametrize unit test functions, which reduces code repetition considerably.

I never used pytest before, and ended up spending a lot of time trying to figure out how to get it working correctly. Getting my test module access to the package I’m testing was the first major hurdle. After that I spent a couple hours figuring out that I couldn’t make test fixtures that return lists, and that I couldn’t use text fixtures as test parameters. For the latter, I found a workaround in the form of the pytest-lazy-fixture package.

Today was my son’s first playdate, which has been long delayed due to COVID. We met our son’s friend’s parents, who were very nice, and had a fun cookout this afternoon. I even made coffee ice cream in my new ice cream machine.

Enable Recycle Bin on mapped network drives

My favorite tech discovery of the week was this one: an old TechNet post titled “Enable Recycle Bin on mapped network drives.” This article helped me figure out how to get the Windows Recycle Bin working on my primary documents folder, which is a mapped drive that isn’t really a mapped drive.

For historical reasons, I store my documents on a mapped drive that is actually a deeply nested folder on my hard drive. Several years ago, my company implemented Microsoft OneDrive for file sync, sharing, backup, and so on. While that is great, it did mean that I had to move my folder tree to a very long path. Because I like to use long, descriptive names for everything, I ended up bumping into “file path too long” errors, especially in Excel. Excel will not even open a file whose path is over 256 characters long.

When your Microsoft OneDrive root folder already takes up almost 100 characters, that leaves too little left for me to use. To get around the character limit, I used the [SUBST] command in a startup script to substitute a drive letter (Z: in my case) for a folder on the C: drive.1 The downside of using SUBST is that you get no support for the Recycle Bin2. To get around that limitation, I found that using FAR Manager, rather than File Explorer, as my file manager would actually move files to the Recycle Bin upon deletion. Unfortunately, FAR Manager’s text-only interface and general jankiness led me to abandon it for Double Commander, which is superior for my needs but does not move the file to the Recycle Bin on my mapped Z: drive.

The TechNet post I found describes a way to make a .reg file that will update the Windows Registry and create a new mapped drive to whatever location you want, with full Recycle Bin support. You create the file, run it once, and you are all set. The drive, unlike one mapped with SUBST, will persist across reboots, and it will have full Recycle Bin support.

I love it, and think I should try to write a PowerShell or Python script that will create such mappings without having to edit a .reg file manually.


  1. Believe it or not, but I still remembered the SUBST command from my MS-DOS days in the late 1980s and early 1990s. ↩︎

  2. I take it for granted that it is preferable to have the safety net of the Recycle Bin, in case I delete something accidentally. ↩︎

I did my first workout at my new gym tonight. I am happy I did, and am proud to say that it was not as hard as I thought to get back into cardio and weights again after many years away from them.

Robocopy

Much to my surprise, I have been relying heavily on a very old Windows app, Robocopy, at work the past few days. Part of the work I need to do this week involves moving very large files to and from a network share over a very slow VPN connection. Those file transfers were hosing my file manager, DoubleCommander, so I started doing them from Windows Terminal via Robocopy. It’s a tool I haven’t really used in about 20 years, when I wrote batch jobs to deploy my software or move data files around, but it still works.

It defaults to copying folders, but it is easy to configure the command to move individual files or groups of files. I love how it provides a summary of what it is going to do, and provides a completion percentage as it copies or moves each file.

Tonight, I learned of a feature that I should have been using the whole time: the /compress flag. It will request network compression during the file transfer, if it is available. I will try that tomorrow to see if it speeds up those enormous file transfers I have been doing.

I joined a gym 💪

I joined a gym today. It has been 12 years since I last had a gym membership. Getting to the gym has seemed impossible to me due to work and kids—and then the pandemic. Last weekend, my wife said I should try, and I jumped at the chance. I hope I like it, and can find time to go—probably after my kids are asleep (or, at least, sopposed to be asleep.

I’m setting up a web server for my five-year-old son to play with on an old Raspberry Pi that fell into disuse a long time ago. I was delighted to discover the Raspberry Pi imager exists now to make OS installs a breeze.

Windows PC setup is still a pain

I set up an old MacBook Pro for my son a little while ago, which I finally gave to him today. I set up an old—but, compared to the Mac, far newer and far more powerful—Windows machine today for my daughter. Setting up my son’s Mac was a breeze. Nearly everything was downloaded via the Mac App Store, and I needed one reboot for a system update.

Setting up the Windows 11 machine took a lot more work. To be fair, it was, in one way, easier: almost all the software could be installed and updated on the command line via winget. Most of the updates were handled by one command: winget upgrade --all -h, which is close to the apt update and apt upgrade -y commands I use on my Ubuntu servers. Unfortunately, some packages would not update because reboots were needed, and Windows was very bad at explaining that to me.

Overall, it took about six reboots to get everything updated and to satisfy Windows Update. Sadly, the first time I booted into my daughter’s new account, which was just a few minutes ago, Windows Update requested a reboot immediately, so all the updates may not yet be done.

Overall, my experience Windows has gotten a lot better in the past few years, but it still lags behind the Mac and Linux in some important areas.

Today was the first 90º+ day of the year for us in Central New Jersey. I took my family out for ice cream, and later to the beach, to beat the heat. I think everyone had a great day.

🎧 Sony WH-1000M4 headphones are just OK and that sucks

Listening to the AirPods Max for five minutes in an Apple Store ruined me for other noise-canceling headphones. Not because they sounded good. In fact, I listened to them only long enough to learn that they are bass heavy and exciting. What wowed me about them was the active noise cancellation. It was far better than anything I had ever experienced. It made the din of the Apple Store—all those human voices, which are difficult for ANC to cancel out—go away completely.

Sadly, they are $550 headphones (street price $479) that don’t even have an analog headphone jack, so they are both outside my price range and unsuitable–at least for me—for listening to lossless quality audio. Still, I wanted “industry leading” active noise cancellation, something better than I already have in my fancy Beoplay H9, for the times that I need it.

I read a lot of ANC headphone reviews and came to the conclusion that most reviewers recommend the Sony WH-1000M4 for its sound, excellent noise cancellation, and price. At $300 (street price $279) they are not cheap, but one could buy them and the AirPods Pro for cheaper than the AirPods Max (at its list price). Also, compared to the AirPods Max, the Sony WH-1000M4 is lighter, folds into a small, protective case, and has a headphone jack for wired listening.

I received them and immediately discovered that I don’t love them. They are fine, but that is disappointing to me. Perhaps they are overhyped by reviewers. Perhaps I am asking too much from them. For whatever reason, I, unlike most people, I guess, think they fall short of greatness.

This is my list of complaints that should serve as a counterpoint to all the glowing, uncritical reviews.

  1. They sound good, but not great. The nearest analog to them that I own is another Bluetooth ANC headphone, the Beoplay H9, which sounds punchier, tighter, brighter, and more exciting than the Sony WH-1000M4. I have three non-Bluetooth headphones that sound better than both the Beoplay and the Sony, too1. I have tried to EQ the Sony via its iOS app, but I have found no preset that I constantly prefer.
  2. The active noise cancellation has an audible hiss and creates a bit of ear pressure. The hiss is disappointing. You don’t notice it during music, and probably won’t notice it in loud conditions where I would use these headphones, but it is annoying during podcasts or TV shows.
  3. Active noise cancellation does not live up to the hype. I actually use ANC headphones a lot in my home office because they remove the drone from the window air conditioner I use when it gets hot. Sadly, I found that the Sony WH-1000M4, with its industry-leading ANC, blocks that noise no better than the Beoplay H9, which is an also-ran in the ANC space and has essentially no passive noise cancellation in its earcup design.
  4. They aren’t that comfortable. My biggest problem with the BeoPlay H9 that I already had is its hard headband, which hurts my head after a while. The Sony headband does the same thing, despite the headphone being lighter and the headband being covered with softer material. The AirPods Max headband is very comfortable, but its clamping force borders on the extreme, so I probably would find it uncomfortable, too.
  5. While their moving parts are silent, the faux leather ear cups creak and squeak when I move my head. It is infuriating. I have no other headphones that do this.

I probably should have returned the Sony WH-1000M4 while I still had the chance. While I do expect to use them during walks on the treadmill and for plane travel in the future, I find that I almost always choose the Beoplay H9 over them for my everyday home-office-with-the-air-conditioner-on listening.


  1. I realize that part of my problem is that I have too many audiophile-quality headphones already. If I were comparing the Sony WH-1000M4 with my aging (non-Pro) AirPods, I would probably think they sound great. ↩︎

Thinking about my next role at work

I spent nearly all of my writing time this evening drafting a job description for the Senior Data Analytics Manager job I hope to be promoted to, sooner or later, at my firm. I feel good about what I wrote, which describes the specialist position that I have carved out for myself at my company, but I’m running it by a couple mentors for feedback anyway. I had a great year at work this past year, but promotion is by no means guaranteed. I am hopeful, though, that I will earn it soon.