Picture of Michael Lee

Keystone habit

Written on August 9, 2022

In Charles Duhigg’s book, The Power of Habit, he describes a concept called, keystone habit.

Essentially a keystone habit is a habit that triggers other actions.

My keystone habit

One of my keystone habits is exercising.

I will either go for a run or do some bodyweight exercises.

Exercise for me leads to cleaning my bathroom.

I have a regular reminder in Things, that tells me to clean my toilet.

I don’t mind cleaning the toilet, but it definitely takes some willpower.

Meanwhile, if I exercise first, my chance of cleaning the toilet or even the shower is higher.

Why does the chance increase because of my keystone habit?

In The Power of Habit, Mr. Duhigg explains that a habit is made up of three parts—a cue, a routine and a reward.

In this case, my keystone habit, exercise is my cue.

My reward is a shower.

Since I’m already “dirty” from sweating, cleaning a toilet or shower doesn’t add to the dirtiness it just becomes part of the routine from cue to reward.

And since I’m going to shower anyways, having a clean bathroom is an added plus.

Turn off Keychron K3 backlight

Written on August 7, 2022

One of the keyboards that I use is the Keychron K3.

It’s a nice, low-profile, slim, mechanical keyboard.

One of its many nice features is the technicolored backlight that does crazy responses when you press on a key—one of which reminds me of the water fountain shows found in Las Vegas.

While very neat, some times I find the lights to be distracting.

I could also imagine when the keyboard is being used in bluetooth mode, it contributes to the battery draining quickly.

How to turn off the backlight on the Keychron K3

It turns out you can turn off the backlight on the Keychron K3 completely.

To do this, press the fn and the light bulb key in the top right hand corner.

This should turn off the backlights on the keyboard immediately.

If you end up missing the technicolor light show, press the fn and light bulb key combination again to bring the backlights back to life immediately.

How I was extra as a parent and created a math worksheets generator

Written on June 29, 2022

A few days ago my wife asked me to print out some math worksheets for our child who is moving on to 2nd grade.

This would allow her to practice her math during the summer break.

I found some on Google, but realized that most websites only had a few set of sheets—meaning there a limited variety.

So, being the engineer that I am, I decided to write my own math worksheet generator.

Screenshot of the math worksheets generator

The motivation behind the project was actually to get more familiar with building something in React.

I learn better when I have an actual project to work on so, this was my motivation.

The setup

I knew the set up would be pretty straight forward.

I’d have a component for the “worksheet” itself.

Then child-components for each of the problems.

For the data set, it would need to be an array of number pairs.

Then I could take each pair and generate a problem.


While the idea was simple enough, I ran into a few challenges.

First, since I’m new to React, understanding the life-cycle of a component and how to update the state of a component was the first challenge.

At first I had each of the problems created and the values for each value was being stored into the component’s state.

This was causing all sorts of rendering issues.

So I then generated all the problems in an array in the beginning and that would be the initial state of the component.

Anytime I wanted a new set of problems, just generate the new array and replace the old one in the state.

The second challenge I ran into was calculating combinations.

By design, I made it so that you can define the upper number and the lower number of a problem and the app would generate variations of it so you have a mixed math worksheet.

The reason I had to do this was because I had determined I can generate 42 problems from the range of numbers.

42 problems is about the number of problems I can fit onto a printed sheet.

So if the upper and lower numbers are too close in range, I wouldn’t have enough combinations to generate 42 problems.

I also needed to determine possibilities because, I also gave the option to have the large number in a problem to always be on top.

Doing some research, I found two math formulas to solve the issue.

The first formula was to figure out the number of combinations without repitition, since I didn’t want any problem repeating itself on the worksheet.

The second formula was to determine unique combinations based on two numbers—which happens to the be possible numbers multiplied by itself—or the possible numbers squared.

The last challenge I ran into was recursion.

I don’t often write recursions and it was one of the concepts that took forever for it to click in my head when learning to program.

In the worksheets app, I knew that I wanted unique combos only. To do this, I have a function that generates the problem. I then have another function that checks to see if the problem already exists in the set.

If it doesn’t exist, it’ll add it to the set.

If it does, that’s where the recursion happens, it’ll keep creating and checking until it finds another unique combo.


I intentionally kept the look and feel of it super minimal.

I didn’t want to focus on the design of the worksheet generator so that I can focus on the features.

After all, most worksheets of this nature are simple looking.

The bulk of the design was getting the placement of the math elements correctly using CSS grid and flexbox.

I also added some media queries so that only the problems will show when printing.

Since the worksheet has all the inputs from the generator as a state, I’ll likely be adding a dropdown with preconfigured settings that updates the state.

This is so that teachers and parents alike can quickly generate worksheets that they would like to print out (e.g. single-digit multiplication, triple-digit addition).

I’d like to also bake in the ability to change the orientation of the problems. Currently it is a vertical layout, but I’ve seen worksheets where the problem is in a horizontal layout.


While the math worksheets generator is a pretty simple application, there’s still room for improvements that I haven’t made yet.

For example for divisions, currently it generates problems which would yield decimals. I think this is pretty advanced for elementary students, so I’d like to come up with a way to only generate division problems without remainders.

Share your feedback

If you see improvements or have feedback please let me know.

If you’re a parent or educator and have some suggestions, please reach out.

I’d love to know how I can improve the worksheets generator.

How to tame your email inbox as a software developer

Written on June 23, 2022

“I get so many notifications from Jira, I rarely check my email because I get so overwhelmed. Slack me instead.”

Ever find yourself saying something similar to a co-worker?

You don’t want to touch your work email because it’s a water hose of useless information.

If something is urgent, surely you’ll be notified of it in Slack.

But you’re missing emails from colleagues about questions only you can answer.

You miss a meeting with your manager because you didn’t see the calendar invite.

When you finally do check your email, you spend hours filtering through emails causing unnecessary anxiety.

In this article, I wanted to share the system that I’ve used to tame my inbox as a software engineer.

As a result, I rarely miss out on important emails, I’ve never got more than 5 messages in my inbox, my inbox doesn’t give me anxiety and I’m in and out of my email in less than 10 minute intervals of my choosing.

Create filters to reduce the noise in your inbox

The reason why your inbox creates anxiety is because there’s a lot of unnecessary noise.

Clean noise is the messages that are important to you—emails from co-workers or your manager.

Bad noise is Jira updates, service emails…just about all the service notifications you get.

In order to get clean noise, you need to filter out the bad. To do that, utilize filters.

Here are instructions on how to create filters in Fastmail and Gmail.

Filter settings

These are some settings that I choose when setting up filters.

For the emails I’m filtering, I have the filter archive the email, what that does is, it prevents it from hitting my inbox.

I then apply a label to it. This will create another “inbox” of sorts where I can check later.

There are a number of other useful controls, play around with them on different types of emails to fine tune your needs.

Start with a clean slate

Now that you’ve diverted the fire hose of useless information from you inbox, let’s clear it up so you can start fresh.

There are two options to creating a clean slate.

Option 1: Select all messages in your inbox and archive.

Archiving removes the visual clutter in your inbox, but if there’s something important you need to reference, you can search for it because it’s in your archive.

Option 2: Select all messages created a month ago and prior.

This option is less hardcore than option 1. Perhaps you don’t want to remove all messages from your inbox but you do want to reduce it.

You can choose any period—a week ago, a day ago.

If you can’t decide, then go for a month.

Go to the most recent email you got a month from today’s date. Then select all the emails prior to this email and archive all of them.

Rinse and repeat

It is likely for the first few months upon using this system, you’ll fall behind and your inbox gets out of hand again.

If this happens, do another clean slate.

Take quick actions with all new emails

Now that you’ve got clean noise—only the emails you care about—coming into your inbox, you want to make sure that you take action on each and every email that comes through.

For every email, you can take four actions:

  • Reply: If the email requires your reply, send a reply and then archive the thread immediately.

  • Create a task: Sometimes an email requires you to take action outside of your inbox. Don’t let your email become your to-do list, instead capture the task into your external to-do list, then archive the email.
    • What I like to do is also grab the URL for the email and add it as a note to my task in my to-do list app. That way, I can reference the email later when I’m working on the task.
  • Archive: Are you seeing a pattern here? Archive as much as possible. Most emails you get are to keep you informed. For emails like this, read it, then archive it. This way you can reference it again later.

  • Delete: If the information is not useful to you and you don’t need to reference it later, DELETE THE EMAIL 😀

Remember, the process is to be quick and not keep you in your inbox.

If you find yourself in your inbox for too long, that means you’re working out of it.

Pause, then remember to take one of the four actions and move on.

Set time for email

Look at your schedule and slot in at least two designated times throughout your work day to check your email.

I like to check once at the beginning of my work day and then a few hours prior to the end of day.

Email isn’t for urgent information.

If it’s urgent, there are more synchronous forms of communication likely at the disposal of your co-workers.

For this reason, you decide when you check your email.

Work happy

🥳 Celebrate!

Your email should be in a much better shape now.

I hope you’re able to communicate better with your colleagues.

I hope your email gives you the information you need to do your job well.

With your email tamed, more than anything, I hope you’re able to work happier.

Avoiding the hard for the easy

Written on June 14, 2022

I’ve got this work task that’s been rolling from week to week.

I’ve had it time-blocked on my calendar for numerous days.

It is in my to-do list app, Things for weeks.

Yet, I’ve looked up from each work session to realize I hadn’t worked on it at all but worked on other things.

It’s a task that no one at work has asked me to do—not my boss, nor my co-workers.

It’s a task I had created for myself.

I created it because I know in tackling and solving it, it would unlock value for my team and hopefully increase productivity and output.

It’s a task that would solve for a pain that most everyone on my team has experienced and know about, but has yet to be solved.

It’s the type of task, that if successfully completed, could potentially warrant a raise.

So why is it so hard to actually work on it?

Because no one has asked for it.

Because my lizard brain is telling me it’s a hard task with a lot of dependencies and I should rather work on something easier at work—which is a programming task.

How am I going to solve this?

Three things…

First, I’m going to change my perspective on the why I’m doing this work.

When I first approached this task, I saw it as an opportunity for personal gain. If I do this project, my co-workers will think I’m brilliant, was the logic.

Instead, I want to collaborate with other co-workers by shopping around my ideas and getting their input and buy-in.

By having others working with me, it naturally creates external accountability.

Second, get back to the three strategies I’ve used in the past to beat the lizard brain.

Those are,

  • Setting a deadline for myself
  • Telling others about it
  • Cutting scope so that I can meet my own deadline

Lastly, I’ve been giving myself hour-plus time-blocks to work on this task for numerous days. It’s become scary. Instead, I’m going to give myself a 15-minute block this week.

If I work longer—which is likely what will happen—I’ll let it happen, but the point is to just get started and build momentum.

How I've achieved success with my shutdown routine

Written on June 6, 2022

At the end of each work day, I have a ritual of shutting down from work.

This is something that I’ve struggled with doing for the longest time—committing to shutting down at the end of the day.

In the past I would reason that whatever task I’m doing at hand is more important than to wind down from the day’s work. But what I found was I was disorganized the next day, I couldn’t easily transition from work to life (especially in a remote setting) and I spent a lot of mental energy organizing and getting into work the following work day.

Here’s how I’ve achieved success in doing my daily shutdown routine.

Make the routine the same everyday

My shutdown routine consists of 11 tasks that I complete at the end of each work day.

While it may sound like a lot, I can get through my entire shutdown list in about 15 to 30 minutes based on how complex the day was.

With the combination of templates and some automations, I’m able to replicate my routine quickly across my systems.

Schedule it in your calendar

Block out a chunk of time at the end of your work day in your calendar to do your shutdown routine.

I’ve scheduled my shutdown routine as a recurring event at the end of each day from 4:15 PM to 4:45 PM.

I’ve come to heavily rely on my calendar since time-blocking work. For this reason, adding a time-block to shutdown automatically kicks off the routine in my brain.

Benefits of having a successful shutdown routine

Since unlocking my shutdown routine, I’m more organized the next day.

This is important because as an engineer, I have daily stand ups and I’m able to share concisely about my progress and issues. Previously, I’d spend the morning scrambling to come up with a worthy update to share with the team.

I’m able to ramp up into my work quicker the following day.

At the end of each work day, I’m able to clear out my brain which means I can join my family immediately and be both physically and mentally present for them.