Solving software problems the hard way

Many years ago, I wrote software for the federal government. Our application helped a couple of agencies produce the documents they send to the President and Congress to ask for money. I mean their official annual budget request, not like “Hey, Joe, you got five bucks on you?” I assume they did that in person. The basic process was our code produced some boilerplate, some tables based on numbers they uploaded, and then inserted text documents that they also uploaded. It then spit out a completed document. With modern technology, this would be pretty straightforward, but this was 2008 federal government tech, so it was held back by all sorts of things.

The code mostly worked fine without major changes EXCEPT for one thing. Treasury liked to change the table heading colors every year. This was a HUGE problem. At the time, we were using a very old document type called Rich Text Format. Maybe you are old enough to have seen an RTF file. It was made by Microsoft to be compatible with non-Microsoft Word programs. In hindsight this is sort of hilarious. To change the color on an RTF file, the code ripped the header off the file and inserted a new one. Then you ran the code and hoped that you did it right. Usually, you did not, so you tried again. It was an ENORMOUS amount of work for something that I thought should be trivial – there were all sorts of escape characters and weird abbreviations and none of it made any sense. It was sort of like HTML with a CSS file except where CSS is supposed to be simple and straightforward (Cascading Simple Straightforward, that’s CSS), this was the opposite.

So I thought, surely there is software out there that we can use to do this instead of rolling our own. And there was! We were a Java team, and at the time, Apache POI was what everyone in Java used to do text documents. I was excited! A polished open source program that was free to use! No more headaches!

And then there were headaches. You see, our Java code lived inside an Oracle database. And the Oracle database version we were stuck on only supported Java version 1.4. Apache POI required 1.5. There was no way I, a lowly software contractor, could get them to move to a newer Oracle version that would support 1.5.

So I did what any young software person in that situation would do – I wrote my own code to create and manipulate DOCX files. Do not attempt to read this code, you will cry, I promise. Interesting note – most (all?) Microsoft Office files (.docx and .xlsx for sure) are just a zipped folder of human-readable XML files. You can just unzip them and look at the files. During my time writing this code, I looked at those files A LOT. More than was healthy, probably. Much longer and I would have been able to open a Word document and see the XML, Matrix-style.

But in the end, it worked! You can see some of the documents my code produced if you look at the Congressional Justification and Budget in Brief at I don’t know how many years they used my code – I left the project in 2010 – but I’m sure they used it in 2008. I get a kick out of knowing that budgeting decisions were made in part using a document I coded.

Crash right in front of me – thankfully no one injured

I was in Annapolis to have lunch with my mom today and made a quick stop at the complex with the Best Buy on Generals Highway. As I was leaving, at the light to turn out, I noticed a car to my right waiting to turn left into the complex. I noticed the car was pretty far back – it’s a HUGE intersection, and I would have come towards the middle to make the left shorter.

As I sat there, she began to turn. Oncoming traffic still had a green, and an SUV with the right of way smashed into the turning car.

Everyone seemed to be ok – I called 911 and I commend Anne Arundel county for their responsiveness. I think a police officer was on site in 3 minutes and the ambulance in maybe 5. The SUV driver was pretty freaked out – I think she was driving with her mom and son, 3-ish years old. I don’t blame her for being freaked out. The other driver hadn’t gotten out of the car when I left but I overheard a woman who had spoken to her tell another witness that the woman was upset she’d have to tell her daughter she’d “gotten into another accident”.

It got me thinking a lot about how our car-dependent areas really hurt us as we age. This woman was coming from somewhere west of Annapolis, so no chance she could get anywhere without a car. My grandmother was like this – she never learned to drive, and it never mattered until they moved to the suburbs and then my grandfather passed away at 61 and she was stuck in that house until someone came and picked her up.

The woman in this crash today probably shouldn’t be driving anymore, but how are you going to tell her that when that’s her only way out of the house?

Parenting perks – trolling your kids

Parenting is hard sometimes. Kids are THE WORST. They’re always there, wanting things, complaining, making messes.

But they’re also great. And one of the side benefits of them getting older is you can troll them to great effect. My younger one has a stack of Principal’s List awards on the dining room table. I’m not sure 1) why she has so many or 2) why they are in a pile on the table. But my wife was teasing her about it and about how they seem to keep multiplying. Of course, this is a GOOD thing, as being on the Principal’s List is a nice achievement and we are of course happy that she is doing well in school.

So I had to take it a step further. When she was at school one day, I scanned one of the papers, put some new dates on, and printed out copies. I taped one to her bedroom door and put one under her pillow. And I added two to the stack on the table. And, my favorite, I mailed one to her. It’ll probably arrive tomorrow after she’s mostly forgotten the first batch.

Boycott Bike to Work Day 2025

The main Bike to Work Day (BTWD) pit stop in DC, Franklin Park, is not served by any bike infrastructure of any kind. Unless and until this is remedied, all cyclists and all vendors should avoid this pit stop completely.

This was my 12th BTWD. Ok, 11th if you don’t count Boat to Work Day where it rained so much they had to park a Circulator Bus at Freedom Plaza to give out t-shirts.

I ride a few thousand miles a year, mostly in DC. I’m okay riding in traffic. But the point of BTWD is not to get cyclists like me a new cheap t-shirt and a water bottle with some vendor name on it. The point is to show regular people that they can bike to work. It’s lunacy to expect inexperienced or hesitant cyclists to brave lower 14th St NW. I certainly wouldn’t send my friends and family there.

I can’t imagine sending someone to that stop who wasn’t already an experienced city cyclist. And not all stops are like this. The main Virginia stop at Rosslyn is well-served by bike infrastructure (and the Intersection of Doom is better-ish, I haven’t been nearly killed there in years). The old spot at Freedom Plaza in DC shows off the lanes on 15th St NW and PA Ave NW (and to a lesser extent 11th NW, which is still WAY better than 14th NW).

But Franklin Park has none of this. The lanes on 13th NW and 14th NW end before the park. I St and K St are absolutely not bikeable for an inexperienced cyclist. And you can’t even bike on the sidewalk (legally) because it’s in the weird CBD trapezoid.

We need to demand better.

Before LLMs were cool

Back in 2015 I wrote a Tumblr to try to earn commissions on wine sales on Amazon. That was a thing you could do then, in 2015. I guess I should say “wrote” because the only thing I wrote was code. I certainly didn’t write the wine reviews.

What I did, before anyone had ever said “Language Learning Model” (ok maybe some nerds had said it, whatever), was download the text of about 800 Wine Spectator “Daily Picks”. This was pretty easy because they used integers as keys in their URL so you could just go to /page/1 then page/2, etc etc, and Beautiful Soup just dumped the words into a text file.

I fed this download into markovify, a Markov chain generator written in Python. Someone may come “well, actually” me on this but Markov chains are essentially early LLMs that could run on your basic laptop in 2015.

Then I wrote a script that took a referral link to an Amazon wine and spat out a review and (and this might be my favorite part) a rating that was a random number between 77 and 94.

It then posted these reviews to Tumblr. They’re still there, you can go see them in all their glory. The name, Andrey Wines, sounds like a fancy winery, right? I would totally buy a nice cab from them. It’s named for Andrey Markov, who invented the Markov chain. I thought that was SO clever.

I mean look at that (click the image for the post, I’m not sure how to do alt-text on WordPress. I should figure that out). It had no idea the difference between a red and a white and I didn’t try to explain.

I giggle to myself knowing that OpenAI paid Tumblr to let them train their AI on Tumblr posts, and some of those posts are going to be this.

Cross Site Scripting is not the same as CSS

In my previous life as a coder, I worked for a while in the DHS Office of the CIO with the accountants. We wrote and managed a website to let the DHS components (Secret Service, CBP, etc) submit their monthly accounting files.

First, some background on building websites. Skip this if you’ve ever built a website. To build a page, all you need is HTML. Think of it like your docx file – your word processor reads a docx file and shows you a pretty document. Your web browser reads an html file and shows you a pretty web page. This is a massive oversimplification but we’re moving on.

One optional thing you can have in your HTML file is CSS. You know how links in pages are blue and underlined most of the time? Let’s say you want them all to be orange. You can add CSS to your HTML page that says “make all the links orange”. It uses different syntax but that’s not important. Now your browser knows to make all the links orange.

Nearly every website you have ever visited uses CSS to make things look pretty. It’s like how nearly every car you’ve ever seen uses paint. It’s POSSIBLE to have a car without paint, but it looks dumb and breaks if it goes through a carwash.

Tesla Cybertruck
A bug stupid truck with no paint

So there’s something else called Cross Site Scripting. This is bad. It’s complicated if you don’t understand it already but all you need to know is that this is one method people use to try and steal your credit card or whatever.

You’ll note that Cross Site Scripting could also be written as CSS. To keep people from getting confused, we use XSS for Cross Site Scripting.

Except DHS IT Security. They use CSS for both, and ban both from all DHS computer systems. Or they did in 2012, I haven’t worked there in a while. But know that this was at least as stupid then as it is now, it’s not a new thing. You would think the agency tasked with protecting US computer systems, among other things, would be knowledgeable about those computer systems.

Parrot social media

Because I need something right now that isn’t irritating, let me share with you that parrots like to video chat with other parrots, and even prefer it to simply watching videos of other parrots.

“The appearance of ‘liveness’ really did seem to make a difference to the parrots’ engagement with their screens,” said Dr. Ilyena Hirskyj-Douglas, though noting that further study would be needed before definite conclusions can be drawn. “Their behavior while interacting with another live bird often reflected behaviors they would engage in with other parrots in real life, which wasn’t the case in the pre-recorded sessions.”

We already have our tvs, our dishwashers, lightbulbs, doorknobs, whatever, everything is connected to the internet. Why not our parrots?

Secure DMs on ActivityPub

I’ve been up and down on ActivityPub – the concept is fantastic, I’ve been wanting something like this for decades. You’d just have this online identity and you could use it to blog or post pictures or do whatever across any platform that supported the protocol – it’s like far-future magic.

But federation is HARD. You can’t just click a button and have a federating website. And there are scalability issues – for example, if you run a small Mastodon server, and some of your users follow high volume accounts, it gets to be a lot on your server. There are ways to deal with this but they’re not as robust or easy as one might like (though I expect them to get there).

As the protocol develops and as more people start building stuff with it, I’m getting more and more optimistic.

And I’ve just heard there are multiple independent projects working on secure messaging. My immediate family uses WhatsApp a lot, which is lovely to use but comes with a lot of baggage. It’s particularly nice because it sidesteps the Apple/Google war of incompatibility and lets you send high quality images and video even if your recipient uses a different phone OS. And Signal is nice but I’ve had no luck getting anyone in my family to use it.

If we can get secure DMs on ActivityPub, that might be an easier pill to swallow. I’m particularly interested in Sup from Daniel Supernault, who built Pixelfed, because Pixelfed is a pleasure to use and I suspect Sup will be as well.

Riding the bus

It was warm out today, one of the first really warm days we’ve had this summer. I was walking up 14th St NW and noticed a vehicle in the bus lane.

“I think I’ll take the bus the rest of the way’, I thought.

I got into the vehicle and greeted the driver politely. The air conditioning was a great relief. I didn’t see a place to tap my Metro card but maybe the reader was broken.

“What the [EXPLETIVE DELETED] are you doing in my car?” The driver said, rudely.

“Oh!” I exclaimed. “I think you’re mistaken. See the red paint underneath us? This is a bus lane, so this must be the bus.”

Am I the only one who regularly fantasizes about this? It’s normal, right?

Spam problems

I’m having a little trouble with spam comments. Not that they’re getting through, but that the plugin I was using was ALSO blocking replies to posts through ActivityPub. They only take support requests if you have accounts at various forums and I’m kinda grumpy today and that was a bridge too far.