In college, a professor once told us that a good programmer produces around 8 lines of code a day. Considering that the average line of code has about as many characters as a text message, I just wrote the equivalent a full day’s work in this paragraph. I’ll be taking the rest of the day off!
I don’t know if that 8-line statistic is true. I’m not even sure I remember it right. But, like most statistics, it doesn’t matter if it’s true when it illustrates my point: there’s more to programming than producing lines of code.
Let’s look at an average programmer’s eight hour day. If it only takes a few minutes to physically write 8 lines of code, where is the rest of that time going? Some of it goes into planning, but even the most pensive programmer spends a small fraction of their total time thinking in silence. Let’s give planning 30 minutes. How about research? Nothing can be built without first understanding how the new jQuery library or Cloud service we’re interfacing with works, but reading more than 10% of the day away looks suspicious. I’ll knock off an hour (tops) for research. Code re-use doesn’t count either. It’s an important part of programming, but those aren’t new lines, they’ve already been counted by someone else.
After planning, researching, testing, cutting-and-pasting, and Facebook stalking, we’re left with 5 hours in the day that are completely unaccounted for. Where does all that time go?
One place: Debugging.
Debugging is the sometimes time-consuming, and always tedious, process of fixing errors in software. I’m going to explain the concept of debugging to non-programmers because I think there might be some parellels between the steps of debugging code and launching a successful marketing campaign on the web. I come from a C++ background.
A lot of people don’t know this, but the original C++ compiler (the program that turns code into other programs) actually plays that “you’re a loser” trumpet sound from the Price is Right every time you compile code. That’s because in C++, 99% of compiled code either doesn’t compile at all or fails straight away. The web is not so unforgiving. Because of that, I learned a lot about the process of debugging that helps me every day. I’m going to go over the general steps I take when things don’t work.
Step 1: Blame everyone else
When anything breaks, the first thing any responsible programmer does is blame everyone else. The user, other programmers, the server, squirrels, the moon; it’s everyone else’s fault, but the code is not broken. I’m joking, but it’s kind of true.
- Make sure the server was updated with the most current stable code. That’s an easy mistake to make and it means it’s not your code. .
- Clear your cache. Clear everyone’s cache. In fact, I think I’m just going to turn my cache off completely after writing this–at least until I can remember what it’s purpose is beyond driving me insane when it doesn’t refresh. .
- Upgrade your software libraries. Update the server, rename files, delete plugins–basically do all of the quick changes you can to fix the problem, and simultaneously hope that none of them work because if they do, you’ll never know what caused the actual bug in the first place. That thought gives programmers goosebumps.
No matter what order you do the above, you’re probably about to move on to the next step.
Step 2: Find exactly where the problem is
There is a very slow evolution that has been happening in software over the last decade or two. Programming has become less about writing code and more about designing systems built on frameworks representing code modules that interact according to the design. This is a good thing. It gives people who are not programmers the ability to design sophisticated software. It also creates better, less-buggy code. It’s the future. It also means that this step in the debugging process is becoming more foreign to developers.
The first real step to debugging software is finding exactly where the point of failure lies. That may sound simple, but there are a lot of layers to a program working together under the user interface. Fixing a big enough piece of software isn’t like fixing a car that isn’t working, it’s more like fixing a freeway that isn’t working. Any number of layers could be at fault and this step is about narrowing it down to the most likely suspects. Here’s a hint, they should have line numbers.
If you’re a programmer, I’m not going to rehash available debugging tools here. The tools specific to your language and platform are probably a part of your IDE. If you’re not using them, do the opposite of that. However, for all you non-programmers, I’m going to give you two little magic words you can use to find out exactly where a program is failing: “alert” and “echo”.
Some people might frown on the idea of a non-developer changing code by adding debug statements all over the place like the ones I listed above, but I say go nuts. You paid for those files, didn’t you? If your developer complains about it, then he needs to figure out a more robust backup system!
Step 3: Fix the problem
This step is the reward for all your hard work in Step 2. If you can fix the bug, fix it and move to Step 4, but what if it really isn’t your problem? It’s not your code, you can’t fix it. Better pass it off to the person who can.
Can you imagine if every episode of CSI ended right after the scientists figured out who the killer was, but then didn’t go arrest them? They just clocked out and went home? I don’t mean CSI: Miami either. That show should end right after the main credits. I mean CSI: Las Vegas. It wouldn’t be as good of a show without closure.
The point is, don’t ballpark a bug and then hand it off to someone else with an email that sounds like, “It’s the server guys doing something crazy again.” Maybe they are, but personally, I think I’m batting a solid .230 when it comes to suspecting that bugs are not my doing–even after tracking them down! That’s not a bad batting average, but it’s also not great. It makes me put in yet another run-through the code to make absolutely sure I can’t fix a problem instead of just punting it into another department.
Tracking down bugs in a complicated system is like that spaghetti scene in Lady and the Tramp. You start at one end, your server guy starts the other and eventually, you’re making out at one spicy meatball of a bug. Fix it or make sure it gets fixed, and get ready to make some more broken code because you’re not done.
Step 4: Track your users
Buggy software sucks, and bug reports suck more. The last thing anyone wants to do when their program crashes is replay the last ten minutes of their life to the same jerk programmer they blame for the crash in the first place! Most people have to be more productive than 8 lines of code a day and reliving software failures seems like a huge waste of time to them. Well, they’re kind of right.
Software is always going to crash, so plan for it. During the prototype phase, track user actions and variables like an obsessive parent attempting to create the most comprehensive baby book ever made for their newborn infant. Then, as your baby software grows up, ease off the monitoring and give it the ability to track itself. Tie user actions to a timestamp and log everything.
Log the URLs, log the server variables and session data, make sure that no data moves without you knowing who it was and where it was going. I try to build this kind of logging into the bottlenecks of code as I go, along with creating a generic logging function to call from anywhere, even if it’s simply a URL I query from inside distributed code. Sadly, since that logging code will eventually be deleted from the finished product, it doesn’t count toward my 8 lines of code a day.
Step 5: Make debugging part of your UI
When you’re dealing with software meant for a large amount of users across several disciplines and with varying degrees of technical expertise, more information is better. Dump it all out in a crash, who cares if it doesn’t make sense? People are smart. Even someone who’s never touched a computer before knows how to play “which one of these things is not like the other” when given enough information. They will call attention to something that doesn’t look right and one time in a hundred, they’ll get it right. That one time might buy you another line of code!
Try adding a hidden panel in the footer of your application that contains your debug information and state variables, or better yet, build it in as an easter egg. I’m always surprised when I see a debug mode in a program or plugin. I don’t think I should be surprised. It should be more common.
Step 6: Do not leave your threads hanging!
This is my most important piece of advice, and I wouldn’t even consider it advice. It’s more of a mandatory life choice for being able to sleep at night. For the love of God, if you asked a question about your bug in an online forum and then you figured out the answer on your own, go post the answer in the question thread that you started. If you don’t, subtract a line from yourself because you just cost the rest of us about a hundred of them.
If anyone is wondering, I counted the lines of code I wrote today. Keep in mind that I’m knocking an hour off of my day for the time it took me to write this post. That means my final figure came in a little below the average of 8.
It was -14*
*research code doesn’t count and consolidation is a killer…it was actually a really productive day!
Edit: Since the two lines of code that I wrote in this article both had bugs in them, my new total was -16. Thanks Joost, for the heads up. Fancy quotes cost developers more productivity every year than Minecraft.