The more I write “real” software - not just demos, but things you actually have to make work for a user you'll never meet - the more I realize that you can never write just one application. Instead, you always have to write at least four:
- There's the app itself. This is the thing that the user runs.
- There's the tests. These will generally be about the same size as the app. Yes, a 20,000 line application will usually have 20,000 lines of test code.
- There's the build. Truly an application in itself (albeit usually not quite as big as the test code) it needs to deal with all the weird third party crap, odd test scenarios, and specialized hacks.
- There's the installer. If you're very lucky, this is a zipfile. Usually, you're not lucky. If not, you're looking at a significant effort to make sure it works right - uninstall, unattended install, rollback on failure partway through, blah blah blah.
Oh, and there's the documentation, too, although I didn't list that since I haven't decided yet whether it qualifies as an application or not. Probably it does.
Each of these things is a major effort in and of itself for any nontrivial project. Each needs to be written, tested, patched, documented, and supported. This also means that the app itself represents well south of 50% of the code, and probably less than 30%.
All of this just goes to justify the practice I've used for years: when someone asks me how long something will take, I estimate it in my head, and then multiply by four before telling them a number. It has worked surprisingly well.