Anyone who wants to start a barber or hair styling place, here’s a name for you: Hair Today, Gone Tomorrow.

Or, if you’re an Aussie: There Is Hair In There (And A Chair As Well)

πŸ”— I Fucking Hate Jira

Real opinions from real people about a project management system which unfortunately is also real.

Love the tag line of this site. Also, spoilers, but Confluence makes a warranted appearance here as well.

One day, Vivaldi’s going to release an upgrade that will fix whatever causes the browser to occasionally crash whenever I start to use the developer tools. Today is not that day.

Walking that fine line on my current work task between addressing the known flaws that may or may not crop up in production (they did crop up in testing) and spending an excessive amount of time gold-plating it unnecessarily. It’s hard sometimes to know when a task is truly finished.

Proposal for a new database maxim:

A query, originally written to find one row with a particular value, will eventually be rewritten to find multiple rows with a collection of values.

That is, if you had select * where id = ?, that query will eventually be rewritten to select * where id in (…).

πŸ‘¨β€πŸ’» A collection of new posts over at TIL Computer:

Swoop-o-meter now at 3 noisy miners. We’ve got confirmed head contact (head strike?). Luckily it was just a tap, but I may avoid going that way for my walk for a while. πŸ‘·β€β™‚οΈ

Select Fun From PostgreSQL

Using PostgreSQL these last few months reminds me of just how much fun it is to work with a relational database. DynamoDB is very capable, but I wouldn’t call it fun. It’s kinda boring, actually. Not that that’s a bad thing: one could argue that “boring” is what you want from a database.

Working with PostgreSQL, on the other hand, has been fun. There’s no better word to describe it. It’s been quite enjoyable designing new tables and writing SQL statements.

Not sure why this is, but I’m guessing it’s got something to do with working with a schema. It exercises the same sort of brain muscles1 as designing data structures or architecting an application. Much more interesting than dealing with a schemaless database, where someone could simply say “ah, just shove this object it a DynamoDB table.”

It’s either that, or just that PostgreSQL has a more powerful query language than what DynamoDB offers. I mean, DynamoDB’s query capabilities need to be pretty restricted, thanks to how it stores it’s data. That’s the price you pay for scale.


  1. My brain muscles couldn’t come up with a better term here. πŸ˜„ ↩︎

Working from home today as there’s a protest at the convention centre, disrupting traffic. Got me thinking of the last time I was at that convention centre. It was 5 years ago, almost to the day, when I attended a small dev. conference. I left early on the last day as I had to join a protest.

Swoop-o-meter now sits at 2 noisy miners. Also, wearing or not wearing a blue beanie makes no difference. No magpies yet. πŸ‘·β€β™‚οΈ

Wish I can use my new vacuum cleaner to suck up all the spam emails I’m getting about my new vacuum cleaner. πŸ˜•

This week’s earworm: The Wind Chimes by Mike Oldfield. 🎡

This one’s a bit surprising since it’s not a new addition to my collection. Maybe because I haven’t been listening to it all that often.

Album cover of Islands by Mike Oldfield, depicting an island on a dark-violet oceans with faint, artistic depiction of hands, with an orange sky

I didn’t record narration for the previous post. It featured a dialog and I needed a scene partner. So I tried recording one with AWS’s text-to-speech engine last night, and ah… yeah, it didn’t sound as good as I was hoping. I mean, the tech is getting better, but there’s still a way to go: that uncanny valley hasn’t been bridged yet.

This is probably the best version of what I was able to make. This was using AWS’s new-ish “Generative” voice model. There are only three voices available of this kind in AWS so far. I chose the US English male voice, since it spoke at a rate which, to my ears, is about as close to a speaking rate that I’d consider natural:

Transcript

I also tried the same exchange out with the “Neural” engine, which has been around for several years:

The Generative voice model is decent. Still not good enough to fool anyone that I’m speaking with a real person, yet it’s a lot better than the Neural engine. There’s no mistake with that one that I’m speaking with a computer.

So, no recorded dialogue, but it was still an interesting exercise. And it’s always a little fun playing around with AWS’s text-to-speech engine.

Rubberducking: Of Config And Databases

It’s been a while since my last rubber-ducking session. Not that I’m in the habit of seeking them out: I mainly haven’t been in a situation when I needed to do one. Well that chance came by yesterday, when I was wondering whether to put queue configuration either in the database as data, or in the environment as configuration.

This one’s relatively short, as I was leaning towards one method of the other before I started. But doubts remained, so having the session was still useful.

So without further ado, let’s dive in. Begin scene.

L: Hello

πŸ¦†: Oh, you’re back. It’s been a while. How did that thing with the authorisation go?

L: Yeah, good. Turns out doing that was a good idea.

πŸ¦†: Ah, glad to hear it. Anyway, how can I help you today?

L: Ok, so I’m working on this queue system that works with a database. I’ve got a single queue working quite well, but I want to extend it to something that works across multiple queues.

πŸ¦†: Okay

L: So I’m wondering where I could store the configuration to these queues. I’m thinking either in the database as data, or in the configuration. I’m thinking the database as: A) a reference to the queue needs to be stored alongside each item anyway, and B) if we wanted to add more queues, we can almost do so by simply adding rows.

πŸ¦†: “almost do so?”

L: Yeah, so this is where I’m a little unsure. See, I don’t want to spend a lot of effort building out the logic to deal with relaunching the queue dispatcher when the rows change. I rather the dispatcher just read how the queues are configured during startup and stick with that until the application is restarted.

πŸ¦†: Okay

L: And such an approach is closer to configuration. In fact, it could be argued that having the queues defined as configuration would be better, as adding additional queues could be an activity that is considered “intentional”, with a proper deployment and release process.

I wonder if a good middle-ground might be to have the queues defined in the database as rows, yet managed via the migration script. That way, we can have the best of both worlds.

πŸ¦†: Why not just go with configuration?

L: The main reason is that I don’t want to add something like string representations of the queue to each queue item. I’m okay if it was just a UUID, since I’d imagine PostgreSQL could handle such fields relatively efficiently. But adding queue names like “default” or “test” as a string on each queue item seems like a bit of a waste.

πŸ¦†: Do they need to be strings? Could the be like an enum?

L: I rather they’re strings, as I want this arrangement to be relatively flexible. You know, “policy vs. mechanism” and all that.

πŸ¦†: So how would this look in the database?

L: Well, each row for a queue would have a string, say like a queue name. But each individual queue item would reference the queue via it’s ID.

πŸ¦†: Okay, so it sounds like adding it to the database yet managing it with the migration script is the way to go.

L: Yeah, that is probably the best approach.

πŸ¦†: Good. I’m glad you can come away with thinking this.

L: Yeah, honestly that was the way I was leaning anyway. But I’m glad that I can completely dismiss the configuration approach now.

πŸ¦†: Okay, good. So I’m guessing my job is done here.

L: Yeah, thanks again.

πŸ¦†: No worries.

If all I was taught came from old DOS games, I’d probably come away thinking that archeology is the coolest job in the world. πŸ˜€

Have to remind myself that it’s better to build for the state of the world now, rather than for some future state that may never happen. That probably means you’ll need to change it later, when the future inevitably reveals itself. Just be prepared to do so, and don’t be so hard on your past self when you do.

Oof, left the house without my wallet. Good thing I set up Google Pay on my phone or I wouldn’t have been able to pay for my coffee.

Project Updates

Well, it’s been three weeks since my last post here, and as hard as it was to write this update, not writing it would’ve been harder. So let’s just skip the preamble and go straight to the update.

Cyber Burger (That Pico-8 Game)

I’m terrible at being coy, I’ll just spill the beens. That game I’ve been working on is call Cyber Burger. It’s based on a DOS game I saw on YouTube, and it seemed like a fun project to try and work on, with some tweaks to the gameplay that I think would make it more forgiving.

In the weeks since my last update, I finished with the prototypes and started working on the game itself. The initial set of art is done and a very simple “Game A” mode has been implemented. In this mode, you are shown a burger you’ll need to make in your basket. You do so by shooting down the items flying across the screen and catching them in order. When you do, you get a “tip”, which basically amounts to points. If you make a mistake, you’re given a demerit. There are five rounds in total, and once the round is complete, you move on to the next one, with maybe slightly different items, or different item speeds, etc.

An example play session, with the new graphics.

I managed to make a HTML version of this which plays through round 1. I gave it to someone at work to play test and the results were… well, they weren’t bad but it didn’t set the world on fire.

I think I’m okay with that, but I do need to keep working on it. I think one thing that would help is adding sound. And I think it might help me deliver this earlier if I abandoned Mode A and start working on Mode B, which is closer to an arcade style of game that would allow for continuous play. These two things, I’ll aim to work on this next week.

Oh, and I’ll need to fix the item spawner. Waiting ages for an item you need is no good.

If you’re interested in giving it a try, you can do so by following this link (it runs in the browser). Feel free to send any feedback you may have.

UCL

The other thing I’ve been spending some time on over the last week or so was UCL. I’ve been using that work tool which has this language quite often recently and I’ve been running against a number of bugs and areas where quality of life changes could be made. Just small things, such as allowing the foreach command to be called with a proc name instead of requiring a block, much like the map function. Those have been addressed.

But the biggest thing I’ve been worked on was building out the core library. I added the following functions:

  • The `seq` function, used for generating a sequence of integers. I like how I built this: it’s effectively a virtual list β€” that can be indexed, iterated over, or calculated the length of β€” but does not take up linear space.
  • Comparator functions, like `eq`, `ne`, `gt`, etc. plus settling on a type system much like Python, where values are strongly type (can’t compare ints to strings) but are also dynamic.
  • Arithmetic functions, like `add`, `sub`, etc. which operate on integers, and the `cat` function use to concatenate strings (these functions do try to cohere values to the correct type)
  • Logical functions, like `and`, `or`, and `not`.

Along with this, I’ve started working through the strings package, which would add the various string functions you see, like trimming whitespace, splitting, joining, etc. I’ve got trimming and converting to upper and lower case, and my goal for next week is to add splitting to and joining from string lists. Once that’s done I’ll probably put this on the back-burner again so I can finish off Cyber Burger or work on something else.

Just a reminder that there’s also a playground for this too, although I apologise for the lack of documentation. I’ll need to get onto that as well.

Finished reading: Hell Yeah Or No by Derek Sivers.

A good book. I resisted reading it for a while (I’m not sure I was ready to hear what it had to say) but I bought this Friday, hoping that it would help me work through an important decision, and I think it did. πŸ“š

My regular cafe no longer opens on Sunday. Most of the other cafes close to me open at 8:00. There’s one that opens at 7:00 but it takes a 30 minute walk to get there. I went to that one today, and despite the walk, I arrived home earlier than I would have if I waited for the other ones to open.