The perfect project plan is possible if one first documents a list of all the unknowns. Premature optimization is the root of all evil in programming. Inside every large program, there is a small program trying to get out. When debugging, novices insert corrective code; experts remove defective code. In order to understand recursion, one must first understand recursion. They don't make bugs like Bunny anymore.
Before software can be reusable it first has to be usable. Measuring programming progress by lines of code is like measuring aircraft building progress by weight. If debugging is the process of removing software bugs, then programming must be the process of putting them in. Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. In theory, theory and practice are the same. In practice, they're not.
A good way to stay flexible is to write less code. One of my most productive days was throwing away 1000 lines of code. Without requirements or design, programming is the art of adding bugs to an empty text file. If something is worth doing once, it's worth building a tool to do it. Talk is cheap. Show me the code. Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
Programming languages, like pizzas, come in only two sizes: too big and too small. Program testing can be used to show the presence of bugs, but never to show their absence! One man's constant is another man's variable. Any fool can write code that a computer can understand. Good programmers write code that humans can understand. It's not a bug - it's an undocumented feature. A good programmer is someone who always looks both ways before crossing a one-way street.