Imagine the fear and freedom of an ancient sea captain at the helm of a wooden ship on an unfathomable ocean; accountable for all souls aboard, yet guided only by the stars. If you take personal responsibility for the success of your team and its projects, then you don't have to imagine, because you already know.
The modern professional's North Star is not Polaris, but an abstract idea we sometimes call “perfection.” This guiding light is easily mistaken for a destination; but perfection, while useful in charting a course, is rarely an achievable goal. Perfection is not an objective, but a direction.
Most real world problems have no perfect solution, for the same reason π has no last digit: There is always room for improvement; for a slightly more precise answer to whatever question we must answer. We must force ourselves to move on once the shortcomings of an approximate solution are no longer our biggest problem, and our time can be spent better elsewhere.
I have a map of the United States, actual size. It says, “Scale: 1 mile = 1 mile.” I spent last summer folding it. I also have a full-size map of the world. I hardly ever unroll it. People ask me where I live, and I say, “E6.”
—Steven Wright
Economists recognize a Point of Diminishing Returns when the opportunity cost of continued investment exceeds the marginal utility. Major League Baseball managers know the VORP—Value Over Replacement Player—of everyone who takes the field. It's tempting to polish the stone in front of us ad infinitum, forgetting that we're not here to polish stones, but to build a cathedral. It’s fine to polish stones (or bake bricks) in service to a larger goal, but no individual stone should ever obscure the bigger picture.
The search for perfect answers sometimes leads to mathematical formalism. We might, for example, attempt a cost/benefit analysis of alternative project plans through a partial ordering of all the tasks we’d like to accomplish: maybe a graph akin to a Decision Diagram, with nodes representing tasks, and edge weights representing the cost of achieving those tasks. Sadly, such models are either too vague to be useful, or so complicated that their maintenance overhead rivals the projects they model. We are not permitted a bird's eye view of the labyrinth we're navigating, no matter how much we want one.
Here are some suggestions for moving forward despite imperfect knowledge:
Make the best decision you can at each point, and roll with the punches. Reassess your status periodically. Don't be afraid to give up on tasks that are costing more than they're worth. Beware the Sunk Cost Fallacy.
Focus on tasks whose completion will be of immediate (rather than eventual) benefit, especially if the benefit is to your development process itself. Enjoying the fruits of your labor makes subsequent labor more bearable, for both practical and psychological reasons. Appreciate the power of rapid iteration and continuous improvement.
Define falsifiable tasks. Whether each task has been completed or not must be obvious to the entire team. A task is either done, or it is not. Disregard wishy-washy statuses like “mostly done” or “code complete,” or claims like “We just have to productionize it.” All of those statuses mean “not done.” Vaguely defined tasks tend to drag on indefinitely, overrunning budgets and making schedules slip.
We all feel, keenly at times, the gap between reality and perfection. Facing forward means we see the long road ahead of us, but not the ground we’ve already covered. Pause regularly to take stock. Keep making progress, and remember that perfection was never really the goal.
I wish I could embed a Meme because I swear this post can be encapsulated in a Dilbert. Something or other to the effect of "We did a cost benefit analysis to see if cost benefit analysis are useful...we're confused and spent too much time and $ doing them that we don't have to to review the analysis. Great post.
Working as a Software Engineer in a startup-like organization, just out of graduation, with no support from senior engineers I feel it difficult to know when to stop thinking about perfecting my code. I believe that one can never learn a programming language completely, at least with Python. I keep reading the documentation to improve the code, even when I have a lot more work to do. I personally think it is important that my code is following the standards when the client team reads it, but searching about how it's supposed to be done and then improving is taking up too much time. How can I assess the progress and stop making up more work for me?