Skip to main content

What is Computational Thinking?

Computational thinking is a nebulous concept that we can summarise as the ability to solve problems through the application of algorithms. The Raspberry Pi foundation consider computational thinking to include logical thinking, decomposition, abstraction, pattern recognition, algorithm design, evaluation and organising data. For the purposes of this article I will go with this interpretation. With the aid of concrete examples, I will unpick each of these components in turn.  

I will start with logical thinking because logic is integral to the other aspects of computational thinking. We are familiar with this way of thinking because many puzzles and games of strategy such as chess, and solving Rubik's cube require us to think logically.  To solve these types of problems we need to be able to think clearly and have sound reasoning.  Consider the following two statements:
  1. All computer science teachers eat cake
  2. No cake eaters cycle bicycles
Based on these two statements is it true that a computer science teacher cycles a bike?  Following the logic through we can work out that the statement is false because the computer science teacher will be a cake eater (statement 1) and no cake eaters cycle bicycles (statement 2). How about the following question: Do all computer science teachers eat cheese cake?  This is inconclusive because all computer science teachers may well eat cake but we need more information to ascertain whether they all eat cheese cake or not. As Star Trek's Spock put it ""insufficient facts always invite danger" because we humans often jump to conclusions that we cannot rationally justify. This is a trivial example for sure but illustrates the logical thought processes needed to solve the problems of this nature.  

Decomposition is the ability to break a complex problem down into smaller more manageable parts. Each component can then be tackled individually before assembling them into the final solution.  

Let us take a look at how this might work in practice by way of example.  Suppose we have 20 people in a room. How many handshakes will need to take place for every person to shake the hand of every other person?  To start with we might just simplify the problem and consider only 2 people in the room.  In that case the answer is 1 handshake. Now let us consider 3 people in the room. Well that is only slightly harder. Alice shakes the hand of Bob and Cathryn, and Cathryn shake hands with Bob, so that makes 3 handshakes in total. For four people there will be 6 handshakes.  We could be really keen and produce a table like this:

Number of           Number of 
people                 handshakes 
---------------------------------------
2                   |          1
3                   |          3
4                   |          6
5                   |         10
6                   |         15
7                   |         21

By now it is only a simple step to realise that we need to add up all the integers between 1 and the number or people in the room minus 1 to work out the number of handshakes.  So if there are 8 people in the room then there will be 7+6+5+4+3+2+1 handshakes, which gives us 28.  By breaking the problem down we have worked out the strategy and underlying pattern that can help us solve this problem. Therefore, for 20 people in the room the answer is 20 +19 …..+1 which is 190.  Through this approach we may have also discovered that there is a quicker and more succinct method using the formula (n(n-1))/2, where n is the number of people. 

In this example we saw how the underlying pattern emerged after we had broken down the problem. This brings us onto pattern recognition which is the ability to see patterns so that we can recognise problems or parts of problems that we may have solved before. Lots of programming is concerned with reusing pieces of code that were originally developed for other solutions.  Even within a piece of code we are writing we may notice that quite a lot of our code is repeated.  It is our ability to notice those repetitions that help us write more succinct and generalisable code using functions perhaps. 

Let us look at something more concrete. Suppose we wish to give instructions for drawing a square using the following algorithm:

forward 50 steps
turn left 90 degrees
forward 50 steps
turn left 90 degrees
forward 50 steps
turn left 90 degrees
forward 50 steps
turn left 90 degrees

Straight away we notice a pattern: That the pair of instructions

forward 100 steps
turn left 90 degrees

is repeated four times.  So we can write this algorithm more succinctly using:

repeat 4 times [forward 50 steps; turn left 90 degrees] 

Next we many wish to draw shapes with a different number of sides, so for a triangle the pseudocode might look like: 

repeat 3 times [forward 50 steps; turn left 120 degrees] 

or for a hexagon:

repeat 6 times [forward 50 steps; turn left 60 degrees] 

As before we could draw up a table relating the number sides of the shape to the angles turned.

number | turn 
of sides | angle
-----------------------
3           | 120  
4           | 90
5           | 72
6           | 60
7           | 51
8           | 45
9           | 40
10         | 36

Using this we can work out the relation between the number of sides and the angle within which we need to turn.

angle_to_turn = 360 / number_of_sides

So now we have found a general way of writing an algorithm for a polygon:

repeat number_of_sides times [forward 50 steps; turn left angle_to_turn] 

And we do not need to write different code for triangles, squares, pentagons and so on. We can use the same code for any shape.  Thus we have used our ability to find patterns for a general solution for the problem of drawing a shape.

Abstraction is the ability to extract the most salient aspects of a problem and ignore those elements that are superfluous.  The iconic map of London Underground is often cited as a great example of abstraction. The map contains only basic information like the stations, what line they are on, where the hubs are, and which stations have wheelchair access. But the information that it does not contain is to some extent what makes it interesting.  It does not show the distance between stations, or depth of the stations.  It does not show the London streets.  It does not even have a scale. In short it only contains information that is relevant to passengers to help them navigate their way around the underground.  All other information is irrelevant and is not included.  But what information we deem relevant or not depends on our purpose.  The underground map is basically useless to the cab drivers who are plying their trade on the streets above.  What they need are the street maps.  Or would need had they not consigned this information to their long-term memory!

Algorithm design is concerned with finding a solution that requires a sequence of steps that follow on from one another in a specified order to solve a specific task.  Algorithms are not necessarily confined to computer programs and we could codify day-to-day processes as algorithms, like the steps we take to make a cup of tea. 

In the movie "Die Hard with a Vengeance" there is a riddle that requires algorithmic thinking. Bruce Willis is given a 3 litre vessel and a 5 litre vessel neither of which have any markings.  He needs to measure out exactly 4 litres of water. I can't remember exactly why he needed to do this but it was to prevent a bomb going off in 30 seconds or something like that. The sequence of steps he took to avoid this catastrophe were:
  1. Fill up the 3 litre vessel
  2. Pour the contents of the 3 litre vessel into the 5 litre vessel
  3. Fill up the 3 litre vessel
  4. Pour as much of the contents of the 3 litre vessel into the 5 litre vessel. One litre of water should now be remaining in the 3 litre vessel
  5. Empty the 5 litre vessel
  6. Pour the contents of the 3 litre vessel into the 5 litre vessel.  There is now 1 litre of water in the 5 litre vessel.
  7. Fill up the 3 litre vessel
  8. Pour the contents of the 3 litre vessel into the 5 litre vessel where there is already 1 litre of water. The 5 litre vessel now contains 4 litres of water.
We can say that this is an algorithm because it not only contains a set of steps, but also that the instructions are ordered. The order in which the instructions are carried out matters.  Compare this to my current list of things to do:

  • Mark Year 10 test papers
  • Organise trip to the First Lego League at Cambridge University
  • Register students of the Informatic Olympiad
  • Plan tomorrow's Year 13 lesson on TCP/IP
  • Write Year 12 mock exam paper
  • Create GCSE knowledge organiser on computer security
  • Complete this blog post! 
For sure some of those tasks will have greater urgency than others, for instance you might think that I should prioritise planning tomorrow's lesson, but it does not matter the order in which these tasks are carried out as they are not dependent on one another.  As a consequence this sequence of instructions is not an algorithm; it is merely a list of unrelated items. 

Evaluation considers the testing and debugging of code.  This means that we not only need to identify a range of suitable tests for our code but also to think of all the possibilities and issues that might arise. When we do encounter problems with our code we need to be able to isolate and identify where the problems are. For experienced coders it is second nature to test small units of code as it is being developed.  But for novices debugging is an incredibly frustrating process, but with careful scaffolding we can turn this into an opportunity to build in resilience into the student's armoury.

Finally organising data in our programs mean what data structures do we use.  Do we use lists, variables stack and so on.  Which data structure is the most efficient for processing or memory usage?  Also we need to consider how we store data. Do we want to store the data in text files, binary files or in databases?

Although algorithms appear in our everyday lives in computer science algorithms are synonymous with computer programs and so the ability to think algorithmically is the same as our ability to find a solution we can put into code that can be understood by a machine.

As a teacher I find that children pick up the elemental programming concepts like sequencing, assignment, selection and iteration quickly.  But the challenge lies in getting them to transfer their knowledge of these concepts to solve more complex problems.  In short, what seems to be their difficulty is their ability to think computationally. It is an important skill because computational thinking is not limited to the domain of computer programming but can be applied in other contexts. There appears to be no shortcut to improving children’s problem-solving abilities.  The current best pedagogy is to get pupils to practice solving scaffolded problems in different contexts.  After a while we can then expect the pupils to solve increasingly more complex problems with less and less support.  Many children do get there but there are some who find it a struggle.   It is those children we should have in mind when we are planning our lessons so that no child is left behind. 

Further reading

Comments

Popular posts from this blog

Mango Learning

We are a community of teachers that have developed extensive computing resources primarily aimed at the English secondary school curriculum that can be accessed here: www.mangolearning.academy .  Mango learning empowers teachers to deliver great lessons that explain complex ideas using clear and highly scaffolded teaching and learning resources. We are very excited to offer these resources for free to the community. These teaching and learning resources for computing are made by teachers for teachers and we understand the day-to-day challenges that teacher face.   The resources incorporate general and computing specific evidence-based pedagogy. We incorporated spaced retrieval practice though knowledge organisers, diagnostic questions and quizzes, for instance. We also incorporate ideas from cognitive load theory through lots of worked examples.   To help with coding we use PRIMM and block to text based pedagogical approaches.   To support literacy we address vocabulary head on, enco

Semantic Waves

In the previous post we looked at the transfer of learning from block based coding to text based languages.  Semantic waves offer a theory that help us to structure our lessons to support transfer of learning (Maton, Waite et al).  When we present concrete examples in single contexts transfer of learning is going to be weak.  We need to present multiple examples in a range of context.  This allows us to abstract out the underlaying features.  This idea of moving along a continuum between the abstract and concrete is given by the term semantic gravity.  For instance, if we talk about an algorithm in abstract terms we might say that it is a sequence of steps to solve a problem.  At this stage we have presented it as an abstract idea so has low semantic garvity.  In a lesson we might then go on and write algorithms for drawing squares.  This represents a concrete episode with high semantic gravity.  In a good lesson we might also want to give multiple examples of algorithm in different co

How to support your students to write code

For many children writing code can be a daunting prospect. To help children learn to write code more easily we can use a range of scaffolded pedagogies. Initially these approaches take ownership of the code away from the students thereby giving them confidence to explore and experiment with the code.   Gradually as the students learn more and more we can reduce the amount of support until they are able to write their own programs independently.   In a previous article we looked at approaches for supporting pupils to learn to read code that included activities such as explaining, predicting and tracing code, and live demonstrations with worked examples. This follow up article presents some approaches to support pupils with writing code. Fixing broken code Children can find and fix common syntax, runtime and logical errors in a piece of code. Errors might include missing brackets, missing speech marks, spelling mistakes and missing variables declarations, for instance. The pupils