How good are your pupils at rising to a challenge? When they encounter something difficult, do they show grit in persevering, or do they give up easily? Given a choice, would they choose to tackle easier or harder work? How do they cope when they fail?
In extra-curricular activities such as music, sport and computer games, the difficulty seems part of the appeal: much that attracts children to these sorts of pursuits comes through the sense of achievement that follows persevering and eventually succeeding at something which previously seemed really hard. As Kennedy said of the space programme: we choose to do these things not because they are easy, but because they are hard.
Within the curriculum, there’s evidence that challenge, overcoming difficulties and learning from mistakes can have a very positive impact on outcomes overall. It’s the activities that make learners think that best support long-term retention, and these seem more likely to be the hard ones than the easy ones. John Hattie has argued that it’s the teacher’s job to make work hard for pupils, because it’s only then that pupils make mistakes, and it’s only when pupils make mistakes that feedback becomes useful. Carol Dweck suggests that those with a ‘growth mindset’ welcome making mistakes, seeing these as precursors of knowledge and essential for learning. In EYFS, the characteristics of effective learning include paying attention to detail, persisting with activities when challenges occur, and finding ways to solve problems: learning in computing (and other subjects) further up the school ought to build on this foundation.
Making mistakes when programming computers is almost inevitable. There’s a lovely story of Grace Hopper, one of the first computer programmers, fixing a computer by removing a moth (or as Americans would say, a ‘bug’) from the relay switches out of which ancient processors were built. We still talk of mistakes in algorithms and code as ‘bugs’ and the process of fixing these as ‘debugging’. The programs pupils write, just like those developed by Microsoft and Google, will contain bugs: neither you nor your pupils should be surprised by this; indeed it’s best to welcome this as an opportunity for paying attention to detail, for understanding code better and for becoming a more skilful programmer. Back in the early days of Logo programming in schools, Seymour Papert argued that it’s better to ask whether a program is fixable rather than whether it’s right or wrong, and that the strategies which pupils applied to debugging their Logo scripts could transfer to dealing with mistakes more positively in the rest of the curriculum.
The new computing curriculum places a lot of emphasis on debugging. In key stage 1, pupils are taught to create and debug simple programs. In key stage 2, they learn to use logical reasoning to detect and correct errors in algorithms and programs. ‘Logical reasoning’ matters: it’s not enough just to get someone else to fix a program, or fix it by dragging random blocks around until something works. Pupils should be able to explain why their program didn’t work, and why their fix worked. It’s important that pupils become self-reliant in their debugging – they’re not likely to learn much programming, and certainly not how to debug their code, if you, or a fellow pupil, is always there to fix things for them: step away from the mouse, remind them the computer isn’t out to get them, and encourage a positive attitude to solving hard problems.
There are a number of strategies on which pupils can draw when debugging their programs. Whilst some pupils might well figure these out for themselves, it’s likely to be more effective to teach these, as well as providing plenty of opportunity to put these into practice.
One technique is called ‘rubber ducking’ – give pupils a yellow rubber duck in computing lessons, when their programs go wrong, they should explain to the duck what their program was meant to do, and what it actually does. Often, simply articulating their plan and the results like this can help pupils spot and then fix the bug. If not, explaining to the duck what happens on each line or in each block of code might be enough. This is similar to the approach we suggested in Barefoot Computing: first predict what should happen, then find out exactly what does happen. Use this to work out where something has gone wrong, and then fix it! Barefoot Computing also advocates a debug early, debug often approach, testing and fixing code as it gets written, rather than waiting until the whole of a complex program is written and then dealing with debugging.
‘Wolf fencing’ draws on an analogy with finding a wolf in the forest by building a fence, and then listening to hear from which side the wolf howls, then cut that region in half with another fence, and then that one, and so on until the wolf is found. With programs, get pupils to work out which section of the code has the bug, then which part of that section, and so on. This sort of ‘divide and conquer’ algorithm is used a lot in computing.
It’s worth making pupils aware of the range of different sorts of bugs that they might encounter when programming. Logic bugs can often be hard to find, as they are more likely to come from errors in algorithms rather than code – perhaps because these haven’t been thought through carefully enough. In Scratch and similar languages, multithreading bugs are not uncommon, as one sprite gets out of sync with another or reacts to input intended for another: broadcast signals might help here. Sometimes programs work, but work too slowly – performance can sometimes be improved by removing unnecessary calculations, reducing precision or by thinking of a more efficient algorithm. Arithmetic bugs through dividing by zero can be avoided with a little care, as can rounding errors with a bit more care. Some of the hardest bugs to deal with arise out of not understanding quite how the language or even the hardware works: Googling error messages, or even reading the manual, helps.
Once pupils start working with text based programming languages such as TouchDevelop or Python, syntax errors become common, which is one way to emphasise the importance of spelling, punctuation and grammar in code! Attention to detail will help here, and the interpreter or compiler usually provides an error message with some detail of what went wrong and what the error is. These messages can seem terse and cryptic, but they’re meant to be helpful so encourage pupils to read these carefully. Googling the error message helps here too.
As well as letting pupils debug their own code, there’s a case for giving them debugging exercises – give them some buggy code, and set them the challenge of getting it working as it should. Or, as Alan O’Donohoe recommends, get them to sabotage one another’s code, swapping seats to introduce say five bugs and then swapping back as the original programmer gets on with debugging. It’s quite alright to make deliberate (or otherwise) mistakes when you’re teaching pupils programming, but make the most of the opportunity this offers to teach debugging. Anything you can do to make debugging seem an intrinsic part of the challenge and the fun of programming is likely to help, and might even make it easier for pupils to apply these lessons to mistakes in other work.
Originally published in Teach Primary 9.5 as Working out the Bugs. Reproduced here with permission. © all rights reserved.Share