blog

Tiny Awards


🔗 a linked post to tinyawards.net » — originally shared here on

Last year, we decided to launch Tiny Awards, a small prize to celebrate interesting, small, craft-y internet projects and spaces which basically make the web a more fun place to be.

We hoped it would be a small contribution to celebrating ‘people making stuff on the internet for the fun of it and the love of it and the hell of it’. We were thrilled to see that people seemed to like the idea, so we’re doing it again in 2024 - still tiny, still celebratory, and still (hopefully) helping spread the word about some of the small, personal, whimsical, weird and poetic things people are making on what is left of the web.

Woohoo! Can’t wait to see the shortlist published on July 19th.

Continue to the full article


Some small tweaks to this site

originally shared here on

It's been a while since I used my own website as much as I did during this year's WeblogPoMo. The daily posting routine revealed some small annoyances which made visiting this site a little less fun.

For starters, I haven't redesigned this site since I got COVID back in 2021. 13 year old Tim would have been mortified at how long we've gone without a big redesign.

That's not to say I didn't try! I experimented with (and coded out) nearly a dozen different potential layouts.

The one I had the most fun with was a 90s Memphis style layout where the background elements were independent SVGs that were subtly animated.1

The problem I'm realizing2 is that I'm not a particularly skilled designer. I know what good design feels like, but I haven't taken the time to articulate what good design feels like.

The other problem? Building websites isn't fun for me anymore.

The tools you use to build websites are all essentially the same. There is functionally zero difference between a monolith Rails app running Postgres, a monolith Laravel app running MySQL, a static site generator powered by a Rube Goldberg-ian series of GitHub actions, or a GraphQL-powered React app.

The biggest casualty of choosing to build software professionally is my desire to learn new web technologies.

Instead of forcing myself to sit down and spoon-feed myself a puree in the form of a Next.JS tutorial, I'm leaning into other areas that interest me more.

Offline, that includes fixing up my house and lawn, writing, and being a better parent/husband.

Online, that includes playing with generative AI and sharing more of my thoughts on this blog and in my newsletter.

But even while I'm exploring other interests, that doesn't mean I can just let this site deteriorate and fill up with prickly weeds.

So over the last couple days, I made a couple small changes to this page that subtly improve the user experience. Most of these changes come in the form of discoverability.

When I launched this version of my site, I decided to lean into the linked list style of posting.

This was a great move because it's allowed me to (1) share interesting webpages with y'all, but also (2) make an archive of thoughts and ideas that inspire me.

Earlier this year, I added tags to all my posts. That process is what first made me realize that once I posted something on this site, it was next to impossible to find it again without jumping into a Rails console and searching for it.

Now that all of my posts have tags, I wanted a way to better visualize what topics I tended to think about and navigate through them.

If you visit the main page of this blog, you'll see a section at the top that explains what I tend to write about along with some groups of tags.3

I also made some slight CSS tweaks so the site looks even better on mobile.4

The main page is another source of stress for me over the past couple years.

As previously mentioned, my blog is mostly linked posts, but I do occasionally post longer essays and these shorter posts.

My main page had two separate sections to display my longer posts and my recent links, but these sorts of posts vanished into the ether.

My solution was to display a stream of all the posts along with their tags and an indication if it's a link post.

Like I said: these are small tweaks.

But small tweaks are sometimes all you need. It's important to maintain our virtual spaces.

Just because I'm not inspired to build new websites doesn't relieve me from the obligation to keep it functioning the best I possibly can.

And a positive consequence of these changes? You can expect more shorter posts from me like these!


  1. The problem I ran into was how inefficient these animations were. One of my main goals with this site is to be as energy efficient as possible. I should probably get off Rails and switch to a static site generator to be even more efficient, but this is good enough for now. And I at least didn't make it worse by deploying a big energy vampire that just made some squiggly lines wiggle up and down.  

  2. Maybe "realized" is the wrong word, because I've known I'm a mediocre designer for the past 20 years. "Accepted" is probably more accurate. 

  3. It was a fun exercise to print out the list of 448 tags and pick out the key ones. 

  4. For some reason, I didn't realize that if you have a parent element that honors the dimensions of the screen, but then you have a child element with a max-width tag set that's bigger than that, mobile Safari will just stretch the content of that child beyond the bounds of the parent, causing it to cut off the content on the sides. That is a đŸ’© experience. 


A Link Blog in the Year 2024


🔗 a linked post to laughingmeme.org » — originally shared here on

Like many people I’ve been dealing with the collapses of the various systems I relied on for information over the previous decades. After 17 of using Twitter daily and 24 years of using Google daily neither really works anymore. And particular with the collapse of the social spaces many of us grew up with, I feel called back to earlier forms of the Internet, like blogs, and in particular, starting a link blog.

One of us! One of us!

This isn’t a lengthy post, but I damn near quoted the whole thing because Kellan makes great points about the state of information sharing, the collapse of the Web 2.0 social infrastructure we all used for twenty years, and lamenting the fact he doesn’t really consume media from a wide variety of sources (me too, friend).

If you’re reading my link blog here, consider starting one of your own. Make it low effort for yourself, but just start one and stick to it for a month.

I think you’ll find your media consumption habits begin to trend toward higher quality sources of information/entertainment.

Continue to the full article


Defensive and Skeptical


🔗 a linked post to david-smith.org » — originally shared here on

Where I have settled in my own work is to strive to keep some meaningful part of my mindset hungry and foolish. To continue to be open to new opportunities and eager to explore them. I don’t want to end up miserly defending what I have already achieved, I want a professional life still rich with tackling interesting problems.

Continue to the full article


ChatGPT is really bad at generating code to interact with GPT-4

originally shared here on

Lately, I've been working on several projects which interface with the OpenAI APIs.

Since this is 2024 and I'm far too lazy to open the official API documentation and write code myself, my first step in generating code is to ask the 4o model of ChatGPT something like this:

Write a Python script which uses the latest OpenAI APIs. I'd like the function to accept a custom prompt and a custom top-k value. It should return the prompt's response.

It returns something like this:

import openai

def generate_text(prompt, top_k=5):
    # Define your OpenAI API key here
    openai.api_key = 'your-api-key'

    # Define parameters for the completion
    completion = openai.Completion.create(
        engine="text-davinci-003",
        prompt=prompt,
        max_tokens=100,
        top_k=top_k,
        n=1,
        stop=None
    )

    # Return the generated text
    return completion.choices[0].text.strip()

# Example usage
prompt = "Once upon a time"
top_k = 10
generated_text = generate_text(prompt, top_k)
print("Generated Text:", generated_text)

Which looks super great, right?

Except when you go to run it in a terminal, you get this:

openai.lib._old_api.APIRemovedInV1: 

You tried to access openai.Completion, but this is no longer supported in openai>=1.0.0 - see the README at https://github.com/openai/openai-python for the API.

You can run `openai migrate` to automatically upgrade your codebase to use the 1.0.0 interface. 

Alternatively, you can pin your installation to the old version, e.g. `pip install openai==0.28`

A detailed migration guide is available here: https://github.com/openai/openai-python/discussions/742

If you paste that error into the chat, it'll respond with this:

It seems like there has been a major update in the OpenAI Python library since I last checked. Let me update the script to use the latest version of the library:

And then it spits this out:

import openai

def generate_text(prompt, top_k=5):
    # Define your OpenAI API key here
    openai.api_key = 'your-api-key'

    # Define parameters for the completion
    response = openai.Completion.create(
        engine="davinci-codex",
        prompt=prompt,
        max_tokens=100,
        top_k=top_k,
        n=1
    )

    # Return the generated text
    return response.choices[0].text.strip()

# Example usage
prompt = "Once upon a time"
top_k = 10
generated_text = generate_text(prompt, top_k)
print("Generated Text:", generated_text)

Notice how it still uses the openai.Completion method!

I've tried prompting it with something like:

You're still using the openai.Completion method. Reference the official up to date API documentation to get the latest call that replaces the openai.Completion method.

And it responds with:

Apologies for that oversight. Let me update the script to use the latest API method based on the official documentation:

And here's the code it generates:

import openai

def generate_text(prompt, top_k=5):
    # Define your OpenAI API key here
    openai.api_key = 'your-api-key'

    # Define parameters for the completion
    response = openai.Completion.create(
        engine="davinci-codex",
        prompt=prompt,
        max_tokens=100,
        top_k=top_k,
        n=1,
        temperature=0.7,
        stop=None
    )

    # Return the generated text
    return response.choices[0].text.strip()

# Example usage
prompt = "Once upon a time"
top_k = 10
generated_text = generate_text(prompt, top_k)
print("Generated Text:", generated_text)

Which, again, still uses the openai.Completion method!

I've noticed this sort of "oops, I screwed up, here's the exact same thing I just outputted" behavior appear more frequently when I use the new GPT-4o model.

If I use GPT-4 and I'm using my ChatGPT Plus subscription, I will still run into the issue where its first response references the deprecated method, but if I inform it of its mistake and provide a link to the official documentation, it'll access the web and try to offer something different. (It still generates unusable code lol but it's at least trying to do something different!)

When it comes to Python and Rails code, I'm seeing that the GPT-4o model is not as good at code generation as the previous GPT-4 model.

It feels like the model is always in a rush to generate something rather than taking its time and getting it correct.

It also seems to be biased toward relying on its training for supplying an answer rather than taking a peek at the internet for a better answer, even when you specifically tell it not to do that.

In many cases, this speed/accuracy tradeoff makes sense. But when it comes to code generation (and specifically when it tries to generate code to use their own APIs), I wish it took its time to reason why the code it wrote doesn't work.


You should write more


🔗 a linked post to lcamtuf.substack.com » — originally shared here on

If you’re a painter, you’re still allowed to paint landscapes. Singers are still allowed to sing about love. And heck — I’m betting the first time your critic learned about this particular topic, he wasn’t standing atop Mount Sinai. Knowledge transfer is a vital human activity, and it’s all about synthesizing, refining, and incrementally expanding on what’s been said before.

Here’s a short list of posts I’ve been wanting to write but have chickened out every time I start a draft:

  • How I’ve organized my Plex music library
  • How to pick the perfect karaoke song
  • Ways you can move out of the corporate world and into the startup world
  • Why I stopped reading the news and quit social media
  • How to avoid clickbait articles

Maybe I should force myself to write one of these and publish it with little self-editing.

I made a concerted effort to write more this year. I’ve journaled roughly 98% of the days this year, and I’ve published something on this blog just as much. I even started a newsletter.

I’ve learned a lot about myself thanks to all of this writing. I didn’t realize how much a daily blogging challenge would reveal about my musical tastes. I wouldn’t have been able to identify my feelings without yelling at a journal until my voice became hoarse.

Best of all, writing is proving to be an effective way for me to share what I’ve learned with others. Feeling useful helps beat back the depression demons.

I encourage anyone reading this to write down whatever you’ve been interested in lately and post it somewhere. Share it with me so I can learn with you!

Continue to the full article


CFO Of The Epoch Times Charged With Participating In Scheme To Launder At Least $67 Million In Fraud Proceeds


🔗 a linked post to justice.gov » — originally shared here on

As alleged, Bill Guan, the Chief Financial Officer of a global newspaper and media company, conspired with others to benefit himself, the media company, and its affiliates by laundering tens of millions of dollars in fraudulently obtained unemployment insurance benefits and other crime proceeds.  When banks raised questions about the funds, Guan allegedly lied repeatedly and falsely claimed that the funds came from legitimate donations to the media company.

Since graduating with a journalism degree nearly 15 years ago, I’ve worked on honing my internal bias detector.

One thing I've come to accept is that there is no such thing as a completely neutral news outlet. Every publication is biased in some way because every media outlet is run by people.

The good media outlets are those that try to set up guardrails to counter the natural biases that reporters may bring into a story.

Those guardrails include things like publishing retractions to erroneous statements, checking the credentials of those who give statements, and avoiding the use of anonymous sources.

The bad media outlets do none of those things. They take up the mantle of the demagogue who constantly claims everything is “fake news”, and they publish anything which corroborates the demagogue's story rather than doing actual journalism work.

I'm not mad at people for getting suckered into reading The Epoch Times. I understand that when your worldview is built up around a narrative, you do whatever you can to validate it. Challenging your core identities is painful1; it's more comforting to find news that parrots back your beliefs, even if it's wrong.

So while I understand the human instincts at work, I'm furious at those who choose to exploit those instincts.

And of course The Epoch Times attracted the kind of person who would allegedly attempt a $63 million money laundering scheme2.

The internet enables all kinds of speech to propagate at incredible speed. We need to all be better about honing our internal bias detectors and find ways to help each other not get suckered in by those who would try to harm us with blatant lies.


  1. Just look at my last six months of posts if you wanna see how much it sucks to address the identities you have embraced your whole life that are no longer yours lol 

  2. Allegedly. Journalism training taught me to always preface these allegations with that phrase because we live in a country where you are innocent until proven guilty. 

Continue to the full article


The Painful, Depressing Reality of Why Congress Is So Dysfunctional


🔗 a linked post to politico.com » — originally shared here on

At the heart of today’s dysfunction in Congress — the serial ousting of speakers, the perpetual threat of government shutdowns, the inability to address pressing issues like immigration, runaway deficits or climate change — lie three political fantasies. These illusions warp the perceptions, cloud the judgment and misdirect the energies of House and Senate members of both parties. Letting go of them will be the necessary first step to restoring a functioning legislature to a country that desperately needs one.

This felt like a great summary of why we have such dysfunction within our legislative bodies.

What it doesn’t do, unfortunately, is give much of a path towards resolving this dysfunction.

Continue to the full article


WeblogPoMo 2024 - Song 18: Neutral Milk Hotel - In the Aeroplane Over the Sea


🔗 a linked post to m.youtube.com » — originally shared here on

When I started this WeblogPoMo series, I knew I'd eventually need to write about Neutral Milk Hotel.

I kept putting it off because it's always been tough to put into words what this band means to me.

I mentioned in my POTUSA post that we used to go to Duluth every summer as a family.

When you visit a place every year, you start to develop routines and habits. My habit was to stop into the Electric Fetus.

Over the years, I acquired most of my CD collection from the Fetus. Highlights included The Unicorn's Who Will Cut Our Hair When We're Gone?, Death Cab for Cutie's Transatlanticism, Ambulance Ltd's 2004 LP, and, of course, In The Aeroplane Over The Sea.

Back in my Rilo Kiley post, I mentioned how much it bothers me to answer the question "what is your favorite band."

If I were honest and not at all self conscious, I would have answered "Neutral Milk Hotel" from roughly eighth grade until my senior year of college.

Let's face it: the band is an odd choice for a favorite, no?

A lot of their songs explore heavy feelings and are, more often than not, pretty depressing. Their most famous album is about Anne Frank. Jeff Mangum's voice is simultaneously soothing and haunting, but unconventional and jarring the first time you hear it.

If this WeblogPoMo challenge has taught me anything, though, it's that it feels so much better to just like the things you like with a full throat. No point in whispering about the things that light you up, right?

When I got my first guitar in high school, the very first song I learned to play was "In The Aeroplane Over The Sea."1

It's a perfect song for a noob: G, Em, C, and D. Rinse and repeat.

I'd sit and strum those four chords in my basement for hours, belting out the lyrics with my best Jeff Mangum impression.

After figuring out "Aeroplane," I tried my hand at the other songs on the album. "The King of Carrot Flowers, Pt. 1" taught me my first barre chord (F). I even busted out my baritone to learn "The Fool."

Like I said, though, I was pretty guarded about my love for Neutral Milk Hotel growing up. I only shared it with folks who I could talk about deep things with.

I remember sitting in the back seat with my mom on a car ride back from Iowa. She asked me what I was listening to, and I showed her the album cover. She put my headphones in right as the first chord from "Communist Daughter" began.

She liked it up until he started singing about semen staining the mountain tops. 😬

This band got me through some of the hardest moments of my teenage years, and more than twenty years after that Electric Fetus shopping session, I find myself drawn to this album when I need to deal with my hardest crossroads.

Albums come and go from my music collection, but I wonder if I’ll ever be able to let go of this album.

It’s truly my most personally meaningful album.

I saw Jeff Mangum perform live a few years back. He took the stage and tears immediately started welling up in my eyes.

He sits down, politely and awkwardly waves at the crowd, picks up his guitar, and starts belting out “Two Headed Boy Pt. 2”.

His raw, haunting voice filled the music halls, powerfully belting out this beautiful song, sending chills up my spine.

At the end of this deeply moving performance, he casually plops his guitar down on his waist, looks up at the crowd, and says, “Thanks!” with the same gusto I use when I meet someone new at a professional networking event.

It made me laugh so hard.

“How strange it is to be anything at all,” indeed.

And for the record: when I die, nothing would honor me more than if someone sang “Aeroplane” at my grave side.


  1. I did learn "Horse With No Name" before "Aeroplane," but it's not a tough song to pick up. It's just an Em chord, and then you move your fingers from the second and third strings to the first and fourth strings. Going from Em to C for the first time was way more challenging. D to G was also really tough for me. 


WeblogPoMo 2024 - Song 17: Taylor Swift - Anti-Hero


🔗 a linked post to youtube.com » — originally shared here on

The story my daughter makes me tell the most is the time I asked Taylor Swift out on a date.

In 2008, my dad’s cousin was a truck driver for the Rascal Flatts tour. He asked if we’d like to go see the show and get some backstage passes.

Country music has never been my go-to genre, but I especially find pop country to be frustratingly formulaic and addresses a range of human experiences I don’t personally identify with.

But who am I to turn down an opportunity to go backstage and see how a major tour moves about the country?

My dad’s cousin took turns bringing my family backstage, and it was my turn just prior to the show starting.

We got to see where the trucks parked and the drivers napped while the show was being set up and torn down. My dad’s cousin’s cab looked particularly roomy and comfortable, not at all what I expected the inside of a 40 foot semi cab to look like.

We got to see the area where the video mixing guys did their thing. I remember being surprised because I know the audio mixing guys sit on the floor in order to get a better feel for how the audio plays in the given arena, but for video, I guess that doesn’t matter as much.

We made our way over to the area that led to the stage. It’s basically a bunch of curtains that make a tunnel. In pro wrestling terms, you might call this “gorilla position”, named after Gorilla Monsoon who you could find perched at that area during a show.

While standing there chatting with my dad’s cousin, a golf cart quickly pulls up, and off jumps Taylor Swift.

In 2008, Taylor was in her “pink sparkly guitar” era. She was amiable and full of energy.

She sees me and asks if I live around here. I say yes.

She asks me if I know who plays hockey in the Xcel Energy Center. I look around at the dozens of Wild logos and reply, “The Wild.”

She asks me if I know who they are playing that night. I happened to know they were playing the Chicago Blackhawks, so I reply, “The Blackhawks.”

She asks me if I know of a good place to grab a bite to eat around here.

I don’t know what came over me, but I decided to take a shot.

I responded: “Cossetta’s is right down the road and they’ve got amazing pizza. I’d be happy to take you there once you’re done with the show, if you’d like!”

She laughs politely, thanks me for my help, and disappears into the curtain tunnel.

She performs her first song and then addresses the crowd:

“Hello Saint Paul! How about those Wild? I hope they crush the Blackhawks tonight! Hey, is anyone gonna hit up Cossetta’s after the show for some pizza?”


I’m still not very interested in “You Belong With Me” and “Love Story”, but the last few years of Taylor’s evolution are compelling to me.

I will throw on Midnights and Folklore when I’m looking for some good background grooves.

The two Taylor songs that I have on my playlist1 are “Anti-Hero” and “the 1”.

“Anti-Hero” is so absurd that it cracks me up every time.

“The 1” is chock full of solid one-liners that layer on top of a general feeling of malaise. In other words, an accurate encapsulation of my internal dialogue.

I’m not a Swiftie, but I’m in an era where I’m working on countering my natural instinct to dump on any exceptionally popular pop icon without cause.

And while I might enjoy listening to some of Taylor Swift’s discography, I’m glad she shot me down.

She’s not even close to being on the same level as Shannon.


  1. Each of us have our own playlist in our family so we can shout “Hey Siri, play Daddy’s Music” and have our own jams play in the house.