Stavros' Stuff

On programming and other things.

Compressing images with Stable Diffusion

You get the gist

Images are just too big. A 3 MB bitmap compresses down to a 500 KB JPEG, which, don’t get me wrong, 16% of the original size is great, but why 500 KB? That’s still pretty large.

This is 2022, we shouldn’t have to put up with large images. Our websites might load 60 MB of stuff for a pageview, but that stuff shouldn’t be images, it should be Javascript, as Brendan Eich intended.

We shouldn’t have to put up with fat images, but, until now, we had no choice.

Now we do.

Continue reading…

Poop analytics

The poop analytics I've always wanted

As you may remember from a previous post, I have a blind cat whom I made some eyes for (which, incidentally, were a great success). One of the perennial and enduring problems every couple faces when they have a cat is how to divide the poop scooping. At least, that’s what I imagine, extrapolating from a sample size of 1.

Over the years, I have tried to come up with various equitable solutions that would be fair to both me and my partner. A few days after implementing the first solution, “just leave poop where it is”, we realized that we needed to add “be fair to the cat too” to the above equation, and I went back to the drawing board.

In this post, I will guide you through the various solutions

Continue reading…

Better communication with other drivers

Expressive, soulful communication

You know the problem: You’re driving through winding city streets, minding your own business, immersed in your thoughts about the kind of poor road planning that leads to a city having winding streets. Suddenly, what you can only assume is an inconsiderate, egotistic driver who revels in causing mild annoyance to everyone around them rudely cuts you off.

What can you do?

Pretty much the only recourse is available to you is to honk your horn at him, hoping he gets the exact meaning behind your honks. This, however, has always struck me as a crude and uncouth instrument. My elaborate, intricate feelings towards which exact plague should befall him are too nuanced for a simple horn to express.

I needed something more. Something succinct, yet expressive. Something complex, yet simple. Something unique, yet recognizable.

Luckily, someone solved the problem long before me:

Continue reading…

Making an AI-generated sleep podcast

Falling asleep is more fun with an AI in your ear

When I was a teenager, I had a CD player in my room, and I used to listen to fairy tales to fall asleep. The narrator’s voice would relax me and I’d fall asleep quickly. Fast forward to yesterday, I was playing with Google Text-To-Speech for an unrelated project, and had gotten one of their code samples to generate some speech for me. I had also played around with OpenAI’s GPT-3, which I had found wonderfully surrealist, and it had stuck in my mind, so I thought I should combine the two and create a podcast of nonsensical stories that you could listen to to help you fall asleep more easily.

Having already played with Google’s speech synthesis, I thought it would be pretty quick and easy to create this, as all I’d have to do is generate some text with GPT-3 and have Google speak it. GPT-3 is an AI model that can generate very convincing text from a sample. You basically give it a topic and a few sentences, and it continues in the same vein, writing very natural-sounding prose. Half an hour later, I had an AI-generated logo, AI-generated soundscapy background music, an AI-generated fairytale, and an AI-narrated audio file. A day later, I have seven:

The Deep Dreams podcast.

Here’s how I did it:

Continue reading…

How to write a modern Slack bot in Python

It took me SO LONG to find this info

This post is going to be short, but hopefully will help you avoid the troubles that befell me. I wanted to make a Slack bot using Python. “How hard can it be?”, I thought. “I’ve done it many times before”, I thought.

Think again.

The problem is that Slack has changed the way their APIs work. The old way is now referred to as a “classic app” with a “bot scope”, and that way is deprecated and you can’t really create apps like that now, so you have to do a whole other thing.

In this post, I will detail the steps necessary to create a simple bot that will listen for messages and reply to them. That’s all the scaffolding you’ll need (or that I needed) to create your apps, but I had to search for many hours to discover this information. Hopefully Google will be kinder to you and

Continue reading…

How to ask for help

It's harder than it sounds

As you may be aware, I very much like building things. Almost by definition, this means that I’m very often in situations where I’m out of my depth, as I always try to do new things that I don’t quite know how to do yet. Luckily, I have a whole bunch of knowledgeable friends whom I can ask for help.

However, I noticed a pervasive problem when asking for someone’s help: It takes way too long to describe the issue I’m having. To make matters worse, conversations are usually synchronous (either chat or phone calls), which means that I’m wasting a bunch of the limited time they’re gracious enough to give me on trying to get my thoughts in order and describe the problem well.

This is very suboptimal, and I’d like to propose a better

Continue reading…

Keyyyyyyyys!

The keyboard you never wanted

I have a friend, Josh. Josh is a literal superhero. He’s a boring, minivan-driving programmer by day, paramedic and firefighter by night. That’s already a much more plausible superhero premise than Batman (a billionaire who spends his time fighting street-level crime? Really, Bruce? Is that the best use of your time and billions?).

Josh showed me some notes he had taken while he was paramedicking his paramedic things. I say “showed”, it was more “asked me if I could make out what the hell the notes said”.

I could not.

The conversation then went like this:

  • Why don't you type on a computer?
  • A computer is generally hard to set up in the field, and you need to keep eye contact with the patient, so handwriting is more convenient.
  • Why not have a special keyboard?
  • I don't think that's very con
  • It can be wireless, and one-handed!
  • Yeah but still, how am
  • It can have five keys, one for each finger, and you can chord combinations to type!
  • That sounds slow and
  • JOSH THIS IS HAPPENING STOP FIGHTING IT

After his outpour of encouragement, I was motivated to create a solution, no matter how hard. I had a rough idea in my mind, but it was going to be tough oh who am I kidding, it’s five buttons connected to a microcontroller, it would take two minutes.

It took four hours. Close enough.

Continue reading…

The "do not be alarmed" clock

An alarm clock for the rest of us

It’s a brand new year, which means I should really start writing a new post. I’ve been wanting to for a while, but we’ve been in lockdown for two months now and Google Analytics is the only indication that I’m not alone on the planet, and most of that is bots anyway. I’ve decided to take a page out of the book of my friend, James Stanley, who both does cool things and actually writes about them, so I’m starting to document all my projects again.

Given my non-frenetic, slow-paced lifestyle, I’ve long had a non-burning need. I don’t use an alarm to wake up, as I start work late, but I still want to know what time it is when I wake up, just to see if it’s way too early and I can go to sleep again. A few days a week I have tennis and need to get up early, but if it’s windy or rainy or very cold, the practice gets canceled and I want to know before I’m awake enough to not be able to go to sleep again.

To accommodate this lifestyle, I’ve traditionally turned to my mobile phone, but that has some disadvantages. Namely, the screen is too bright and wakes me up when I check the time, and I’m too obsessive to not check all my messages instead of falling asleep when I see the notifications on the screen. I’ve long thought that a bedside alarm clock would be perfect for me, but I couldn’t find one that fulfilled all my requirements:

Continue reading…

How to use FIDO2 USB authenticators with SSH

Secure, easy to use, cheap: Pick three

I recently installed Ubuntu Wacky Whatever, the latest version, and I’m very excited about it shipping with SSH 8.2, which means that I can finally use hardware USB keys for secure, easy to use authentication. If securing your devices has been something you’ve wanted to easily do yourself, read on, because it’s finally happening.

FIDO2

One of the most exciting security-related developments recently has been the development of WebAuthn and FIDO2, which are basically euphemisms for “nice security stuff”. In summary, WebAuthn and FIDO2 aim to make it really easy to use security devices with stuff by standardizing the way the two talk to each other, and using better terms than “stuff”.

This is great news for us, because now we can have dirt-cheap USB keys that can be used to secure all our authentication very easily, without requiring any special security knowledge. All you need to know to be completely immune to phishing, password theft, and a whole host of other ways of losing Bitcoin is to just plug your USB key in, press the little button/type your PIN/enter your fingerprint, and you’re logged in.

What does this have to do with SSH? Very little, but

Continue reading…

Using FastAPI with Django

FastAPI actually plays very well with Django

You know me, I’m a Django fan. It’s my preferred way of developing web apps, mainly because of the absolutely vast ecosystem of apps and libraries it has, and the fact that it is really well-designed. I love how modular it is, and how it lets you use any of the parts you like and forget about the ones you don’t want. This is going to be emphasized rather spectacularly in this article, as I’m going to do things nobody should ever have to do.

My only issue with Django was that it never really had a good way of making APIs. I hate DRF with somewhat of a passion, I always found its API way too complicated and verbose, and never managed to grok it. Even the simplest things felt cumbersome, and the moment your API objects deviated from looking exactly like your DB models, you were in a world of hurt. I generally prefer writing a simple class-based view for my APIs, but then I don’t get automatic docs and other niceties.

It’s no surprise, then, that when I found FastAPI I was really excited, I really liked its autogenerated docs, dependency injection system, and lack of magical “request” objects or big JSON blobs. It looked very simple, well-architected and with sane defaults, and I seriously considered developing the API for my company’s next product on it, but was apprehensive about two things: It lacked Django’s ecosystem, and it didn’t have an ORM as good and well-integrated as Django’s. I would also miss Django’s admin interface a lot. Three things.

It would have been great if FastAPI was a Django library, but I guess the asynchronicity wouldn’t have been possible. Still, there’s no reason for DRF not to have an API as nice as FastAPI’s, but there’s no helping that. A fantastical notion caught hold of me: What if I could combine FastAPI’s view serving with Django’s ORM and apps? Verily, I say unto thee, it would be rad.

And that’s exactly what I did. Here’s how:

Continue reading…