I never took classes on programming. Back in the Ancient Times, I picked up a ridiculously thin book on programming for the ZX Spectrum my dad had bought for the family. I was maybe 7 at the time, and me and my dad sat down and input the small programs (less than 100 lines, IIRC) that were in the book. I only remember a racing game that used a capitol 'I' as the top-down view of the car (the font gave the letter cross bars, like on a 'T', except both top and bottom. Hey, to a kid in the infancy of the computer revolution, it was a goddamn racing car, and it was amazing). Over time, I experimented and learned. Today I look back and marvel at the important evolution of concepts like the GOTO and especially GOSUB commands. We knew so little back then, but we experimented so damned much.
The first thing is "have a system for testing how the program runs". It seems pretty simple, right? Most of us are very familiar with error messages, after all. But I am not satisfied. Too many times has a program crashed and taken the console or whatever along with it, making the error message impossible to read. Also, not all messages are errors. Also, I may want to compare messages from multiple runs of the program. So dear rookie, write a function early on that creates a seperate error log. Not a big revelation to someone with a bit of experience, but going from console error messages to a simple txt file with runtime messages saved in was a freaking miracle my first time! The process of looking for errors or inefficient code structures went from being an art that depended on me looking at a console and having a flash of genius, to being a craft with me flipping through lines and lines of program run statuses and non-crashing error messages. Also, a txt file can be searched! It can be posted online easily! Do it. You will thank yourself later.
But that is just the entry-level stuff. If you do anything more than dabbling, you should know that. The much bigger tool I depend upon now, one that I have very recently used to handle some important work, is modularity.
Tabula rasa, the clean slate method, is the most efficient way (for me) to handle large problems in the code. I know people who still scoff at the idea of extensive back-ups. "I'll just fix it if anything goes wrong, no need filling my harddrive with old versions" and such. Some make the mistake of taking regular back-ups, but deleting all but the most recent. I cannot count the times that I have had to go ten or more versions back to redo some work that got all tangled up, to the point where untangling it would take days. Filing a line of several back-ups as "whoopsie" is embarassing, but it beats having to untangle or redo everything. As they say, real men don't do back-ups. Real men cry a lot.
But tabula rasa is not just for those horrible moments when you realize that half of the code you wrote is essentially screwing up the other half. My latest use of tabula rasa is actually the reason for the image at the top. I 'scrolled back' my versions to a previous back-up to get rid of all code that formed stars and planets, going back to almost only the colored dots (celestial objects at great distances). Why? Because the code for generating landscapes was getting bothersome. It was clunky and hard to improve. Nothing more. Just a petty grievance, a first-world problem, so to speak. But all the progress is still in the scrapped 'line' of backups, and I can lift both basic concepts and entire chunks of code from it, if I so wish. Meanwhile, the core code for forming those spheres (from top left to bottom right, they are a star, its innermost planet, the planet's closest moon, and the planet's farthest moon, which looks bigger because it's closer to the camera) is now getting far more streamlined and flexible. Had a redo of the code been far more troublesome than a mere tabula rasa back to an earlier version, I would have been tempted to avoid it, and slave on with inefficient, clunky, poorly structured code. Now, I can just yank out part of the code and start that part over.
I have done similar things before, on a bigger scale, removing all but a few key components and starting over in a 'scorched earth' kind of way. Usually, that means starting up a new C++ project and transfering key structural parts (the file setup, the main game cycle, etc.), but with the right early back-up, a lot of that time can be better spent. And by tracking the back-ups (I keep a txt file with the main changes to each back-up noted), you can treat everything as a library of code, to copy into your current version and retrofitting.
From some of the thigns I have seen of professional code, people know this perfectly well (this is neither my idea, nor anything new), but it seems like it is considered a very low-key tool. As a result, I see code that is patchwork upon patchwork, with large chunks being little more than fixes to other chunks. I am a solid proponent of tabula rasa. Every now and then, you need to clean the slate and start over, using what you now know to recreate code better and sleeker. It seems like a banal thing, barely worth a blog entry, but if I had those seconds on the elevator, I would gladly pass on that banality to someone who might avoid a lot of wasted effort trying to deal with piled on code in the future.