Do I need to write it?
Is there another way I can accomplish the goal without writing any code? For example, I was about to write a script to send templated emails from a spreadsheet, but I realized that showing the non-engineer I was collaborating with how to do it themselves through Mailchimps UI would make both of us a lot happier.
Has someone else written it?
If I’m doing anything that feels at all computer-sciencey, the answer to this is almost certainly ‘Yes’! The only questions are whether I can find the code, and whether I have a license to use it. Even if I can’t find the code, there’s a good chance I’ll find helpful pointers about how to tackle the problem in blogs or inside open source projects on Github. I want to spend my time on what makes Jetpac different, not re-inventing the wheel, and what’s unique about us are our core image and data algorithms, and the application logic and design that deliver useful results to people. I try my damnedest to reuse open code for anything else, even if it’s not ideal and I have to contribute patches back, because otherwise the miscellaneous programming to handle things outside of our core business would eat all our resources and leave us moving at a glacial pace.
Do I understand why I’m writing it?
Every person I’ve worked with has wanted to be helpful, and bring me as fully-formed a solution as possible. Things go wrong when I mistake their suggested solution for the real requirements. The only way I’ve found to know the difference is to understand the problem they’re facing, to learn the domain as deeply I can, to have as many water-cooler chats as possible with the folks on the coal face, and generally immerse myself in the background behind their request.
How will I know when I’m done?
The most painful conflicts I’ve had have been after I’ve delivered something that I thought was completed, and the person I’m giving it to was expecting parts I didn’t include. If I had to tell the truth, sometimes I knew we had different expectations at some level, but a desire to avoid conflict made me put off the difficult discussion as long as possible. Engineers have a lot of freedom, people ask us for things, pay us money, and then leave us to do incomprehensible rituals for weeks in the hope that we’ll give them what they want. If at the end we hand over something that’s not what they wanted, we’ve failed, even if it’s exactly what they asked for in a narrow sense.
The best solution is to describe in as much detail as you can what you’ll be delivering right at the start, with a particular focus on the tradeoffs you’re thinking you’ll make. I find ‘User stories‘ a great way to do this even if you’re not using a formal methodology that requires them, because they’re specific enough to be useful as engineering guides, but are in a language anyone can understand.
How will I debug it?
Writing the code is the easy part, it’s fixing the bugs that takes time. Any planning I’ve done up-front to make debugging easier has always paid off. Always. Guaranteed. Debugging isn’t glamorous so it tends to get less effort applied to it then it should, but as the biggest time-suck of the whole development process it’s always a good place to invest resources at the start. As a practical example, I’ve been doing a lot of GPU image processing recently, but graphics cards are terrible platforms to try to track down bugs on. I don’t even have the luxury of logging statements, let alone a proper debugger! To speed up development, I’ve actually been writing CPU reference implementations of all my algorithms first. When I do encounter a bug in the final GPU implementation, I can check to see if it occurs on the CPU too. If it does, I can debug it in a much saner environment and then port the fix over to the graphics card. If it doesn’t, I know the GPU must be doing something different, and I can dump buffers on both implementations until I’ve identified the exact stage where the results differ.
Other things you might think about at the planning stage are whether unit tests might be helpful, if specialized logging or other instrumentation frameworks makes sense, and whether there are any debugging tools you can add to your environment to help, for example automatic emails whenever your code hits an error in production.