I generally equate programming to a jigsaw puzzle.
For creating a new project - you have tons of pieces, a couple of which don't belong to this image, and you don't have a preview of what the puzzle looks like when it's done. But you do know the size and general colors, so estimates are possible, but not necessarily accurate.
For modifying an already-existing project - a cat came by and knocked off a chunk of the finished puzzle. It'll take some time, but the framework is already there, so it shouldn't be too bad (depending on how much needs to be changed).
It also helps for describing progress. One of my recent projects, at one point I was wondering how to describe it so that a non-technical person would understand why I don't know how much longer, and I came up with: Think of a jigsaw puzzle where all of the border pieces are done, as are a little over half if the inner pieces. The ones left are all separate from each other, what I have to do now is fill in the gaps.