Checklists and Software Development

In 2011, Atul Gawande published The Checklist Manifesto: How to Get Things Right. I first became aware of it when I had the opportunity to hear him speak during his book tour for his latest book, Being Mortal, at the end of 2014, but only got around to reading it this week. The book is about managing complexity in the medical field, but can also be applied to software development.

Checklist Manifesto book coverThe central thesis of the book is that modern knowledge has made the world too complex for humans to handle unaided. Take any complex profession – medicine, architecture, etc – and you find specialization and sub-specialization: there’s simply too much expertise required for anyone to be a generalist. Even within the sub-specialties, there’s so much to keep track of that it’s easy to miss a step, and that one missed step can result in a collapsed building, crashed airplane, or dead patient. We have finally advanced enough that “errors of ignorance” – mistakes because of what we don’t know – are often less important than “errors of ineptitude” – mistakes from not making proper use of what we know.

The solution is the simple checklist: a written list of the steps to take each time an action (whether it’s landing a plane or checking a patient) is performed. Interestingly enough, the checklists aren’t useful only for those who are new to an area, but even for experts with many years of training and experience who may nonetheless overlook a minor, routine step under stress.

So how can we apply this to software development? I personally use a checklist (in the form of a spreadsheet) that I compare against every new activity my team creates. The list contains around a hundred items to check, from making sure that CSS files are linked in the correct order to ensuring that our naming conventions are followed and strings are properly internationalized. It’s a lot of minor details, the vast majority of which we can expect to do correctly on any given day without the aid of the checklist, but I find that I usually catch a few things in each new activity. Unlike the steps on a doctor’s checklist, these aren’t going to kill anybody if they’re missed – most of them will simply result in a slight inconvenience to us (the developers) in the future – but running through the checklist before the end users ever see the software lets us fix the issues more easily and makes the software look more polished to end users (and testers) as we find issues before anyone sees the results.

Of course, we can also look at non-technical checklists: does the code do what it’s supposed to do, regardless of the implementation? To some extent this is what we’re doing when we write unit tests: we define what each unit should do, and then check that it actually does what we expect. I find that one of the best ways to avoid getting a lot of change requests is to have a checklist of exactly how the finished activity should work, and verify that it meets every one of the requirements (many of which might be too simple to remember when coding) before marking the development as complete.

What processes do you use for finding bugs in code? Can they become a checklist?

Paying to Learn

Earlier this week, I was reading a friend’s blog post in which he argued that it’s silly to ever pay for education, given the vast number of free resources available online.

I disagreed. While I think it’s great that there are so many free resources – in fact, I’m trying to make this blog one of them – and I’m no fan of spending money when you don’t need to, I also know that sometimes you get what you pay for.

Sometimes the free resources really are the best. When I’m stuck with a technical problem, I search online to see how other people have solved it. If I want to know how a particular CSS property works, I again look it up online. I’m not sure I’ve ever spent a day at work where I didn’t use Google.

Reading On the other hand, when I’m trying to sit down and learn something, I usually turn to paid content. In particular, I like books. Yes, most technical books are providing the same information you can find with a Google search, but the author is providing an additional service: collecting what’s known about the topic, paring it down to what’s most relevant, and presenting it in a way that makes sense. (At least, if it’s a good book this will be the case.) Because there’s a financial incentive, someone who is an expert on the field can afford to spend a great deal of time sharing his or her expertise in a way that might not be possible on a free medium.

Similarly, while I know that many people have successfully learned material watching free videos on youtube, I haven’t been a fan of that method for two reasons: most videos on youtube don’t have subtitles (crappy automatically-generated subtitles don’t count) and if I’m trying to learn something, I’m presumably not knowledgeable enough about it to know which presenters actually know what they’re talking about. Lately, however, I’ve been trying Pluralsight, which has a ridiculous number of professionally produced videos, many with subtitles. Full disclosure: I probably wouldn’t have gotten around to trying them if I hadn’t gotten a free trial, as it’s hard to find enough time to justify the $25+/month – but now that I’ve tried it out I suspect I’ll want to continue once my trial runs out. Because I have limited free time, it’s worthwhile to me to spend money to increase my learning speed.

Of course, none of this is to say that you can’t do just fine with free resources, especially if you have more time than money. Although I’m no longer a starving student, I still feel the pull of getting something for cheap or free; just realize that you may be paying for those free materials with your time. Sometimes, spending money really is worthwhile.

Error! Error!

One of my least favorite errors is ORA-01775: looping chain of synonyms. This often means that you’ve referred to something that can’t be found for one reason or another – a table doesn’t exist, a table is owned by a different user, there actually is a synonym loop…

The nice thing about Oracle error messages is they all come with descriptions to tell you what’s going on and numbers so you can look up more information. The bad thing is that the messages aren’t necessarily all that helpful, and the error may be too general to let you know exactly what’s going on, as in the case above.

The action could not be completed. Ok, what do I do next?
Ok, what do I do next?

In 2013, I spent a good chunk of time going through the software I work on and looking for any error or warning messages that were not helpful. We used to have one internal error message that really meant you needed to have the Oracle Client Tools installed on your machine, but that wasn’t what it actually said, and we got questions about it pretty regularly. While those questions only took five seconds to respond to, it would have been a lot better for the message to actually be meaningful to the person experiencing the problem! Thankfully, we got those cleaned up so that now our error messages actually tell you what you need to do to resolve them.

This applies to help text as well; much of our help text has been rewritten to be actually, y’know, helpful. By definition, help text will be used by someone who’s not an expert in the software or problem domain, so it needs to be very clear about what’s expected of the user.

While this isn’t directly related to coding, it’s still something programmers should consider as part of usability. Someone has to use your software; part of your job is to make sure they can do so effectively. Include technical details if it’ll be helpful in debugging, but remember that every error, warning, or help box should make sense to the end user of the software. Give that person clear direction so that he or she knows what to do next, and doesn’t attempt to defenestrate the computer.

Never mind the looping chain of synonyms; just tell me you can’t find the darned table!

Preparing for Microsoft exams: how and why

The value of certification is a constant hot topic for many people; a search for certifications on stack overflow alone returns over 27,000 results, and adding the exact phrase “worth it” still returns almost 800. I’ve never been responsible for hiring people or been asked about certifications, so I have absolutely no comment to make about whether they’re helpful for finding a job.

Where I find certifications helpful is in setting a deadline for myself. Since 2011, I occasionally needed to write SQL code and wanted to learn more about SQL, but I never did because it was never a priority. A few years ago, I signed up to take exam 70-461: Querying Microsoft SQL Server 2012; because I was paying for it (my company will reimburse exams only if you pass), I finally had the incentive I needed to sit down and learn the material. I never bothered with the other exams in the certificate, because the certificate wasn’t what was important to me; what I needed was to learn the material that was covered in that first exam.

So that’s my primary motivation for looking at certifications: as a way to encourage myself to study. After five years as a professional programmer, I feel like I still have a ton to learn, so I’m in favor of anything that helps me to focus.

Right now I’m looking at Microsoft’s exam 70-483: Programming in C#. Looking over the list of topics covered, I see some stuff I know reasonably well, and some stuff that I’ve never learned because it’s never been something I’ve needed to use. Here’s the key part, though: it all looks like stuff I would like to know, that could very well be useful to me at some point. So this is actually stuff I’m interested in learning; the test just helps me find the areas I need to know more about.

For example, I see that one of the topics covered in the exam is performing symmetric and asymmetric encryption:

Choose an appropriate encryption algorithm; manage and create certificates; implement key management; implement the System.Security namespace; hashing data; encrypt streams

The theory behind this is all stuff I studied in school, but I’ve never had any reason to use it in practice. As it happens, Pluralsight has a two-hour course called Introduction to Cryptography in .NET, which I expect will go into way more detail than the exam will. This is what I mean about focus: Pluralsight has just a ton of content that I find interesting, so having a list of topics that I need to cover helps me decide which courses to take first.

When I took the SQL exam, one thing that helped me relax was having the second shot offer, which lets you retake an exam for free; even though I didn’t need it, it was helpful to know that if I somehow screwed up and failed the exam it wasn’t going to automatically cost me $150. The most recent second shot offer expired a few weeks ago, so my plan is probably going to be to start reviewing this month and be ready to schedule the exam next time the offer comes around again. Or if it’s not available by this summer, I’ll probably take the exam then anyway.

In areas as diverse as finishing my PhD and learning to write a SQL query, setting a deadline is what helped me get it done, and that’s why I plan to pursue certifications.

Clarity in programming and the conditional operator

The interesting thing about the conditional operator (?:) is that hardly anybody knows what it’s called (it’s often just referred to as the ternary operator), but everyone seems to have an opinion on whether it should be used.

The conditional operator is shorthand for an if/else statement; rather than writing

if (condition) {expression 1}
else {expression 2}

we can just write

condition ? expression 1 : expression 2

Coworkers arguingI’ve had one code reviewer who was extremely against ever using this, to the point where I replaced the one I was using with an if/else statement (at the expense of clarity) just to end the argument (knowing that I was unlikely to work with him again anyway). The conditional operator can certainly be misused; consider something like the following:

condition1 ? exp1 : condition2 ? expr2 : condition3 ? expr3 : expr4

That’s a bad use of the conditional operator, because the reader has to stop and think through it to understand what’s going on. The equivalent if/else block, on the other hand, is longer but much easier to read:

if (condition1) { exp 1 }
else if (condition2) { expr2 }
else if (condition3) {expr3 }
else {expr4}

Understanding the second block is trivial. Side note: I would normally prefer to have each expression on its own line, but that’s a whole different argument and I’m condensing it a bit for this post. Also, I’m using C# here, in which the conditional operator is right-associative; that’s not true in all languages.

On the other hand, if you have a block that looks like this:

if (var1 % 2 == 0) {var2 = Parity.Even}
else { var2 = Parity.Odd }

Then the conditional operator version is just as easy to read, if not easier:

var2 = (var1 % 2 == 0) ? Parity.Even : Parity.Odd;

This version also has the advantage of making it obvious that, regardless of the outcome of the test, var2 is being set. There’s no way to accidentally set var2 in one case and var3 in the other, which removes one small possibility for bugs. It emphasizes the operation being done, while the if/else version emphasizes the condition.

Long story short: use the conditional operator when it improves the readability of the code, don’t use it when it doesn’t.  Here are some more bad examples:

a = expression : true ? false;

a = b != null ? b : null;

a = (b != null ? b : c); // use a = b ?? c;

Again, this just comes down to a simple rule: given two or more ways to code something, tend towards whichever method requires the least amount of concentration from the reader. The sanity you save could be your own.