I got a new pair of glasses from Zenni Optical last Friday. For awhile now I’ve been looking for a smaller (but not too small) circular lens – kinda going for the Steve Jobs or John Lennon look. I think this pair has nailed it. I’m pretty happy with how they look, which I think is a little unusual for me.
I continue to be shocked how inexpensive glasses are at Zenni. These – were under $60, even with a bunch of special magic options (which yes, probably do nothing) added to the lenses.
And – since they’re so price-effective, when I realized that I accidentally ordered a -4.75 instead of -4.25 for my right eye, I didn’t even mind just ordering a second pair. I thought I could tell the right eye was a little off, so I guess it’ll be better when I get the strength that the doctor ordered?
Oh – and I have 2 old pairs (plus whichever of these is less good to see through) that I’m going to donate to the Lions. Because (1) I heard someone recently say how they used donated Lions glasses when they were a kid, and that made a difference in their life, and (2) because I feel more and more compelled to give more and more back to the world recently, and what a small thing that is – to donate glasses that will otherwise just sit in my drawer unused.
On Friday, 2024-11-08, I got a new M4 Pro Mac Mini š
My intention was to use this machine as a home server, primarily for backups, but also for, idk, any servers I might want/need to run – such as Home Assistant, Octoprint, and/or any personal apps I build.
I recently picked up a 4TB Samsung T9 SSD, which is plenty big (by almost 2x) for my current backup needs.
I had been backing everything up to a Synology, and then from there, offsite via Backblaze B2… but my bill for that service keeps growing (as it does), and just past $40/month! By switching to this Mac Mini based approach, I can use Backblaze’s single-computer = $99/year plan, and … eventually the Mini + SSD will pay for themselves š
And in the mean time, I do have a suuuper fast new Mac here. I’m trying hard not to switch my daily-usage to be on the Mini… Build times for my main work app were about 50% of what they are on my M1 Max MacBook Pro — not that it’s ever felt slow to me. I think I’ll stay here for now, and try to just let the mini do the job it was bought for.
A month ago (or six months? who can tell), Timmy mentioned getting a tray or rack or other kind of “mount” for his MacBook, to elevate it, and keep it off his desk. At least, that’s the story I heard. I thought it was interesting, so I Amazoned for one for myself (side note, Google became a verb, but Amazon didn’t? I think it’s high-time we fix that).
Anyway, I had one in my cart for some number of months (see above). And I finally pulled the trigger last night, with overnight delivery – so, now my MacBook Pro is flying too š
Not entirely sure why I did this? Maybe it was because my Mac Mini which is coming today might temporarily live below my MacBook?
Or maybe it was to correct this serious alignment issue that I had been dealing with for like 3 years now:
A couple of nights ago, when it was raining like crazy here (my 8-inch rain-gauge was overflowing!), our power went out for a second around 5AM. Not sure if this is just coincidence, or if there’s a causal relationship here, but later that morning, my electric kettle would no longer let me press the “warm” button multiple times to set it to stay warm for a longer period. That is to say – it used to be, each time you hit that button, it would add 30 minutes to the “stay warm” timer. Now, when I hit the button it puts up a 30 – but hitting it again, just deletes the 30. I only thought about a possible connection between the power-fail and this change in behavior because, whenever the kettle loses power, it forgets that I want it in “quiet” mode – so when i first turned it on, it was beeping at me, which made me think about the fact that it had lost power. Then, when I saw the change in behavior on the stay-warm function, I wondered if those thing were related. I did un-plug, wait 10, and re-plug, to see if that would fix it, but, no dice. :shrug:
Well, after 25 year of being a programmer, and around a decade of being an ever more all-in Apple fanboy, I’ve finally allowed those worlds to merge a bit, and I’ve published my first app on the iOS App Store!
Oh, I’ve had many half-baked ideas for apps over the years, but one issue had always been, that I’d never quite learned the specifics of how to do iOS development. I also played a role in a few apps that my teams built over the years, for MMLT and Infoplus, but none of those were ever truly *mine* from start to finish.
(humble brag? I did get through both of those tutorials in well under 100 days… I think that 100 number is meant for if you’re just starting out as a programmer – not a distinguished engineer as myself :lol:)
That eliminated my excuse of not quite knowing *how* to build an iOS App. It left me with just not having an actual app to build, plus the inertia of being “at rest”, meaning I’d never actually built an app from “0 to 1” as they say, and gone through the process to publish it to the App Store.
But over the past few months, I finally had a use case come up that would actually be useful to me, at least on a daily basis, that I think could potentially be slightly useful to others, and that was of a scope that I knew I could tackle at this point in my life.
I’ll avoid the gritty details of “why” this need exists, but suffice it to say that, virtually every day I am asked to perform a time-based calculation, which generally takes the form of:
Point-A to Point-B = Interval-C
Interval-D minus Interval-C = Interval-E
Point-C plus Interval-E = Point-D (which is our desired answer)
For example:
11:47 to 12:26 = 39 minutes
4 hours minus 39 minutes = 3 hours 21 minutes
1:18 plus 3 hours 21 minutes = 4:39. QED.
It’s not fun to do that math in your head (heck, for me, it’s barely possible!). It’s a little easier to do on paper, but then, who has that much paper just lying around? I’d like to do it on my Mac or iPhone, but what app do you use for that? Doing it in a regular calculator app is just about the same as doing it in your head, thanks to all the number-bases and intermediary values. So I searched the App Store for Time Calculator apps, and let’s just say that none of the results were satisfactory for me.
Therefore, as a programmer, I wanted to solve the problem by writing some code. And having recently completed the Swift tutorials mentioned above, I was ready to build my own app. The pieces were starting to line up for something good!
So I wrote some code! It was lots of fun, and I think I took an okay approach, both in terms of the structure of my Swift and SwiftUI code – several discrete views, a completely isolated model – unit tests on the models, and a heavy dose of Swift enums, that I used to implement a finite state machine, to manage the parsing of user-keyed time equations, as well as the enabling and disabling of all buttons on the calculator screen.
Wait, at this point, I should probably show what the app looks like. So, here are some screenshots!
That’s a fancy Time Calculator!Copy, Share, and Create RemindersDark mode support!Fancy animated Splash ScreenOnboarding / Tutorial screensSettings to force Light or Dark mode.
The last problem to overcome was one of the two Hard Problems⢠in Computer Science: choosing a name (the other hard problems in CS being cache invalidation and off-by-1 errors). I won’t say I’m “proud” of what I ended up with, but I can at least say that it’s fun, and, by golly, I like fun things.
So my first App published on the App Store is officially named: Whenr Whenr
(to be me, and explain the thing that’s probably obvious… that name is based on the word “when”, but with an awkward ‘r’ appended onto the end, to ape a certain style. then it’s supposed to sound like “winner winner”, which reminds me of the fun expression “winner winner, chicken dinner“. ok, explanation time over, back to the blog)
There you have it. A rough tale about my first iOS App. Of course I’ve got a long backlog of things I might add to it some day:
Support for seconds and/or decimals
Support for Dates and Date/Times
Date and/or Time pickers (the standard iOS widgets for choosing, rather than keying the values)
Saving the Ledger; having multiple Ledgers; exporting the Ledger, naming and time stamping entries in the Ledger – lots of Ledger work.
Widgets… yeah, it should have widgets. And shortcut support – not sure how, but somehow. Oh, and to keep up with the times, Live Activity / Dynamic Island support! Heck, if it was just spinning the icon, that’d probably be sufficient!
Starting a timer (e.g., from the Clock app) from an Interval in the app.
But – I decided to finally “shoot the engineer and ship the app” today. Which meant I got to spend a whole lot of time making lots of images for App Store Connect… Not too much fun, but a nice change of pace I guess.
Oh, I should probably provide a link to Whenr Whenr on the App Store. It’s available for iOS, iPadOS, and macOS (for Macs running Apple Silicon, as it’s just the iPad version).
When I saw a renewal notice for Kelkhoff.com on Squarespace come through the other day, I was shocked by the price tag. Did I really pay that much for it a year (or was it two?) ago when I first put up my own blog?
Well, it’s not like times are tough, but I figured, I should “host my own” site, so, here we go, a WordPress site.
I really like this theme that I found – called Curveflow.
So that’s the whole post – Kelkhoff.com – it’s now running on WordPress.
Earlier this year, when the game Wordle was all the craze, I woke up one morning with the idea in my head of the same basic game, but instead of choosing letters to make a word, the objective would be to pick numbers and operations (addition, subtraction, multiplication, division) to complete an equation.
The result is online at http://equationle.com. Itās nothing polished or complicated or great in any way, but, I had fun building it, and I get a little bit of fun from playing it.
I decided to make the equation* consist of 3 numbers and 2 operators that the player must figure out, which would be shown to equal a pre-determined number. To make things a little more constrained, I thought to put parentheses around the first 2 numbers, so you wouldnāt have to worry about order of operations (e.g., doing multiplication before addition) – the parentheses would mean to always do the left operation before the right one.
For example (as shown in the screenshot):
(number operator number) operator number = 21
Just like in Wordle, a correct guess is shown in green, and a guess thatās in the equation, just not the right place, is yellow. Incorrect guesses are shown on the on-screen keyboard in dark-gray. You can enter an equation which doesnāt equal the number shown – if so, that line will switch from showing an = to a ā sign. Oh, and unlike Wordle, every time you reload the page you get a new game (and I didnāt build the result-sharing featureā¦).
Before I put together the user interface for the game, I first wrote a little program to generate all possible equations fitting that structure, and to work out their result. Then, so that the game would never pick an equation that only had 1 or 2 possible combination of inputs to produce the answer, I counted (well, my program counted) how many equations each produced every given answer, and then only kept ones that had more than 10 equations.
Finally I placed that list of equations into a JSON data structure that I loaded into the HTML/JavaScript user interface that I put together, and I did my best to copy the CSS styles used on the real Wordle. After buying a domain at hover.com and uploading to Linode, I was all set.
* Technically, I suppose, since weāre only building the āleft hand sideā of an equation, I should call it an āexpressionā, but, this isnāt a formal paper or anything, so letās just go with this loose language.
Coinciding with the great explosion in work-at-home that came about with COVID-19, there was a big increase in popularity of the Elgato StreamDeck. I assume someone other than I can explain this connection better than I can. I think it has something to do with being on lots of video calls, and for some reason, the StreamDeck is apparently helpful for folks doing live video streams, like youāre basically doing on a zoom call.
My StreamDeck – Positioned just between my keyboard and monitor
But for me, the potential of the StreamDeck was all about extending the customization of my Mac, not just for streaming, but for everything I do day-to-day on my Mac. Iāve always been a big believer in using the keyboard as much as possible instead of the mouse, and one of my favorite things about macOS is how you can define global keyboard shortcuts, and add tools like Keyboard Maestro to give you access to more commands without using your mouse (or trackpad in my case).
But, one challenge with the standard keyboard shortcut approach is the mental load of remembering all of the various key combinations (sometimes called āchordsā) that you have to “play” for each different app, and all of your commands, some of which may be a bit obscure as well.
At one point, for one my most common tasks as a software engineer, debugging, I printed out a rather janky little paper guide that I physically taped to my keyboard above some of the function keys, to help me remember which key did which command, with what set of meta keys⦠I guess in a way this was my proto-StreamDeck, as the idea was in part the same: giving a visual cue to avoid having to completely remember every key combination.
Enter the StreamDeck
But the StreamDeck goes to the next level. (Letās be honest: itās pretty easy to go to a level beyond a piece of paper taped to your keyboardā¦)
For one, you can customize every button on it – both in what it does, and in how it looks. Thatās because every button is a tiny LCD screen. On my StreamDeck XL, thatās 32 buttons, in 4 rows of 8. Now finding or creating good icons can be a challenge. Elgato has a selection of icons, but honestly, I think they’re terrible. I’ve invested some time on my more popular profiles creating good icons – but I also get lazy and, well, you’ll see some of that if you look at my screenshots.
Next, you can add a whole new dimension to the StreamDeck, by setting up a unique set of keys to be available based on what your active application is. So thatās 32 buttons for IntelliJ, and 32 other buttons for OmniFocus, and 32 for Obsidian – I think you get the idea. This feature allows you to really add “contextual” power to the StreamDeck – where the buttons that make sense for the context that you’re in appear – and they’re out of the way the rest of the time.
In terms of what you can do with each button, there are dozens of built-in actions, such as activating an application, or simulating a key sequence, or changing system attributes like the volume. Thereās also a healthy marketplace of plugins, and the killer one for me is KM Link, which gives the StreamDeck 1st class access to run any Keyboard Maestro macro on your system. (Note, thereās also a plugin that’s just called “Keyboard Maestro”, which isnāt nearly as good. If youāre reading this, and trying to do this setup, go with KM Link!) By combining this excellent piece of hardware, with one of my favorite pieces of software, we really get into a near Apple-like level of greatness.
My Debugging Profile
For the rest of this post, I’m just going to lean into the jargon of using a debugger, and assume that you either know what these actions mean, or, you don’t care. That is to say, I’m not going to explain the details, but rather, just paint a picture. So, to start, here’s the picture:
To get started, the buttons I probably use the very most of all are in the lower-right – the debugger step/flow-control commands. Starting from the bottom-right, i’ve got Step Over (the one I use the most), and right above it, Resume. Then to the left, the less-common Step Into, Step Out, and Run to Cursor. Thereās also a control-flow power move: Drop Frame.
Next Iāve got a set of keys for controlling breakpoints: One to toggle the āMuteā state for all breakpoints in a debug session. Then two to Toggle a breakpoint on or off for the currently focused line, or toggle the Disabled state of the breakpoint on the current line. To help with these last two, I often need to make the current broken-line be focused, so thereās a button to Show Execution Point as well.
Iāve got a set of buttons on the top-right for building and running code as well. Thereās a hot key in IntelliJ to run or debug the unit test (or test class) that your cursor is currently inside of. This works for either a test class or method. I call it “Debug Focused“, as I actually launch my tests in debug mode (instead of run mode). It’s actually the same as clicking the little “run” icon next to a test class or method, in the gutter of the editor window, but so much easier to run by just hitting that button on my StreamDeck. Similarly, there are times when I find myself frequently editing Run Configurations and then launching one of them – so the (text-only, no-icon) buttons “Edit Configs⦔ and “Debug⦠(select from menu)” make those a single-tap to get into. Finally in this set, there’s “Build” (self-explanatory), along with “Rerun” – which is dangerous if you’ve got a server with a slow startup time, but which is great when working with small services that you like to frequently restart in case a hot-swap fails.
Similar to those buttons for running, I’ve got a couple of odd-balls: The first is for a case where I want to go to Postman and click the “Send” button, to issue an http request to my code that’s running in IntelliJ. Rather than do that by-hand, I’ve got a KM macro to do it, and this dedicated StreamDeck button to launch that macro. Similarly, I’ll often have a shell script in a loop, paused waiting for me to press Enter, and when I do so, it then issues a curl request to my running server – so that “iTerm, Enter” button automates switching to iTerm, hitting Enter, then switching back to IntelliJ for me.
In the miscellaneous section toward the left, I’ve got a few really useful buttons for cycling through diffs in the currently open file – “Previous Diff” and “Next Diff“. In addition to just letting me quickly review what changes I’ve got in a file, I combine these with “Rollback Lines“, to quickly revert changes that I don’t want.
There’s also a “Highlight” button, which I don’t use much, but it surfaces the IntelliJ command to highlight the word under your cursor, and all other instances of that word, with a bright color, to make them easier to see together. Finally here I’ve got “Block Comment“, which runs a plugin I built to create a big flower-box style comment block.
The last 2 buttons in this section also do KM macros, to find images on the IntelliJ window, and click them – one, to Clear the Log of my currently running application, and the other, to just Scroll the log to the Bottom – both actions I used to do a handful of times every day with mouse – now just a tap anytime I want them. And yes, I didnāt even try on these icons, and just got them from the web š
I don’t know if 1,000 words about debugging with a StreamDeck can convey how much I feel like it’s boosted my efficiency. I’m quite convinced that it has, however. If nothing else, I find myself much more eager to do use some of the techniques that I have dedicated buttons for now. And I know that I get a smile on my face as I do them. I’m never frustrated by hitting a wrong hotkey, or struggling to remember if a command needs the Option ā„ or Control ā button to be held down. There’s a real satisfaction that comes with seeing the icons I’ve created (even the bad ones). And I love having a physical world connection to my debugging experience. If it makes me more efficient as well, then it’s icing on the cake!
Ever since I started working as a professional programmer, I’ve been a pretty big coffee drinker. Part of the appeal was always the ritual of walking to the coffee maker in the break room with my teammates, and certainly, the caffeine has always played a big role. But even from when I first started drinking coffee, I always took it black, and always thought that it tasted “just fine”, no matter what kind it was, or where it came from. I’d say I enjoyed all of the routine and ceremony and side-effects (i.e., the warmth and energy) more than the taste of the drink itself.
A few months ago I was reminded of an experiment that I conducted in the office we used to rent, where they had coffee from two different providers, and some of my teammates expressed a real preference for one over the other. I used to maintain the position that I couldn’t tell a difference between them, and they were all good to me – that any coffee was good enough for me. But one day I decided to do a side-by-side taste test of these two options. Much to my surprise, I really could tell a difference between the two, and from that day on, I always was insistent on having the one I liked better.
I think that this experiment showed the potential for me to appreciate better coffees. Yet, once the COVID-19 lockdown came, and I switched to drinking all of my coffee at home, I settled for some very “okay” K-cups.
Gratefully, I had 3 sources of inspiration to experience something more:
First is my best friend James Maes, who has always had a taste for finer things in life. He has spent years working searching for a great cup of homemade coffee, and he is not shy to share with all the rest of us when he’s enjoying an amazing cup. James is also a fanatic researcher, and he sent me a great YouTube channel focused on making good coffee: James Hoffman.
Second, was a podcast episode I heard (a special members-only episode) of the show Under the Radar, where two somewhat well-known programmers in the Apple/iOS community, Marco Arment and David Smith, shared their experiences finding better ways to brew at home.
Finally, I re-read a blog that I wrote from the time I did that side-by-side taste test, and finally I decided that it was time to try to take my home coffee game to the next level.
My Setup
Once I decided to step into the world of making good homemade coffee, naturally, I went to James for his experience (he doesnāt give advice – only shares experiences). He told me that 3 things matter, and they are in this order of importance: Beans, Grind, and Delivery. Each of these elements can be a world in and of itself, and I spent a week or two researching them lightly. So now Iāll share what I ended up using, and I’ll tell the story backwards, starting with the end of the process, the delivery mechanism.
Part 3 (or 1?): Delivery
When we talk about delivery, we mean the thing you do to add water to your ground beans, to actually make your coffee. My understanding is that this may be the least important part of the process, but my goodness there seems to be a huge variety of options for how to do it. In this case, I followed the tip from that podcast I mentioned before, and went with an AeroPress. It seemed like a cost-effective, and easy-to-use device, yet at the same time, it is well reviewed both by those podcasters, as well as by James Hoffman the YouTube coffee guru.
It took me about a week of repetitions with the AeroPress before I felt confident with what I was doing, but now itās become second nature. The basic process is:
Grind one scoop of beans, while heating up 8oz of water (I actually still use my Keurig for this!).
Insert a filter paper into the bottom of the AeroPress outer cylinder.
Pour your ground beans on top of the filter and shake to level the grinds.
Place the cylinder onto your drinking cup, and add hot water into the cylinder up to the (1) mark.
Stir the water and beans for about 10 seconds.
Insert the inner cylinder (with a rubber plunger on the bottom) into the outer cylinder and slowly press down. Pause when you feel pressure. Eventually press all the way down until it hits the grinds.
Clean up by ejecting the “puck” into the trash, and wiping the plunger from the inner cylinder.
Add the rest of the hot water into your drinking cup, and immediately start enjoying!!
That sounds like a lot, but it only takes me about 3 minutes, and itās actually kinda fun to do š
Part 2: The Grind
Since I decided early on to use the inexpensive AeroPress for my delivery mechanism, I felt like I could spend a little bit of money on my grinder. Having no idea where to start this search, and only with the basic info of knowing that I should have a āburr grinderā (as opposed to a blade grinder), I ended up taking a recommendation from James Hoffman on YouTube, and going with the Encore Baratza.
Iām not sure what else there is to say about my grinder. It seems to work very well. It is kinda loud, but only for the less-than-a-minute that it takes to grind enough beans for one cup. It does make a great smell – but, all of this, maybe any grinder would do just as well? So, it seems like a win, Iām just not sure what better or worse options are out there.
Part 3 (or 1): The Beans
The last thing I needed to be ready to start brewing good coffee at home was a source of beans. Now I guess maybe the very best experience comes from roasting them yourself at home – but I havenāt decided to go that far just yet. From what I hear, you can get pretty similar quality, and avoid a somewhat difficult step of roasting at home, as long as you buy and use freshly roasted beans. If you use them within a few weeks of their roasting date, your results should be pretty good.
I spent a little bit of time trying, unsuccessfully to find a local rooster or to find freshly roasted beans at my local grocery stores, but I had no luck. Then I chanced upon https://www.drinktrade.com, which offers a subscription service where theyāll ship you a bag of freshly roasted beans on a schedule of your choosing (like every week or 10 days or two weeks). They even have a program for beginners like me, where you can tell them a little info about your tastes, and theyāll recommend specific beans for you. Then as you rate the beans they send you, they adjust your subscription.
The Results
I have to say, I wasnāt entirely sure what to expect. Remember, before I did that side by side taste test, I thought I wasnāt picky about coffee. So, was all of this a waste of time?
But: Boy oh boy, from the first cup of freshly roasted beans that I ground at home and immediately brewed in my AeroPress, I knew that I had made a very good decision to get into this world.
The best way I can try to describe the flavor difference between good coffee and my old K-cups is that the good coffee is so much more subtle, more smooth, more delicate. My old coffee was like music that was turned up too loud and was clipping. My new coffee is intriguing, inviting, and making me want to know more about it. It makes me want to drink every cup down to the bottom. My old coffee was like being yelled at – my new coffee is like having a compelling conversation.
Some evidence that I really do like it better (and that Iām not just telling myself that itās better):
I used to, every morning when I came to my office, have a half an inch of coffee left in my cup from the day before that I had to dump down the drain. Now, every cup I make, I drink it completely empty.
I ran out of beans a few weeks ago, and had to make an old K-cup. I could barely drink it. It was just so strong and rough – not elegant and complex.
Now, I make coffees on the weekend. I used to be content to take Saturday and Sunday off from coffee, in the before times.
In a similar vein, I find myself making cups of coffee and bringing them in a travel mug in the car, which is something that I never used to do.
My new brewing process is slower than making a K-cup. It takes me about 3 minutes to grind and brew a cup. But I even get enjoyment out of those 3 minutes. The smell of the freshly ground beans fills my office. Iām so happy Iāve made this change!