Brief automations: Playing a random album from Plex

Another installment in my series on listening to music is forthcoming and it will mostly be a love letter disguised as a 1000+ word use guide for Plexamp. In the meantime, this is a slightly out of context taste.

My music library lives under the watchful eye of a Plex server. The server pulls down a lot of metadata that makes artist and album pages much more delightful to browse than iTunes/Music.app ever did. I then use Plexamp to listen to music both at and away from home. I really love this setup.

Besides the official Plex and Plexamp clients, there is an unofficial Python Plex library whose goal is to “match all capabilities of the official Plex Web Client”. I’ve been playing with it for a while, it is impressive, and this is the first of many uses I have in mind for it.

Play a random album the simple way

I keep all the albums I own as CDs in a Collection called ‘💿’.1 Sometimes I want to put on some music but I don’t have a specific album in mind and end up scrolling the collection aimlessly.

A common way to deal with this kind of choice paralysis is to let a random picker choose for you. This is very easily done using the Python library.

Here is a simple implementation.

import random
from plexapi.server import PlexServer

BASEURL = 'http://192.168.1.123:32400'
TOKEN = '<insert your own token here>'
plex = PlexServer(BASEURL, TOKEN)

owned = plex.library.section('Music').searchAlbums(collection='💿')
plex.client('KEF').playMedia(random.choice(owned))

Requirements:

  • pip install plexapi
  • Know the local or remote IP address of your server.
  • Your X-Plex-Token for authentication. Here’s how to find it.
  • Know the name of the client that will play the album. This is cool because it doesn’t have to be on the same machine running the script! In my case I have a machine running Plexamp connected to my KEF speakers.

Steps:

  • Import the random library and the PlexServer class.
  • Create an instance of your server with the correct url and token.
  • Get a list of the albums in the ‘💿’ collection.
  • Tell the client to play a random album from that collection.

So that’s amazing and simple. Here’s how you can make it amazing and a little fancy.

Playing a random album the glamorous way

A random choice from a large collection can be jarring. Too decisive, you know? One compromise you can make between that and choosing from the whole collection yourself is to get random to offer you two – or more – candidates to choose from.

The implementation is a bit involved but still pretty straightforward.

#! /usr/local/bin/python3

import random
import requests
import subprocess

from PIL import Image
from io import BytesIO
from plexapi.server import PlexServer
from rich.console import Console

CONSOLE = Console(color_system='truecolor')
BASEURL = 'http://192.168.1.123:32400'
TOKEN = '<insert your own token here>'

plex = PlexServer(BASEURL, TOKEN)
owned = plex.library.section('Music').searchAlbums(collection='💿')

albums = {
    album.title: album
    for album in random.sample(owned, 2)
}

albumart = [
    Image.open(BytesIO(requests.get(candidate.thumbUrl).content)).resize((500, 500), Image.LANCZOS)
    for candidate in albums.values()
]

merged = Image.new('RGBA', (1020, 500))
for ii, art in enumerate(albumart):
    padding = 0 if ii == 0 else 20
    merged.paste(art, (ii*500 + padding, 0))
merged.save('/var/tmp/amp.png')


CONSOLE.print('\n')
subprocess.run(['/Applications/kitty.app/Contents/MacOS/kitty', 'icat', '/var/tmp/amp.png'])

CONSOLE.print('\nPick an album')
choices = ' '.join(['"'+albumtitle+'"' for albumtitle in albums.keys()])
choice = (
    subprocess.check_output(
        f"/usr/local/bin/gum choose {choices} --cursor '  ' --selected.foreground='#7851a9'",
        shell=True,
        encoding='UTF-8')
    .rstrip()
)

plex.client('KEF').playMedia(albums[choice])

CONSOLE.print(
    f'\n  [italic]Now Playing: '
    f'[#9966cc]{albums[choice].title} ({albums[choice].year})[/#9966cc] '
    f'by [#47c1ff]{albums[choice].artist().title}'
    '\n',
    justify='center'
)

Requirements: I wanted to make this aesthetically pleasing, so there are some splurgy requirements.

Steps:

  • Same imports from the simple implementation. Then a few imports for image processing, reading the album art from the server, and pretty printing in the console.
  • Get a list of the albums in the ‘💿’ collection.
  • Get the titles for two random albums, then get the album art for those two albums.
  • Merge the album art into one image. I have to do this because as far as I can tell kitty won’t let me display two images next to each other in the terminal.
  • Tell kitty to display the merged image.
  • Use gum to ask the user which album to play.
  • Tell the client to play the chosen album.
  • Display a “Now Playing” status with the album title, release year, and artist.

Other notes:

  • The characters appearing as in the code are music glyphs in the PragmataPro font I use in kitty. You can see it in the video.
  • Resizing the album art to 500×500 is hardcoded across the script. You could set that as a variable to change later. Also some album art isn’t perfectly square and will look silly when resized to a square. I might deal with that later.
  • It’s more idiomatic to use tempfile to get a path to a temporary filename. You can read more about the tradeoffs here.
  • I wrote this to make it easy to accept the number of albums as an argument instead of that also being hardcoded in the script.
  • You could build this out to also ask the user which collection they want to pick from. I plan to do just that.

And that’s it. Kinda swanky.

  1. This also has music I bought from Bandcamp, Qobuz, Boomkat, etc. But it’s mostly CDs. ↩︎

Programming the Atreus Keyboard

Happy New Year.

Okay here’s a thing. About a year ago I bought a Keyboardio Atreus keyboard.1

I don’t remember what made me think that was a good idea, or how I even found out about it. I did it for my Mental Health? Some people buy a Rolex, others buy a keyboard. Let’s move on.

What’s all this then?

Keyboardio Atreus. Bright keycaps are Massdrop x MiTo XDA Canvas custom keycap set. Black keycaps came on the Atreus.

It’s a tiny little thing.

The Atreus has a learning curve, no question. Space is a key not a bar. Arrow keys, number keys, special characters, function keys, and media controls exist in Layers 1 and 2.2 This means you use Fun E / D / S / F for ↑, ↓, ←, and →. A numpad exists on the right side with its corners defined as Fun M for 1 and Fun O for 9. All special characters are accessed using Fun other keys. To access media controls, function keys, and other lesser used buttons like Page Up and Page Down keys, you need to activate Layer 2 by pressing Fun Esc then releasing them, which locks the keyboard in Layer 2 until you Esc out of it. So if you want to turn up the volume, you press Fun Esc and let go, press X for volume up, then press Esc to go back to the base layer.

It’s a lot, I know. I want to tell you it takes a week or two to get used to it, but the truth is it takes about 3-4 weeks for proficiency in typing prose and maybe double that for proficiency in writing code. That said, I love this thing so much that it activated the principle of “two is one and one is none” and I got myself a second board as a backup.

Programmability

One of the big selling points of the Atreus is that it runs on open source firmware called Kaleidoscope.

Keyboard.io created a GUI interface around Kaleidoscope called Chrysalis which you can use to remap and modify some things on your keyboard without messing around with code, compilations, flashing, etc. The downside of this option is that Chrysalis doesn’t support all of Kaleidoscope’s features (yet–including the one that matters the most to me: Macros).

You might opt for modifying and building Kaleidoscope directly for any of the following reasons: You want to use a feature not exposed in Chrysalis. You want to define a complicated setup in code so you avoid forgetting what you implemented and how you did it, and so you can commit it to a dotfiles repo or something similar. Or maybe you just have a preference for code and live a terminal > GUI lifestyle.

If you’ve ever messed around with an Arduino board, it’s the same idea: you write a script encoding the behavior you want, compile it, then install it to the keyboard. In fact, Arduino software is required if you want to build and install Kaleidoscope yourself.

Quick note on why this matters: some programs will let you create macros or remap your keys. Keyboard Maestro is one example and it can do (probably?) everything Kaleidoscope can. The benefit of programming your keyboard’s firmware is that you can plug that keyboard into anything and have the same behavior come with it. Set it up once, have it everywhere. This is especially useful if you use external keyboard with an iPad like I do, where a utility like Keyboard Maestro cannot exist.

Code

I’ll use the first macro I created in Kaleidoscope as an example.

On a Mac, the common keyboard shortcut to move to the tab to the left or right of the current one is Shift Command [ and Shift Command ] respectively.3 On a normal keyboard this chord is simple enough to type, but on an Atreus, it’s a 4-key contortion: Shift Command Fun Z for previous tab and Shift Command Fun X for next tab.

Here’s how you can modify the Atreus firmware to add a simpler macro – Fun H and Fun ; – that translates to the Mac keyboard shortcuts for switching tabs.

1) Start with the base firmware file.

2) Define the macros in macro_t constant. In this case I named them LEFT_TAB and RIGHT_TAB. This defines which keys are pressed when the macros are triggered.

const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) {
  if (keyToggledOn(event.state)) {
    switch (macro_id) {
    case MACRO_QWERTY:
      Layer.move(QWERTY);
      break;
    case MACRO_VERSION_INFO:
      Macros.type(PSTR("Keyboardio Atreus - Kaleidoscope "));
      Macros.type(PSTR(BUILD_INFORMATION));
      break;
    case LEFT_TAB:
      return MACRO(D(LeftShift), D(LeftGui), D(LeftBracket));
      break;
    case RIGHT_TAB:
      return MACRO(D(LeftShift), D(LeftGui), D(RightBracket));
      break;
    default:
      break;
    }
  }
  return MACRO_NONE;
}

3) Add the macros to the H and ; keys on the second layer (which is triggered by holding the FUN key). Look for M(LEFT_TAB) and M(RIGHT_TAB).

KEYMAPS(
...
  [FUN] = KEYMAP_STACKED
  (
       Key_Exclamation ,Key_At           ,Key_UpArrow   ,Key_Dollar           ,Key_Percent
      ,Key_LeftParen   ,Key_LeftArrow    ,Key_DownArrow ,Key_RightArrow       ,Key_RightParen
      ,Key_LeftBracket ,Key_RightBracket ,Key_Hash      ,Key_LeftCurlyBracket ,Key_RightCurlyBracket ,Key_Caret
      ,TG(UPPER)       ,Key_Insert       ,Key_LeftGui   ,Key_LeftShift        ,Key_Delete         ,Key_LeftControl

                   ,Key_PageUp   ,Key_7 ,Key_8      ,Key_9 ,Key_Backspace
                   ,M(LEFT_TAB)  ,Key_4 ,Key_5      ,Key_6 ,M(RIGHT_TAB)
      ,Key_And     ,Key_Star     ,Key_1 ,Key_2      ,Key_3 ,Key_Plus
      ,Key_LeftAlt ,Key_Space    ,___   ,Key_Period ,Key_0 ,Key_Equals
   ),
...

4) Finally, add the macros to the enum declared towards the beginning of the file.

enum {
  MACRO_QWERTY,
  MACRO_VERSION_INFO,
  LEFT_TAB,
  RIGHT_TAB
};

5) Follow the development guide I linked above to compile and flash this new firmware, and you’ve built your first Atreus macro

See also

  1. I’m glad you asked. Kailh BOX White switches. ↩︎

  2. What you see in the photo is Layer 0, the base layer. Because of course the layers are 0-indexed. ↩︎

  3. I just learned that Control Tab and Shift Control Tab also works. ↩︎

Listening to music: Last.fm

This is part 2 of a series on listening to music. Other parts:

  1. Beginnings
  2. Last.fm

My Last.fm account knows about every song I’ve listened to since 2008.

~6,500 artists, ~7,700 albums, ~170,000 tracks.

When I listened to the MP3 files I brought with me from high school, I made sure Last.fm was scrobbling. When I listened to the mix CDs my best friend made me, Last.fm listened too. When I tried Spotify for a few months, when I switched to Hype Machine, when I listen to the CDs I own or the albums I bought from Bandcamp, everything I’ve played in iTunes, on my iPods, on Music.app on iOS, on Marvis, during my short-lived Roon experiment, through Plexamp. It’s all there.

My life.

Last.fm remembers every day of the last fourteen years of my life.


Last.fm is an anomaly, a mutation of the internet, and a service that just celebrated its 20th birthday.

Now you could say so what, right? Myspace is still alive and its website still technically loads. Google is like, 100 years old or something. So what.

Sure. First of all Myspace launched in 2003, so it’s technically 19 years old. That’s right: Last.fm is older than Myspace! And Google is…well who gives a shit about Google. Do you feel anything when I say “Google”? No you don’t.

Also thing is, Myspace doesn’t exist the way Last.fm still exists. I don’t know what Myspace is today, it looks like it’s a social network for singers and actors? No one who uses it today sits and thinks about where it was and how it got to where it is now.

Last.fm had a lot of ups and downs. In its heyday it had a technical blog and a staff that posted photos of server rooms and office space, it had actual streaming radio that did intelligent things with music it knew you liked, they put random slogans at the bottom of site pages. It was scrappy and ambitious. They figured out how to create a plugin that automatically scrobbled what you listened to in iTunes, but that also figured out how to scrobble what you listened to on your iPod.1 As far as I know, that’s the only useful thing any third party app did with what happened on your iPod.

Everything was fine. No everything was great! Then came a redesign or two, the streaming died and got replaced with a hacky “we’ll just play YouTube videos and pretend you’re streaming” setup, Groups which was actually fun died, CBS bought the company (that was the moment I thought it was all over), and then a long silence during which it felt like every other month a piece of the site would disappear. They used to let you export your data, that went away. https://status.last.fm which was a proper service status page now redirects to a Twitter account. It all felt a little grim. Okay a lot grim.

But. Throughout all of this, the ups, downs, happy days and sad, not being owned by a large media conglomerate and being owned by a large media conglomerate, the site never stopped accepting scrobbles.2

And in a world that has turned its back on, then mooned the interconnectivity of Web 2.0, in a world where APIs get turned off and rarely on, Last.fm still commands death-defying loyalty with music listeners who demand scrobbling of old and new music apps and streaming services.

There are signs of life. The listening reports feature gets improvements every once in a while. Library search is here.3 Their Twitter account is fairly active. The site isn’t…you know, dead. Every time I update that plot I wonder how many more years of data I’ll be able to add to it. Who knows. It’s the internet, and nothing is forever, even if some things feel like they are.

Appendix: Listenbrainz

I mentioned in passing that Last.fm used to let you export your data including all scrobbles and loved tracks, and that this disappeared at some point. So how did I make the plot at the top of this post?

Listenbrainz is part of the MetaBrainz Foundation.4 Its goal is to be a “public [and] permanent” store of your listen history, to make this data available for download, and share this in some technically knowable and supported fashion.

Here is how I think of Listenbrainz: Yes we all can hardly believe that Last.fm still stands, but the clock is ticking. You know that right? Don’t you want a backup plan? Don’t you want a way to get your money outta that bank before it craters? That’s Listenbrainz.

The good. Listenbrainz will let you import all your listens from Last.fm, and will let you download it in a fairly structured payload. That’s how I made the plot at the top.

The bad. This is a manual process. You have to remember to come back and do it regularly. Why? Because it seems to basically load and scrape each page of listens from your Last.fm profile. Why? Probably because Last.fm doesn’t want them doing this, and probably has no API for it. Lord knows the APIs they do have barely work. The other reason this is bad is that it might stop working.

Listenbrainz has an API. Technically music players can start letting you authenticate with Listenbrainz in addition to or instead of Last.fm and send your listens there too. As far as I know, as of today no Mac/iOS music players do this.

  1. It wasn’t black magic, but it was still technically impressive. I don’t know if they ever officially said how that worked, but I’m fairly sure it relied on play counts. Whenever you listened to music on your iPod (or iPhone) the playcounts were incremented, and when you synced your device to your computer the playcounts in your iTunes library got updated too. Last.fm would use a track’s changed playcount and last played timestamp to decide what you listened to since the last sync. One thing I can’t remember is whether the plugin could figure out if you played tracks A -> B -> A. A’s playcount would be incremented twice, and its last played timestamp would show the latest play, so as far as the plugin could guess, what you did was B -> A -> A. So if the plugin could figure out that you played A -> B -> A, the solution must be more sophisticated than I thought. ↩︎

  2. There are frequent downtimes, but the core service seems well-designed enough that it always catches up with what I played once it’s back online. ↩︎

  3. The blog post before that one is from Feb 2019. The one before that was Sep 2017. So it’s still a little sad. ↩︎

  4. The one Metaverse that actually exists. ↩︎

Listening to music: Beginnings

This is part 1 of a series on listening to music. Other parts:

  1. Beginnings
  2. Last.fm

First, there were cassette tapes.1

I grew up in a small Arab town and didn’t get dial-up internet until I started high school. Before then, I had to walk to the record store in the nearby mall and use what I could save from my allowance to buy cassette tapes, meaning I could afford a handful every year.

At the time, the United Arab Emirates censored cassette tapes. As in, any parts of the song containing lyrics you imagine would be objectionable to the politics and morality of a thirty year old Arabian Gulf government were cut, and not in a subtle way.2

Do you know what it’s like for a middle schooler to pay what felt like a thousand dollars for a copy of the Marshall Mathers EP only to discover that all obscenities and obscene-adjacent expressions were censored? It was practically an instrumental version of the record.

Still, I played my tapes.


At some point I owned a Panasonic portable CD player, although I can’t remember if I had it before or after my first MP3 player. I also can’t remember which model it was and so I can’t find an image of it online. It was black, and I used to carry it in a custom-made black fabric case with a big red pentagram sewn on it. Thanks mom.

I had a few CD albums but I mostly used a CD-RW that I burned and re-burned multiple times a week, treating the player as a heavier and less convenient MP3 player.

This is also when I started ripping CDs and building a modest local music library in Windows Media Player (later migrating to Real One Player).

Windows Media Player as I remember it from the Windows XP days courtesy of PCMag
Real One Player from the same era courtesy of dailymotion.com

The first digital media player I ever owned was a no-name USB thumbdrive MP3 player with a janky screen. I am shocked to find that you can still exchange currency for one in this year 2022. Today you can have one for the price of an Americano, but back then it was the most precious thing I owned.

Noname MP3 player courtest of aliexpress.us

Looking at the image, I can remember how it had that cheap soft plastic smell, and how I played a lot of Three Doors Down on it.


The next evolution didn’t come until 2007, when I moved to Canada, started university, and got my first computer.3

I couldn’t give you a strong reason why, but I asked for a Mac even though that was a risk at the time. Macs were still kinda new, I had never used one, and I couldn’t be sure that I could do everything I needed to do for university on it. But, they seemed cool and the only teacher I really liked in high school had one, so I YOLO’d it and assumed it would all work out.4

Apple’s educational discounts were better back then. With my white plastic MacBook, I got a free iPod Nano 2nd generation, and a free printer (after a mail-in rebate).5

I still have my first MacBook, sans battery.
iPod Nano 2nd Gen courtesy of ifixit.com

It took me a while to get used to the iTunes/iPod model of a music library. Having spent years dealing with the files themselves (downloading the, copying them, burning them, moving them around), I couldn’t figure out why iTunes seemed to be hiding my files from me.

In the end, iTunes taught me the value of playlists and accurate MP3 tags. Despite the rocky start, I loved iTunes, and would end up moving and growing the same iTunes library from 2007 until today (although it’s been largely ceremonial since November 2020). A lot of people hated iTunes, but iTunes never let me down. Not until they started calling it Music.app.


Over the next few years I started earning some disposable income, became a regular at the local Beat Goes On, started buying a lot of CDs, and also found my way to a private site mourned by many and replaced by none. Those were heady days and the depth and breadth of my music library exploded. This was the golden era of music discovery in my life.

In 2008 friends at the campus newspaper where I volunteered (and loitered at for the majority of my undergraduate life) told me about Last.fm and I created the account I still use to this day.

In 2009, I upgraded from the iPod Nano to a refurbished 80GB black iPod Classic. It was my first, not to be the last.

iPod Classic 80GB in black, courtest of bhphotovideo.com

I loved that iPod. It was heavy, felt good in the hand, was big enough to carry my entire music library (for a while), and did one thing: played my music.

The iPod Classic times were the best of times.


After the iPod Classic came the iPod Touch, and after that came the iPhone.6 This period is marked with a lot of noise. Music no longer had a sanctum and got mixed up with everything else. With the iPod music was everything, but after that it became just an app. It became something that happened while other things happened on the same device.

I have more to say about this phase and the role iTunes played in everything, and that will come in a later post.

Next, a note about Last.fm.

  1. Which are making a comeback. You can buy tapes on Bandcamp now! A coffee shop near my place has a shelf with cassette tapes for their stereo. ↩︎

  2. I always wondered whether the music labels created special copies of these tapes for these censorial markets, or if the distributors in the UAE performed the mutilations themselves on import. Who knows, maybe the labels didn’t even know those copies existed. ↩︎

  3. Until then I used a family Pentium desktop that lived in the living room. ↩︎

  4. A highly underrated tactic. ↩︎

  5. I think I got the silver iPod. I wish I still had it. ↩︎

  6. In the mix was an iPod Shuffle 2nd gen, but it never grabbed me as much as it did other people. ↩︎

Bulletin

I’m out of practice when it comes to writing blog posts; writing here feels like counting backwards from 1000 while skipping all numbers divisible by six or seven: unnatural. I’m torn on whether to take this seriously and if so how seriously to take it. But I’m also out of practice because I’ve been somewhere else. In life, I’ve been working on a lot of things that aren’t technical, and in writing and communicating, I’ve been writing on my Bulletin which cross posts to my Micro.blog account.

Micro.blog is like a town square of people who want to be friends.1 People create accounts, they mostly use their names and faces, they write brief notes or post a lovely photo or two from their day, and they talk to each other. It’s wholesome and friendly, and its design, rules, and structures are very thoughtfully designed. Also it’s the most diverse crowd of internetians I’ve ever hung out with.

There are no “Likes”, you can follow accounts but no one can see a list of their own followers, there are no follower counts at all, there is no hashtag support, and there’s a Discovery stream that’s manually curated. You can search for certain types of posts using emoji, and you can discover or meet new people by following conversations the people you are already following are having with others.

Anyway, you can have Micro.blog host your blog for you, and I did that for a while. I couldn’t find a theme that I liked, and I couldn’t figure out how to modify any of the existing ones to my satisfaction, but that wasn’t a problem because after I reserved my username (@sherif) when I backed the project on Kickstarter back in 2017, I didn’t do much with it for five years. A few months ago I realized that Micro.blog was thriving, and that it was the kind of place with the kind of people I was looking for.

I love an opportunity to design something whimsical for the internet, and Bulletin is exactly that. I like thinking of my posts as dispatches from a desk or a location, and I tried to design the site with a modern telegram or chain of correspondence motif. I also had to solve some interesting technical problems with the Jekyll site, like adding a filter to handle generating the correct local and UTC timestamps for each post based on the location it was posted from. I also designed it with a focus on how it displays photos, because I think with Bulletin I finally, finally, have a place where I can post occasional photography without overthinking it.

I’m very happy with how Bulletin turned out, but the bigger point is Micro.blog is a pretty chill place to be, and you should come over and enjoy some of the best vibes currently available on the internet.

  1. For a description that’s a bit more helpful, see here↩︎

Sabbatical

Sunset flight - sabbatical

I started working at $FAANG_COMPANY (henceforth referred to as $COMPANY) on Monday January 16, 2017, and stopped working at $COMPANY on Friday June 24, 2022. I was paid (well) to further the business interests of $COMPANY for one thousand, nine hundred, and eighty-five days, excluding most weekends. Thus was my first full time job.


I would tell you what my job title was, but it doesn’t really matter, and anyway I worry it might mislead you about what I actually did because job titles are weird. I ran and analyzed data from experiments, did some data engineering, trained a regression model or two, trained a deep learning model or two, and built a lot of automated inference and decision-making workflows that combined model outputs and business rules. Yes I did “machine learning” “in production”. I was halfway between a scientist and a developer and I liked it.


It’s important to acknowledge that there’s a lot of privilege in being able to quit a job not because you’re going to a different one, but because you’re just not happy doing it anymore.

  • Financial. I have enough money saved to support myself through a period of unemployment without getting anxious about meeting my basic needs. Multiple unlikely catastrophes would have to happen for me to be in a bad place.
  • Legal. Getting my work visa to move to the US and start my job at $COMPANY was not a smooth process, but it got done. Getting my permanent residency was far more turbulent, but despite the odds it also got done. I’m lucky to have a more stable life in this country without having to carry the work visa holder’s constant anxiety about losing or leaving a job. For those unfamiliar with that anxiety, it sucks and it warps the way you think.1
  • Social/mental. Leaving a job is a scary thing to do. I’ve had the support of some who reassured me that I wasn’t crazy, others who reassured me that I would be able to find gainful employment again, and even others who quit jobs before me and did not immediately die or combust into flames.

You do a job for a mix of intrinsic and extrinsic motivations.

Intrinsic motivations include:

  • You enjoy the ideas you’re working on, the specific problems you’re trying to solve, the product you’re trying to make better.
  • You enjoy the technical aspects of the work.
  • You value the impact of the work.

Extrinsic motivations include:

  • Compensation (salary + benefits + retirement savings + other).
  • Job stability.
  • You don’t want to leave a great manager.
  • You don’t want to leave a great team.

Different people have different intrinsic/extrinsic portfolios. Some have an intrinsic heavy ~90%/~10% mix (I’ll stereotype here, but: artists? people who work in used bookstores?), some have a ~50%/~50% mix (tough to find stereotypical examples for this), and some have an extrinsic heavy ~10%/~90% mix (people in finance, a lot of people in tech, and me at $COMPANY towards the end).

That’s the main reason I had to leave; I was running out of intrinsic motivation. For a while I was able to lean on the enjoyment of the technical aspects of the work, but they were tangential at best to my job description. I was stealing fulfillment from a role that wasn’t designed to give it to me, and my team was starting to move in the opposite direction. Not good.

I already lacked a good answer to the question “did my work delight anyone or make anyone’s life significantly better?”2 Losing the enjoyment of the craft itself made my decision easier. Going forward, I cannot not have a good answer to that question no matter what other conditions are met.


So I am taking a sabbatical. I don’t know how long it will last, and I don’t have a solid plan for it yet.

I want to travel (check), write more (check), read more (check), spend more time with people whose company I love (check, and in progress), return to and start personal projects so I can remember what it’s like to code for fun (not yet started), and explore the widest possible range of ideas for what I’m going to do for money next (not yet started).

Can I find a role defined around the technical work I enjoy? Can I walk through the valley of the shadow of death (interviewing in tech) again? Will I even go back to tech? Will I move? Will I work remotely?

All open questions.

  1. For an excellent writeup on what the US work visa and immigration process looks like, do read 18 Years A Transient – My Journey Through the American Immigration System as a Computer Engineer – Software the Hard way↩︎

  2. Thankfully I’m pretty sure my work didn’t make anyone’s life worse. A fate not trivial to avoid in tech. ↩︎

Personal Retreat

Yes it's not a good photo of a desk so I made it BW

In May of 2022 I went on a three day personal retreat to a small cabin in Whidbey, WA. I had travelled just to be alone before, but this was the first time I went with a plan for what to do. It went better than I expected and I wanted to write some personal notes about it here.


I don’t know what first comes to your mind when I say “personal retreat”. It’s not the spiritual meditative kind (although it can feel a little bit like that at times), and it isn’t the kind where you go to a remote location in the California desert and join others for a week of silence and contemplation.

Try not to over-hype it. You’re just taking some time to think about where you are, where you want to be, and the actionable changes you can make to get there.

The plan

David Sparks published a guide for how he does his personal retreats, and it seemed pretty good to me so that’s what I did too.1

You can watch/read the guide for yourself, but to give you some context I’ll say that the work revolves around Roles. You can imagine that everything we do, we do while inhabiting a particular role. You’re a friend, a writer, a painter, a cyclist, a lover, a spouse. I know it’s not that straightforward and roles are not that separable, but this works well enough to be useful.

Now that you know the first principle of Roles, the rest of the steps are:

  1. Write down all the roles you inhabit.
  2. Write your ideal description of how you want to be in each role.
  3. For each role, you answer a list of questions that you’ve prepared ahead of time (this is the most time-consuming part of the whole exercise).
  4. After answering all questions for all roles, collect a list of actions that you want to take to move yourself to where you want to be.
  5. Don’t do the actions themselves, but build whatever systems you need to make it easier for you to do those actions when you’re back in the real world.

There’s not that much more to it, but you should watch David’s video for more details. What I want to do with the rest of the post is document some practical meta notes as they apply to me.

Notes

Going somewhere else

This one is short. Don’t do this at home. Don’t do this where you will be surrounded by other people (strangers or not), and even if you’ll be alone don’t do it in a familiar place where you will be surrounded by all your distracting shit.

Pack a light bag, go somewhere else that’s simple, cheap, sparse, and quiet.

The vibe of the space matters

I wish I could say that any place would work as long as you were alone. Maybe that’s true for some people, in which case that’s great because it gives you more flexibility. For others, including me, aesthetics influence mood and ability to focus and introspect. A lot. Know whether that’s true for you as well, and account for it.

I was was lucky to find the place I went to. It was small, cheap (as cheap as a cabin on Whidbey island could be), cozy, and not modern in any way. No linoleum, no chrome, carpets everywhere, wood everywhere, old comfortable furniture everywhere. It wasn’t fake mid-century modern, it was actually old. It was perfect.

Pen and paper vs. typing.

I’m parroting David here, but having periods of focused, uninterrupted writing is critical. David manages to protect his attention while still using a computing device to write (I think he uses an iPad), and I can imagine how this might work: turn off the radios, turn on Do Not Disturb, use Focus Modes to suppress things even further, etc.

My digital hygiene is much worse than David’s. I think just looking at a screen and touching a keyboard would crack my attention even if no information is popping up, so I opted for the pen and empty notebook approach.

There are downsides to pen and paper. Writing by hand is a lot slower than typing.2 Also if your handwriting is terrible, you might not be able to read it later, or it might just put you off during your review.

A year ago I would’ve added “you can’t search” to the list of cons to pen and paper, but iOS now has Live Text and it’s amazing, even with handwriting. I wouldn’t say that it’s a solved problem, text flow and formatting might still be garbage, but at least it’s searchable.

This is also where the specifics of the place helped me a lot. There was a corner with an old writing desk and creaky wood chair that helped me keep my work environment sparse and tidy.

Silence

Boy does it matter. I wish it didn’t, because I usually like to listen to music while I do things, but it does.

It’s very à la mode to say this these days, but it’s amazing how clearer your mind can be if you spend an hour or two writing or thinking in uninterrupted silence.

Not a lot stuck after the first try

I left the cabin full of insight and plans for things to change to get closer to the life I wanted to live. I don’t think any of the insights were wrong, but I made some classic mistakes, the classic-est of which was to have plenty of plans for things I was going to do without sufficiently planning for things I was going to stop doing. It’s a mistake as old as time.

So, in the final analysis, I intended to make ꭓ amount of change, and I’ve actually accomplished about ⅛ ꭓ. But hey, that’s good! I learned some lessons and I’ll do a better job next time.

Next time

Have a next time. This is good to do once, but the real gains come from doing it often.

  1. He also has a PDF version but he unfortunately put it behind a newsletter signup form. You can decide to sign up to get it, but it’s essentially the same content from the video in readable form. ↩︎

  2. That said, slow can be good here. ↩︎

Pilot

Turning base for runway 16 at KRNT

I passed my private pilot checkride on Tuesday, September 14th, 2021. I think getting my pilot’s license was the hardest thing I’ve ever done.1 Flying didn’t come naturally to me, and being able to say that publicly and be okay with it is perhaps the second hardest thing I’ve ever done.

So how do you learn to fly a plane in the United States? There are many ways, and many aviation websites will tell you all about them. I’m writing this here for those who won’t go looking it up otherwise.2

Discovery

Unless there’s an aviator in your family who introduced you to flying in your childhood, it starts with a discovery flight: a 2-ish hour flight offered by flight schools that previews what it’s like to fly a general aviation aircraft—think Cessnas, Pipers, Cirruses (Cirri?). You meet with a flight instructor who shows you how to pre-flight a plane, pre and post engine start checklists, radio communications in towered or non-towered airports, taxiing, more checklists, takeoff, cruise, and hopefully at least one landing.

On a discovery flight you fly left seat (which is the normal pilot in command seat), the instructor will hand you the controls to do some flying during cruise, and might even let you take off yourself if the vibe is right. Some people get into it right away, others are so overwhelmed by the earth pulling away from them in what is essentially a tuna can with a propeller that it takes them a while to get comfortable. You can guess which one I was.

Say you loved your disco flight—you caught the flying bug as they call it—and you want to take it all the way to your license, what next? You find an instructor, have an orientation, and schedule your first lesson.3 Congratulations, you’re about to spend a lot of money very fast.

Training is split into stages which might vary from school to school but generally look like this:

Stage 1: Pre solo

Stage one is about learning basic flight maneuvers: takeoffs, climbs, level flight, turns, descents, and landings. It’s also about learning beyond-basic maneuvers that teach you about the plane’s performance envelope: steep turns, slow flight, stalls, ground reference maneuvers, and emergency procedures. You will be asked to demonstrate these on the practical test.

This stage is complete when your instructor endorses you to do your first solo flight. Your first solo is a massive milestone, equal if not exceeding in significance to your practical test.

Stage 2: Cross country

Wind farm near Chehalis, WA

In this stage you build on basic flying skills to learn the fundamentals of navigation. For the purposes of a private pilot license, a cross country (XC) flight is one in which the “point of landing… [is] at least a straight-line distance of more than 50 nautical miles from the original point of departure”.5

During this stage, you practice planning XC flights by examining sectional charts, knowing what airspace you have to avoid or fly through, choosing altitudes to avoid terrain, and using weather and winds aloft forecasts to calculate your magnetic heading from true course, wind correction angle, magnetic variation, and magnetic deviation (if applicable).

This stage is fun because you’re actually going somewhere instead of doing circles in the practice area. But it’s frustrating because your instructor will probably have you do everything on paper to make sure you actually know what you’re doing. Planning a XC flight on paper is an excruciating and error-prone task. An instructor once asked me “How many times do you think I made a cross country flight plan on paper after I got my license?” and then made a big zero with their index and thumb.

The thing is there’s an app for that, it’s really good and it’ll do almost everything for you. That said, the examiner will want to know where all the numbers come from, and so the instructor wants you to know where all the numbers come from. It will also help you not get yourself killed when you inevitably press the wrong button in the app and not pick up on all the suspicious estimates.

This stage is complete when you perform a XC flight of 150 nautical miles, with full stop landings at three points, and when at least one segment of the flight is more than 50 nautical miles along a straight line between the takeoff and landing sites.

I did two cross country flights: KRNT → KCLS, and KRNT → KCLS → KKLS → KSPB. The solo cross country flights were the most fun I had during training.

Stage 3: Checkride prep

This is a catch-all stage. The goal is to complete any remaining requirements and bring up your maneuvers to the tolerances of the Airman Certification Standards (ACS).6 The ACS is very specific about the deviations allowed during maneuvers. For example:

Slow flight

PA.VII.A.S5: Maintain the specified altitude, ±100 feet; specified heading, ±10°; airspeed, +10/-0 knots; and specified angle of bank, ±10°.

Steep turns

PA.V.A.S5: Maintain the entry altitude ±100 feet, airspeed ±10 knots, bank ±5°, and roll out on the entry heading ±10°.

Power-off stalls

PA.VII.B.S2: Select an entry altitude that will allow the Task to be completed no lower than 1,500 feet AGL (ASEL, ASES) or 3,000 feet AGL (AMEL, AMES).
PA.VII.B.S3: Configure the airplane in the approach or landing configuration, as specified by the evaluator, and maintain coordinated flight throughout the maneuver.
[…]
PA.VII.B.S6: Maintain a specified heading ±10° if in straight flight; maintain a specified angle of bank not to exceed 20°, ±10° if in turning flight, while inducing the stall.

And so on.

Some examiners will look the other way if you deviate by 12° during your power on stalls. They might not notice, or they might get you to try the maneuver again. Most examiners aren’t trying to fail you; they want to give you your ticket. They just have to make sure you’re going to be safe, which is why some mistakes are automatic checkride busts and they’re usually mistakes relating to safety and situational awareness.

Closing thoughts

Orcas Island, WA

I’m a pilot now and I am really happy about it.

  1. Palpably aware of my privilege, thank you. ↩︎

  2. Above all else, I’m writing this here for me. ↩︎

  3. Finding an instructor is one of the more difficult things to do when starting flight training. Not unlike your relationship with your therapist, fit is critical when it comes to schedules, personality, communications, etc. ↩︎

  4. Serious talk, it’s not just you who will get slapped if you do stupid things during your training, your instructor will get slapped too. And since your instructor is very likely trying to build hours to get to the airlines, having a black mark in their file could end their career. ↩︎

  5. 14 CFR § 61.1↩︎

  6. I know. ↩︎

Archive