There's no shame in code that's 'good enough' but I think there's a danger in this article of missing an important point: you can't classify your output if you don't know its context and goals. If you're coding something that definitely won't be used again then make it 'good enough' for this use case, if you need it to be extended by others over the next few months then make it 'good enough' for that use case, if you have a contractual obligation to get it out to the client 'now' then stop thinking and start doing!
But paralysis is costly. If you lack the required knowledge to take a sensible decision, then take a gamble: never hold up making a low-risk choice because you don't know enough. The opportune time to learn what the right choice was is once you've made it and can evaluate the outcome with data.
The other thing to note is that complexity on its own isn't bad, complicatedness is [2]. The knowledge you've gained shouldn't be making your code more complicated. You should spend your time on creating an arsenal of simple solutions to complex problems. That is perfection (and you will never reach it.)
Optimize your time by evaluating after instead of planning before; over time create simple solutions to complex problems and use these as shortcuts to act decisively.
[1] http://paulbuchheit.blogspot.com/2007/04/perfect-is-enemy-of...
[2] http://usabilityworks.org/2006/12/13/simplicity-complexity-a...