How Novices Debug Code

A few months ago I debugged a real hairy issue involving dependencies on different machines running the same cloned git repository. I had begun to write a real lengthy post on how novices debug code vs. how experienced programmers do it. Today I came across this article that explains it much better than I ever could. You should check it out. My thoughts on it are after the jump.

So this little exchange from the article is great:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Student: My code isn't working.  Can you tell me what's wrong with it?
Teacher: I'm not psychic! I need more information. :)

         Can you answer these questions as best as you can, first?

         1. What makes you say your code isn't working?
         2. What did you expect your code to do and why?
         3. What did your code do instead and how do you know?
Student: <answers questions>
         Ohhh, I see what's wrong!
Teacher: Imagine if you had a habit of asking and answering these
         questions yourself.  Half the time you'd solve your own
         problem and the other half you'd be able to ask a much
         more specific question and get relevant help more quickly.
Student: I totally agree.

What makes you say your code isn’t working?

This is an interesting question. If you are seeing an error message then, yeah, that’s how you know the code isn’t working. Whether it’s an exception statement on a 500 page in a browser or a huge stack trace in the command line (which Ruby loves to freak people out with) these are obvious problems. What isn’t obvious is when you run some code, some stuff happens without any error messages, but then the output is not what you expected.

I’ve had plenty of issues where code I’ve written seems to simply get ignored when its run. Take this PHP script for instance:

1
2
3
4
5
6
7
8
9
10
// If you guess the number I'm thinking you win a prize!
$lucky_number = 13;
$your_guess = $_POST['guess'];

if ($your_guess = $lucky_number) {
  echo 'You win!';
}
else {
  echo 'You lose.';
}

So assuming there’s a form where someone submits a guess everyone ends up being a winner. It’s easy to think your code isn’t working because you put in a different number than the lucky number and you still won. What’s going on? If you don’t know yet, keep reading. So far we know our code isn’t working. We say this because we purposely entered data we know should create a certain result.

What did you expect your code to do and why?

Such a simple question and again so important. This gets to the core of why we think there’s an issue and gets us to begin thinking of the code line by line. In our case we expect the script to say we win if we enter the same number as the lucky number and say we lose if we put in a different number. Why do we expect this? Because we compare the user supplied number to our number in an if/else statement. The success message is in the correct block and so is the ‘you lose’ message.

What did your code do instead and how do you know?

It always says we win when we shouldn’t. We know this because we hard code the lucky number and intentionally enter a different number as a guess. But wait… do we really know that it shouldn’t say we’ve won? Now we start thinking, what did the code do that’s different than what we think it’s doing. And by now (in most cases I’m sure it gets caught far earlier) we realize that instead of comparing equality (==) we’re using assignment and overwriting the value of the lucky number (=). The code works. The way we wrote it just doesn’t give the result we want. So we just change line 5 to if ($your_number == $lucky_number) {...} and we’ve solved our problem.

Why do novices always ask a vague question instead of running through the 3 What’s?

This is where I disagree with the post. They say

it’s because they believe that no matter the problem, an experienced programmer “must” have the solution

That can’t be it. That sounds like someone who’s forgotten what it’s like to be a novice. Sure, they think an experienced programmer will have the answer but that isn’t the core of why they continually do this. I know that someone more experienced than me knows the answers to my problems but I still run through, at a minimum, the basics of debugging and ask myself the three questions we’re talking about here. It’s my belief that the reason novices ask someone before running through the introspective debugging questions is because they just don’t know what to ask. You can’t be specific about something you lack details about.

For example, someone who is unfamiliar with OOP but is learning a framework like Rails may ask something like “how do I get things out of the database in Rails by name” instead of “how do I use Rails finder methods to retrieve a record by column name”. They’re the same question but the second shows an understanding of several concepts including what a method is, how frameworks like Rails return database records, basics of an RDMS like what a column is, and what a finder method is. The first question is exemplary of a person who knows that data is being stored somewhere and there’s a way to “get it out” again.

When they ask even more vague questions like “what’s wrong with my code” it’s not solely because they think experienced programmers have the answer. It’s only because they don’t know what question to ask.

There is a distinction to be made however between novice programmers and forever novice programmers. On the one hand, the novice will ask vague, frustrating questions and learn from them each time. Their questions will become better and their ability to debug issues themselves will increase. Forever novice programmers are the ones who will forever ask the same vague questions because they’re either lazy, arrogant (you’d be surprised how many awful programmers think their the best), or don’t know how to learn. It’s unfortunate that the second group makes things very difficult for the first group.

Web development

Visit linked content

« Sublime Text Keyboard Shortcuts Quick and Dirty Option Parsing in Node (or Why Eval() is Not Evil) »

Comments