So I often get comments or questions about my blog. Unlike most online forums, I don’t like insulting newbies. I can understand how hard it is to learn new concepts, how things that may seem common sense to other programmers may seem inexplicable to a beginner.
I can understand that just because the code works on my machine, it won’t necessarily work on yours. This is a problem even programmers with decades of experience struggle with. Big software companies have policies to deal with the Works on my machine syndrome — everything from virtual machines, to checking in the exact version of libraries used, to Docker.
I get it, it’s hard. You read a tutorial, it looks so easy, but when you run it on your machine, everything explodes.
What I don’t get is this: I get an email saying “Hey, I got your code, it doesn’t work.” Period. No explanation of where it fails. And then I’m forced to interrogate the questioner to ask them what is wrong (yes, interrogate, like a KGB agent. So comrade, have you or your programs been working for the bourgeois capitalist pigs, yes?)
Is your Python version correct? What version of the libraries? Is anything happening? Is your computer switched on? Yes, I feel like a call centre worker.
I remember reading this book by a FBI autopsy expert. She said that in some cities, they carried out thorough exams on dead bodies. In otehrs, the coroner, usually the local doctor, came in, kicked the body and said, Yup. He’s dead. And that was completely useless if the FBI was later called.
And that’s how it feels when you say, “My code doesn’t work.”
I don’t want to respond like one of those angry a-holes on the web, so I end up still trying to help the person, but I usually lose interest and move on.
Debugging is one of those skills almost every new programmer lacks. Only because debugging really isn’t needed for most toy / learning type programs. It’s only when you start getting into real world does debugging come in handy.
Of course, if you are one of those who believe TDD or any other religion will save you from having to debug, you will be in for a rude shock once your perfect program with its perfect tests still doesn’t work.
Debugging may also be slightly harder than programming, depending on the language you are using. If you are using compiled languages like C/C++, the compiler will do magic at the machine level, and your code won’t work as planned. It’s a real fun to debug the code where your C code says one thing, while the assembly is doing its own thing (which usually happens because the compiler optimised away your code, turning it into something else than what you planned). It doesn’t help that debugging using gdb is hard.
But then you don’t use gdb command line. You use the debugger built into your IDE, like Eclipse, or you use something like DDD (on Linux). That will allow you to graphically step through your code.
And if you are using a dynamic language like Python or Ruby, you have no excuse. Debugging is super simple, you don’t have to worry about the compiler doing weird stuff, or shudder, magical cache stuff going on in the background.
And in worst cases, you might have to debug using print statements. And that’s fine. It’s still better than throwing your hands in the air and going Mummy! I don’t know what to do.
The power of debugging
If you really become good at debugging, there is nothing as powerful as it. Have you seen all these questions on stackoverflow with zero answers? And dozens of people saying they are stuck with the same problem too?
If you are using an open source library (and chances are, you are, since it’s fashionable now), you can debug right into the library to find out what’s wrong.
I was recently struggling with a Twitter library for Python, whose philosophy regarding exceptions is We throw ’em. Then they’re your fu@&ing problem. Ie, the exceptions were thrown at the wrong place, the wrong exceptions were thrown, and the trace told you nothing about what had failed.
And I was getting a bug, and I went through the whole library’s source code (in my debugger) before I realised the bug was in my code. If the library had thrown better exceptions, I could have figured this out earlier (instead, it failed at some random point). But at least I got to study the internals of the library.
If I had asked this question in a forum, I would have been insulted, or ignored. That’s because it looked like the error was in the library, and a beginner would have asked What’s wrong with this library? Rather than admit they didn’t know the answer either, the online gurus would have found it easier to call the beginners an idiot and RTFM. That’s the problem with most complex problems: No one knows the answer.
When working with complex systems, being able to look into the code of libraries and go deep into the application is a needed skill. For all you know, the bug might be in the library. Or how you are calling it. Or an undocumented feature that is only visible when you look at the code. You won’t know until you jump into the entrails of the code, armed only with your debugger. Like a warrior. Or this guy.
So learn how to debug, and how to do it well. That way, when you get stuck, rather than saying My code don’t work, you can say The function to call the Reddit API authentication is failing. And that will make it easier for me (and others) to help you.
So whatever language you use, find the easiest way to debug it, and get used to the debugger. It’s a skill that will save your life.
If you want a Python debugging tutorial, leave a comment below.