One of the most common criticisms of software is that it's buggy, but anyone who's ever written a modicum of software is not in the least bit surprised by this. The layman does not share this understanding, to put it mildly. Since the process of programming, debugging, and shipping is not a readily understandable topic if you've never thought about logical implications to the 4th or 5th degree, one needs a good analogy. Here's mine:
Imagine most everyone has a robot in their home that takes blueprints for any object (a toy, a piano, a house, etc.), can build said object really quickly, but can't make any intuitive decisions. That is, the robot follows the designs on the blueprint exactly, for better or worse.
Most of the time objects come out of the robot just fine, but what if whoever wrote the blueprints didn't think about how his toy design would work when covered in baby slobber? What if the house the robot built was designed for 3 people but 7 people are trying to live in it? What if the blueprints for the desk the robot built didn't account for handicapped people?
Writing software is tantamount to making blueprints for builder robots that people end up making in their own home. When you're writing the blueprints you don't really know how people are going to use your stuff. You might not properly get the Feng Shui right in your house blueprints and people across the country using your blueprints get depressed. You never intend all of this stuff.
The blueprints are the code. The builder robot is your personal computer. The door that doesn't quite close is a bug.