fair warning, this section is mostly polemic
One thing that it appears students struggle with exams is the terminology (used here as a politer form of "jargon") that exam boards require students to use. I would argue that the fault for this is, however, more on the exam board than it is on the students. Take a question that OCR asked in 2019 – "describe two examples of defensive design that should be considered when developing this program" (the program was given in a previous part of the question). If you ask most working programmers what defensive design is, you are likely to get a lot of blank stares (for the uninitiated defensive design means anticipating malicious users of one's program). Even those who work in some of the most error-prone and complex areas of software engineering (e.g. distributed systems) will probably draw a blank.
One really has to question the pedagogic utility of making up your own concepts (ok, to be fair, "defensive design" does have a Wikipedia page, but I was unable to find a Google result that did not mention "OCR GCSE Computer Science" in it) to quiz concepts on. I can live with questions about email-protocol minutiae, because perhaps some students will end up building email software, but I really struggle when it comes to these made-up ideas.
end the polemnic
issues with programming
For more useful insights, it seems that functions confuse students (and I think many maths teachers would agree that students find function confusing). This is unfortunate given that functions are at the heart of computer science. The key issue I feel students experience with functions is the idea of "binding" – i.e. where variables are valid, and their relation to the overall lifecycle of the function (when they are taught programming, many students do not seem to have a very good idea of progam dynamics – more on this below). Many students are not sure of as to the meaning of a "return value". This is perhaps a consequence of Python programs (unfortunately frequently written by teachers) that look a bit like this:
x = 12
def square(number):
x = number ** 2
square(12)
print(x)
Which is very confusing to a lot of students, because they are not really taught about the idea of "scope". In programming language terms, what this does is:
# creates the global variable x
x = 12
# define the square function
def square(number):
# 'capture' a reference to `x` inside this function
# this reference will then be used when the function
# is later called
x = number ** 2
# invocate square, which updates the reference to `x` it has
square(12)
# prints the value of "x" to the console
print(x)
Unfortunately this approach really undermines a core reason why we use functions – encapsulation. Whereas if we write:
def square(number):
return number ** 2
print(square(12))
We have moved the squaring logic into a separate function. This has all the usual benefits that functions bring. Of course, in reality our functions tend to do more complicated things, and also reference each other.
I think the key things to double down on are:
- binding (aka scopes, namespaces)
- that functions are designed for encapsulation
- how the control flow of functions works (i.e. something about how they are executed – don't start explaining how stack frames work, but do try to explain to them that programs are things that do things.)
Relating to 3, is the issue of dynamics. This is a term from programming language theory (from the excellent Practical Foundations for Programming Languages the following definition is provided – "the dynamics of a language describes how programs are executed"). You might accuse me of 'inventing' unnecessary terms in the same was as OCR do with "defensive design" here, but the key difference is that the term "dynamic" is actually used in programming language theory, whereas "defensive design" is not. Explaining how programs are executed is essential. Using a debugger, or other mechanism for visualising a program's execution throughout time is really essential here.
One question that seemed to give a lot of students trouble one year was where candidates were asked as to whether or not a number of loops would run forever or terminate. Given the importance of the halting problem to theoretical computer science (and its easy proof) I imagine that an engaging lesson could be devised around it.
issues with number bases
It seems that the key issue here is place value – i.e. that numbers in different columns need to be multiplied by relevant_base^(the zero-indexed column number in question)
before they can be added together.
issues with algorithms
general explanation of algorithms
At GCSE it is exceedingly rare that students are asked to implement an algorithm from scratch. However, they are often asked to comment on implementations on algorithms and many students seem to fall down here.
binary searches
When asked to perform binary searches on datatypes other than numbers, many students struggle. I think this is to do with how binary searches are usually introduced to students by using lists of numeric data. The example I give on this site uses names (see binary search for exact details) and I think some explanation on how a system for sorting strings can be devised (as in the dictionary) is helpful. It is also probably sensible to explain how records can be searched (by sorting on a single field).