Author: Jud

Technologist interested in building both systems and organizations that are secure, scaleable, cost-effective, and most of all, good for humanity.
Where My Mouth Is

Where My Mouth Is

As I get older, the more I’ve reflected on ways I can give back to organizations and communities that have had a big influence in my life. It’s why I contribute to open source projects. It’s why I respond to Stack Overflow posts (or at least try to periodically). And it’s why I give to the Wikimedia Foundation.

Despite it’s quirks and occasional inaccuracies, Wikipedia is a modern miracle of information that has shaped countless lives in inestimable ways. I find their mission statement a beautiful ideal: “a world in which every single human being can freely share in the sum of all knowledge.” Knowledge isn’t everything, but it’s a significant something; a necessary ingredient to human flourishing. And I’m happy to do my part to increase its presence in the world.

Home Cooking

Home Cooking

Decent lighting is essential when wanting to exude professionalism in a video call. But sometimes you either don’t have equipment at hand or don’t want to mess with it. As a stopgap, I’ve discovered that if I open up a few browser windows with light backgrounds they can help illuminate my face, but the results are a bit bluer than I’d otherwise prefer.

It got me thinking if I could build a simple website that would be nothing but an adjustable color background. Behold, the webcam light tool. Not only is the color adjustable via HSL (hue, saturation, lightness) sliders, there’s also a slider in Kelvin if you want to pick a color temperature instead. Color values are saved to browser local storage and remembered on subsequent visits, and automatically synchronize in real-time if you open multiple windows.

With a pair of tall and narrow windows, one on either edge of my ultrawide monitor, the results are pretty good. Chalk one up for creative solutions!

On The Turning Away

On The Turning Away

I write this blog post sitting in my favorite coffee shop having begun yesterday a nearly three week micro-sabbatical. Not since I was laid off in early 2019 have I taken more than a few days of time off that didn’t involve travel or other busy-ness. I’m looking forward to spending some time relaxing, some time away from technology, and some time purposefully pursuing activities I haven’t had time to otherwise accomplish.

What sorts of activities? Well, for one I want to publish a new CDK construct, which I’ll talk about here once it’s published. Another is recording a podcast, which I’m happy to announce now has a brief trailer. Mostly it’s going to be similar to material covered on this blog, but perhaps with some conversations also. I’ve no idea if I’ll be able to keep it up, but I’m starting nonetheless.

I’ll also be reading quite a bit. Finished a book this morning, and started a second, the appropriately titled How To Do Nothing.

Finally, I’ll be drinking copious flat whites with the above view from my corner table. Life is good.

A Helpful Transmogrifier

A Helpful Transmogrifier

Have a large CSV file and want a quick way to query it? Consider transforming it into a SQLite database. It’s easy! One command will do it:

$ sqlite3 "$sqlite_filename" ".import $csv_filename $table_name --csv"

Here’s a concrete example using airtravel.csv:

$ sqlite3 air.db ".import airtravel.csv air --csv"
$ sqlite3 air.db "SELECT * FROM air WHERE air.Month = 'JAN'"
JAN|  340|  360|  417

Neato! Admittedly the handling of headers and column names isn’t great, but that can be solved with a bit more script-fu (which I’ll leave as an exercise for the reader).

Sean Maguire Was Right

Sean Maguire Was Right

Don Norman came to mind today, a not uncommon occurrance. I’ve mentioned him before, but not loudly enough. If you care at all about building great solutions, technical or otherwise, reading The Design of Everyday Things is a must. Here’s my favorite passage:

The idea that a person is at fault when something goes wrong is deeply entrenched in society. That’s why we blame others and even ourselves. Unfortunately, the idea that a person is at fault is imbedded in the legal system. When major accidents occur, official courts of inquiry are set up to assess the blame. More and more often the blame is attributed to “human error.” The person involved can be fined, punished, or fired. Maybe training procedures are revised. The law rests comfortably. But in my experience, human error usually is a result of poor design: it should be called system error. Humans err continually; it is an intrinsic part of our nature. System design should take this into account. Pinning the blame on the person may be a comfortable way to proceed, but why was the system ever designed so that a single act by a single person could cause calamity? Worse, blaming the person without fixing the root, underlying cause does not fix the problem: the same error is likely to be repeated by someone else.

The notion of system error is quite profound, applicable to technology, organizations, governments, even entire civilizations. Leaders of all stripes do well to consider its explanatory power.

Just discovered that Don has a new book coming next month: Design For a Better World. Pre-ordered!

The Tie That Binds

The Tie That Binds

Read these two articles yesterday. On the surface they’re about different topics, but there’s a common thread: both call out an aspect of technical work that is often ignored, especially by the less-experienced.

The first tale, Our Company Fired the Best Developer and Project Manager, reminds us that “Getting your tasks done is half of the job. The other half is how you do it.” I’d go even further and say getting your tasks done is only a quarter of your job. The rest is how you do them, when you do them by, and most importantly, ensuring you understand why those are your tasks in the first place, and if perhaps you should be doing other tasks instead. Don’t climb the ladder only to find you leaned it against the wrong wall.

Coding Won’t Exist In 5 Years is yet another ChatGPT article, whose crux is the following: “Programming is the process of solving problems using a computer. Writing code is just one aspect of this process. It’s a necessary part, but it’s not the whole picture.” Yes, learn to write code well, but be aware you’re more valuable as an editor than as a drafter, and that’s only going to get more true as AI gets better.

That Last 20%

That Last 20%

I got an email this morning from a reader who asked if I had an email subscription feature on this blog. I didn’t then, but now I do! Want my writing to hit your inbox the moment I publish? Just add your email address into the widget at the top of the sidebar and hit subscribe. Easy!

You know what wasn’t easy? Trying to get that widget to match the rest of the site. At first it looked like this:

Gross. Luckily WordPress supports adding custom CSS. Unluckily, that means I had to fiddle with CSS, which is a special form of hell. I couldn’t get it perfect on all browsers, but it’s not bad now:

While I was at it, I made a few other visual tweaks to the site, primarily shrinking the masthead height, which has always bugged me. Here’s the final code snippet. Not the prettiest, especially with all those !important keywords (generally they’re a smell that your CSS is too complex), but it gets the job done.

.navbar {
    display: none;
}

.site-header {
    height: 300px;
    min-height: 300px;
}

.site-title::after {
    margin-top: 0.5em !important;
    margin: auto;
}

button.wp-block-button__link {
    height: 34px !important;
    margin-left: 0px !important;
    padding: 0px 5px !important;
    background: #fab526;
    font-weight: bold;
}

input#subscribe-field-1 {
    padding: 5px !important;
    border-bottom: 2px solid #ddd !important;
}

.search-field::placeholder {
    color: #B9B9B9;
}

If you happen to notice any weirdness on your device/browser of choice, do let me know, eh?

No Easy Answers

No Easy Answers

I’ve been managing technical people for a while now, but when it comes to asking good questions and listening well, I’m always learning. One thing I’ve discovered is that questions needn’t be complex to be effective. Here’s three I use regularly:

How do you feel about that?

Giving someone space to express their emotions is usually a good place to start when beginning a conversation. This is doubly true in the workplace, where there’s a misperception that feelings have no place. But we’re all human, and our effectiveness is predicated on aligning our emotions to the task at hand.

What could you do about that?

Once a person feels safe describing how they feel about a situation, it’s time to explore options for how to move forward. The word could here is critical, it’s a word about possibilities. Usually with just a little nudge, people will be able to come up with a variety of potential solutions on their own.

What do you want to do about that?

Too often people are asked to consider all sorts of factors when weighing options, but never their own desires. And especially not just surface desires, but what they truly want based on their own complex (and often competing and contradictory) web of values. It’s a powerful question; simple to ask, but hard to answer truthfully. Though once it is, I’ve found one often has all the data at hand to make a high quality decision.

Irreduceable Complexity

Irreduceable Complexity

“Make everything as simple as possible, but not simpler.” – Albert Einstein

In any technical discussion, beware when someone says something is simple. Things are rarely as simple as their marketing materials claim, and there is a vast gulf between a quickly-constructed proof of concept and a production-ready solution.

Even concepts that might seem straightforward at first glance have considerable potential for edge cases and other gotchas. Consider the following as canonical examples:

A corollary to the above: there is no such thing as a “5 minute task” in technology. When you hear such a claim, mentally multiply by 10.

Jud Flow

Jud Flow

Keeping a nice and tidy code repository makes me happy. Here’s the typical process I use to avoid messes:

  1. Create my-sweet-new-feature branch from main
  2. Make some awesome code edits, then commit them
  3. Make some slightly less awesome edits, commit them also
  4. Run some tests, nothing works; debug and commit the fix
  5. Decide my originally awesome code isn’t so awesome; rewrite the whole feature and commit
  6. Tests pass locally, yay! Push my-sweet-new-feature to Github and create a pull request
  7. Hrm, tests fail in pipeline; whoops, forgot a file; commit and repush
  8. Okay, tests pass now, so message team for review
  9. That’s a reasonable request, change made and committed
  10. Fine, we’ll use your naming convention; change made and committed
  11. Ugh, made a spelling error; committed
  12. Fixed moar typos
  13. Uggggggh, one last commit to fix spacing; pushed to Github
  14. Wha? Tests failing? :facepalm: forgot a file again
  15. Commit that file and push one last time for realz
  16. Tests pass, team reviews and approves, we’re good to go
  17. Pull an update of the main branch
  18. Come back to my-sweet-new-feature and rewrite all the commits on top of updated main; group edits into a clean subset of logical changes, one per commit, that makes it look like I wrote the code perfectly the first time, with nicely crafted commit messages that will mean something to some poor future developer that has to maintain my code ten years from now
  19. Run tests to ensure everything still passes; it does
  20. Force push to the pull request, obliterating all those ugly prior commits with these nice clean ones
  21. Try to merge the branch to main with fast-forward only option, forget that Github doesn’t support it (curse you Github! even flipping CodeCommit supports fast-forward only merging)
  22. Fast-forward merge my-sweet-new-feature to main locally so my final commit signatures are preserved
  23. Try to push main to Github, but it fails because the branch is protected
  24. Unprotect main temporarily, repush
  25. Dang it, someone merged new changes since step 17; repull main and rebase my branch
  26. Re-push my final changes and re-protect main

See how easy that is? No excuses moving forward, my friends!