Problem solving: Dealing with the unknown
The central challenge in coding is problem solving. By “problem solving,” I mean working through a problem when you initially have very little idea where the solution will come from.
A simple way to look at this is that there are two kinds of problems. In one kind, you understand immediately what caused the problem and what the solution will be. An example is that one of your lights burns out. Yes, it’s a problem, but it’s obvious what caused it and what the remedy is (change the lightbulb). Let’s call that a Type I problem.
In the second kind of problem, you have little idea what caused the problem and where the solution will come from. Let’s say you’re having trouble with lights that go on and off randomly and you’ve never seen this before. Is it the lightbulb, the wiring, the switch box, or something else? You don’t know at the beginning. You will have to experiment and make a few guesses. Let’s call this a Type II problem.
Most coding is Type II problem solving, not just book knowledge
It may appear that coding is about book knowledge and that any given program can be written by using ideas you’ve previously memorized.
This is occasionally true. Sometimes in coding you have a pretty good idea what to do, and you just need to look something up. Or you know that enough repetition will make the details stick. It’s not too hard to memorize and copy things, like you do in studying for your boot camp exams or watching YouTube tutorials. But those are all Type I problems.
The central challenge of coding is not doing things you can just look up. Instead, the central challenge is solving problems in which you initially don’t know what to do, or Type II problem solving. This is even true for experts, who are often trying new things and writing programs that are unlike any programs they’ve written before.
An example of a Type II problem: bugs
To make this more concrete, let’s consider bugs.
A lot of your code won’t work at first. This is completely natural. There are so many details to get right that it’s not worth lingering over them before you just run the code and see if it works.
If your code doesn’t work, it’s time to track down the bugs.
Bugs can come from anywhere and show themselves in many ways. So when you begin to track down a bug, you may have little idea what causes it. You can use certain techniques to narrow down the possible causes, but there’s no formula that tells you which techniques to use. So one of the most common problems in coding, debugging, is Type II problem solving.>
Bugs can happen even when you’re just copying code from somewhere. You can make mistakes that lead to mysterious bugs.
When you run into these kinds of problems, it’s easy to feel that you must have done something wrong or that you aren’t skilled enough as a programmer. But it’s okay to acknowledge that Type II problems are normal. No need to second-guess yourself; just start working on the bug.
Another Type II problem: reverse-engineering a task
Solving a problem with a program is like taking a real-world situation and reverse-engineering it. Let’s say you love a dish you ate at a restaurant. Now you have to figure out all the steps to make that recipe. You need to figure out the ingredients, the methods of cooking, and what order to put them in.
A program is like a step-by-step recipe, written to accomplish a particular task. Usually that task is something that humans have been doing intuitively for a while. In programming, you consider the way a human does it, then reverse-engineer that to produce a list of steps that can be understood by a computer.
This is a Type II problem because the “recipe” is never obvious from the beginning, particularly if you want an elegant solution. You have to experiment, guided by intuition. You may make a few bad recipes before you figure it out. Even an expert may start out with some confusion.
But you can get there without stressing about it when you apply these important principles: (1) working in tiny steps, (2) permission to be wrong, (3) permission to feel confusion. Here’s an article about these principles: Code with greater ease.
Where does good problem solving ability come from?
As you would expect, pretty much all experienced coders have gained good Type II problem solving ability with time and experience. If you ask them where they got this, they might not know what to say other than “experience and ability will come with time.”
That’s true, but problem solving ability can come faster with the kind of training I provide. Learning to code will be a smoother process.
How I became interested in Type II problem solving
In high school, I enjoyed solving math competition problems, and like most people I assumed that problem solving was an abstract skill that couldn’t be described or taught. But I discovered a book by the mathematician G. Poyla,“How to Solve It.” In this book, Poyla analyzes techniques that help problem solving in a general sense. These techniques work with many kinds of problems, and Dr. Poyla was actually describing this “unknowable” skill.
I’ve adapted some of these ideas into my teaching, in particular simplifying problems and working in tiny steps. For a beginner, it may be a shock to discover that few problems in coding have easy solutions. But it’s not a foregone conclusion that this will be a painful experience. I can help smooth it out and show you a simpler way to solve problems.
Your coding sessions with me
In a session with me, we’ll use these general problem-solving techniques. The problem you bring to me will probably have some unique aspects to it, as all coding problems do. I’ll guide you to work step-by-step in the way your problem needs. I’ll guide you to keep your solutions as simple as possible and to give yourself permission to make mistakes so that you’ll learn from them.