Progress
Memory Game. I wrapped up the final pre-work project before bootcamp begins next week. It’s a traditional memory game where you have to flip over two cards at a time trying to find two that match.
Building it was a fun, iterative process that had me going back over the code I'd already written for the base-level functionality and enriching it with new features and capabilities. I started with the ability to flip over a single card and then added layers of feature logic one at a time: allowing two cards at a time to be flipped, randomly generating the colors on the back, letting the user set the number of cards, letting the user restart the game, keeping track of the score, and using GIFs instead of colors as the card backs.
It was cool to see that even as I added most of this functionality, the length of the underlying JS file didn't change much from when I'd finished it with just the basic card flip capability. You can see in the commit history that most of my updates had me adding as many lines of code as I was deleting.
I also had a very “proud dad” moment with Mika as she excitedly dove right into beta testing my 1-player game, finding a way to turn it into a 2-player game, and beating me at it. We are now playing it every night at dinner time and she's making feature requests. 🤦♂️
Deep Work. I started and finished reading Deep Work by Cal Newport this week. I’ve long been a fan of Cal’s writing so I was excited to dig right into this one. I feel like now was the perfect time for me to come across it, too, as the satisfaction that comes with doing deep work is one of the things that has drawn me to programming in the first place. Cal defines “deep work” as follows:
Deep Work: Professional activities performed in a state of distraction-free concentration that push your cognitive capabilities to their limit. These efforts create new value, improve your skill, and are hard to replicate.
This is opposed to “shallow work:”
Shallow Work: Noncognitively demanding, logistical-style tasks, often performed while distracted. These efforts tend to not create much new value in the world and are easy to replicate.
There’s no way to escape shallow work—in fact some jobs, including most executive-level jobs, are made up almost entirely of shallow work. But the goal should be to minimize the deep as much as one can and/or is appropriate. Because of “The Deep Work Hypothesis:”
The Deep Work Hypothesis: The ability to perform deep work is becoming increasingly rare at exactly the same time it is becoming increasingly valuable in our economy. As a consequence, the few who cultivate this skill, and then make it the core of their working life, will thrive.
This focus on delivering truly differentiated value to the world is something that’s becoming more important as things like AI start gobbling up knowledge work—and marriages!—and the idea of learning a skill once and doing it for the rest of your life goes away. My favorite futurist who is actually a historian, YNH, first introduced me to the concept in Homo Deus and it feels really relevant here, especially when you consider that learning something new is in itself deep work:
Traditionally, life has been divided into two main parts: a period of learning followed by a period of working. Very soon this traditional model will become utterly obsolete, and the only way for humans to stay in the game will be to keep learning throughout their lives, and to reinvent themselves repeatedly. Many if not most humans may be unable to do so.
— Yuval Noah Harari, Homo Deus
But what’s more personally important to me is the sense of satisfaction that comes from entering the flow state (h/t to Csikszentmihalyi). He writes that, “human beings, it seems, are at their best when immersed deeply in something challenging.”
Ironically, jobs are actually easier to enjoy than free time, because like flow activities they have built-in goals, feedback rules, and challenges, all of which encourage one to become involved in one’s work, to concentrate and lose oneself in it. Free time, on the other hand, is unstructured, and requires much greater effort to be shaped into something that can be enjoyed.
The me from 10 years ago would have scoffed at this idea, but as I’ve gotten older I’ve come to appreciate the process of working toward accomplishing things because it’s in that process that I demonstrate the values to which I hold myself.
Problems
Stolen wallet. My cross-body bag, containing my wallet and keys, was stolen from me yesterday en route to Pennsylvania to pay my mom a long overdue visit. As a result, I had to cancel the trip at the very last minute and fly back to California just eight hours after having landed in Newark.
Needless to say, it was an extremely stressful and depressing 36 hours, and the hassle of having to re-secure my accounts and replace the things that were lost is one that I’ll be dealing with for the foreseeable future.
When I’m feeling down, I turn to a note that I keep on my phone where I collect quotes that inspire me and remind me to take a broader perspective. This one stood out to me yesterday:
Everything can be taken from a man but one thing: the last of the human freedoms—to choose one’s attitude in any given s4et of circumstances, to choose one’s own way.
— Viktor Frankl, Man’s Search for Meaning
It’s very hard to read this sentiment from a guy who survived Auschwitz and keep feeling bad about myself. So here are some silver linings:
I am learning a ton about the EDC movement (not the music festival, but just as cool IMO), and I’m currently geeking out over a set of minimalist supplies for keeping my important items with me securely at all times moving forward.
This interruption gave me a lot of downtime which I was able to put to some good use. I read the entirety of Deep Work and I made a lot of progress on an open source Logseq theme I hope to launch in the coming days as part of my developer portfolio.
I was inspired by the—surprisingly—authentically good people that work for United’s ground and baggage services team. They really exhausted every option they could to help me out, including stopping a fully boarded plane from taking off so the flight crew could search my seat area.
NodeLists
and HTMLCollections
. While working through the Memory Game project I encountered the first of what I expect will be many quirky behaviors of some of JavaScript’s built-in functions.
In the function that checks the two flipped cards to see if they match, I had planned to flip cards that do not match back over by iterating over them and adjusting their class name accordingly:
const flippedCards = document.getElementsByClassName('flipped');
function checkMatches() {
if (flippedCards[0].className === flippedCards[1].className) {
for (const card of flippedCards) {
card.classList.toggle('matched');
card.classList.toggle('flipped');
}
}
}
Unfortunately getElementsByClassName
returns an HTMLCollection
which is a live list of elements that updates in real time to reflect the conditions specified at declaration time.
So in this case, each time I toggled off the flipped class from a given card, the card dropped out of the list and everything behind it moved up by one index value. In other words if I had two cards in flippedCards
, my function would flip the card at index 0, drop it from the list, and move the second card to index 0 which, from JavaScript’s point of view, had already been handled. The second card wasn’t getting flipped!
The function querySelectorAll
, on the other hand, returns a NodeList
which is “static.” Each element is essentially a reference to the live element but the references are static from the time they were declared.
I had a helpful chat about this with my cohort-mates in our Slack channel and landed on a couple solutions:
Iterate backwards through the
HTMLCollection
, so the next index value always will exist, orUse
querySelectorAll
I actually like the “live” aspect of the HTMLCollection
because it means that I can declare flippedCards once and then know that it’s reflecting whatever is live in the DOM whenever it’s called, as opposed to having to keep track of when it was most recently declared. So I ended up going with option 1.
Plans
Rithm School. Classes begin Monday morning! I have to say, it’s been a long time getting to this moment, and I’m now at the point where I’m itching to get started. The time is upon us!
Surf Report
Here are some interesting tidbits I’ve found on the internet this week. Thanks to ChatGPT for the clever name for this section.
Here's a sampling of some of the interesting stuff I've found from around the internet.
Chart: Apple vs. China. I’m not sure there’s a lot to take away from this other than the fact that, wow, Apple is really, really big. (Source: Compounding Quality)
PianoGPT. An amazing demo applying predictive piano playing to a low-fidelity 8-button controller. This was actually made in 2018, long before ChatGPT. There’s even a live web demo you can play with here.
Wirecutter’s Identity Theft Article. Say what you will about the NYTimes, I’ve always found Wirecutter’s product reviews to be particularly practical and unbiased. Their article on identity theft solutions is also really useful because it shares a comprehensive list of actions you can take to be proactive about securing your identity. This is an area to which I really haven’t paid enough attention.
This bag theft issue (knock on wood) could have been a lot worse, and it really can happen to anyone. If you haven’t already, I encourage you to take a look at your information security measures and make sure you’re doing what you can to protect yourself.