Coding discipline
Over years of programming I have learned how to be most productive, but I found it strange we do not teach this to the students. We teach obscure features of academic systems they will never see again, but we fail to teach how to tackle large projects. Course lab tasks usually consist of writing around 30 lines of code, which doesn’t expose the students to the challenges of large code bases. Here are some things I tried to teach this year in COMP20252.
The one hour cycle
I code in cycles. During these I try to disconnect as much from environmental distractions as possible (headphones). These cycles are roughly one hour long, including a 5 minute break at the end to commit the code to the repository, have a biscuit and a stretch. There are three reasons for this and I think it makes sense for students to learn this as a sensible method of being productive.
Set-up and burnout
When starting a new change on the code base, I spend about five to ten minutes trying to locate all the areas that will need to be changes and generally planning how to tackle the problem. After about 15 minutes, I am in full swing as I have everything I need to know, cached in my head. At this point I can code for hours straight, but generally I target to finish after a further half an hour and move onto testing and debugging. The reason for stopping so early is because there is a good chance you will burn out (become tired and clumsy).
The first ten minutes are not productive, yet most students will only work for 10 minutes at a time before updating their status to “Bored now” and having a chat with someone before starting again from the beginning.
Testing and debugging
In half an hour of coding you will probably write about 50 lines scattered between several files. The rule of thumb is there being one bug every ten lines of code. So, you now have five bugs to find in 50 lines of code. Testing while you still remember what you may have broken is very easy compared to testing something that was written by someone else, or by you but months ago. Finding the bugs, knowing they are somewhere in the small blocks code you have just written, gives you a massive locating boost. This is the main reason why you should never abruptly walk away from the computer without doing some testing. Test and debug will hopefully take five or ten minutes, but can often take an hour. If it does take an hour you will be grateful that you didn’t carry on coding until you were exhausted.
There is one even greater sin than that of walking away from a computer leaving untested code, and that is leaving the code in a broken state. Each programming task involves breaking an already working piece of code in order to add functionality, change the behaviour etc. In the set-up you will probably want to examine the current behaviour of the system to ascertain the areas that need to be changed. This is very difficult if the system doesn’t work.
Students rarely do any testing as they never see their code coming back to them. After writing something and finding that it broke the system, they would generally walk away hoping the bug fix itself in their absence. The next week they would ask a demonstrator to fix it for them while saying “I can’t remember what I did”. Their original buggy code coming back week after week scared many students in COMP20252. In the feedback forms, that was one of their main criticisms. I say “GOOD! Be afraid. Very afraid”.
Divide and conquer
Forcing yourself to have a working system every hour partitions large tasks down to sensible sized components. Many of the students, from the start, wanted to create a large system involving several ambitious components. They would begin by writing a massive monolithic block containing all the features expecting that, once you write that last line of code, the program will work. This is bad on two counts. Firstly, it won’t work due to bug problems outlined above, and secondly there is no way you are going to keep so much state in you head. Even if you can keep track of the state of every variable you’ve used, all the possible input combinations and every possible error that could arise, you are making the job unnecessarily hard for yourself and for anyone else reading your code.
There is one more bonus reason of why you want to return to working code sooner rather then later, and that is the frequency of random unblockable interrupts. I receive a “stop what you’re doing and help me with this” request several times a day and with small changes it is still possible to revert the changes (infinite undo in nedit) and play them back to remind myself as to what I was doing. If I do have to revert and start again, then I have wasted at most half an hour, but at least I know what I am doing the second time round.
Great article. I agree with you completely about the need for students and new professionals to follow this practice. One thing I would add is the use of versioning software (e.g. Git) even for class projects. It’s a great benefit when you do not have perfect memory.