TJL #16: How to understand difficult code
Follow this easy 3-step plan to tackle any difficult problem
Hi friends,
Welcome back to Today Jan Learned (TJL) #16. In this newsletter I try to share something interesting every day. If you haven’t subscribed already, you can do it right here!
Today I want to show you how I tackled a piece of code that I didn’t really understand. I don’t remember exactly how I got there, but I stumbled upon this page: Comparing different hierarchical linkage methods on toy datasets, and saw this piece of code:
At that point, I didn’t understand it, but I really wanted to. Why? Because it makes some damn flashy plots.
So how do we tackle such a problem? I wrote up my actual findings in a Jupyter notebook which you can find here. But, what is more interesting to you is how I tackled this problem.
Here is a simple 3-step process, that I believe can be used to understand almost any complex problem:
Break up difficult problem into its ingredients (core components)
Understand each ingredient in isolation
Slowly build up the complexity by adding ingredients one-by-one
Breaking it down
The first step in this process is breaking the problem down into smaller, less complex problems. A single big problem is scary and unapproachable. A series of smaller problems suddenly becomes much more doable.
One of the best ways to do this, is to split up the problem into its ingredients (core components).
In this piece of code I could find the following ingredients:
np.array
list
islice
cycle
int
max
Turns out that I actually know many of these ingredients already! For example, np.array (which makes arrays), list (which makes lists), int (which casts things to an integer), and max (which returns the maximum of an array). In other words, the ingredients I do not know yet are:
islice
cycle
Build up complexity
After breaking down the problem into smaller steps, you first want to understand each ingredient in isolation. Once you’ve done that, it becomes time to slowly build up the complexity by adding each ingredient one-by-one.
This is how I did it:
First, I read the documentation and watched some Youtube videos to understand what a cycle was exactly, then I coded up an example of a cycle.
After that, I did the same thing but then for islice. I read the documentation, watched some videos, and then coded up an example of an islice.
Finally, I rewrote the original piece of code in my own language.
The key here is to do this slowly. Don’t try to rush this. This process will be slower than you would like. Take the time to thoroughly understand each ingredient, and only then go to the next one. You want to slowly crank up the complexity dial. You need to give your brain some time to process every step. You want your brain to realise that this complex thing that you are tackling is actually a series of simpler things.
Mindset shift
Eventually, what you want to work towards is a mindset shift. Instead of being intimidated by large complex problems, you want to be confident that you have the tools to chip away at them. You want to have tools at your disposal to tackle any large problem and turn it into smaller problems that you can actually solve.
You just have to realise that complex things are made up of smaller, simpler things, just stacked and combined in many different ways. If you continue to stack up enough simple things at some point our brain goes from:
“Hey this is just a lot of simple things!”
to
“Fuck this is complex shit!”
Beat your monkey brain to the punch by telling yourself that complex things are made up of smaller simpler things.
This is what you should do:
Cut through the complexity and reduce the problem into smaller more manageable steps (ingredients).
After breaking down the problem, understand each ingredient in isolation
Finally, build it back up again. Slowly. Make sure that every step you take is valid and that you understand it.
Finally, when we arrive back up on the surface again you have a solid understanding of what happens under the hood. Our monkey brain goes back from:
“Fuck this is complex shit!”
to
Yes, this is complex, but it is made up of smaller simpler steps.
I have looked at each step in isolation and understand what it does. For the steps that I do not fully understand I know what details are important and which ones are not.
This seemingly complex thing is just a series of simpler steps, each of which I understand.
Recap
Tackling hard things is nothing more than repeated application of this three-step process:
Break up difficult problem into its ingredients
Understand each ingredient in isolation
Slowly build up the complexity by adding ingredients one-by-one
Liked this article? Follow @janmeppe on Twitter or subscribe right here!