Everything from the 11 lessons of this topic on a few pages: the key idea of each lesson, the diagram to remember, the points to learn and the traps examiners set. Read it, cover it, test yourself.
A variable is a named memory location that stores a value which can change while the program runs. A constant is a named value that cannot change while the program runs. In pseudocode you declare them with DECLARE Score : INTEGER and CONSTANT VatRate ← 0.2, and assign with the arrow ←. The five basic data types are INTEGER, REAL, CHAR, STRING and BOOLEAN. Statements run one after another in sequence, so their order matters.
Fig. 1: each variable has an identifier, a value and a data type
Worked example: Choosing data types
A club stores, for each member: their surname, their age in years, their height in metres, the first letter of their team name, whether they have paid, and their phone number. Choose a data type for each.
Surname is text: STRING.
Age in whole years: INTEGER.
Height such as 1.62 needs a fractional part: REAL.
One letter: CHAR. Paid or not: BOOLEAN.
A phone number such as 01632 960123 starts with 0 and is never used in arithmetic: STRING.
Variable: named memory location; its value can change while the program runs.
Constant: named value that cannot change while the program runs; declared with CONSTANT and a literal.
Data types: INTEGER, REAL, CHAR, STRING, BOOLEAN. Phone numbers are STRING.
Sequence: work through statements in order, updating each variable as you go.
Watch out!
"A constant never changes" is not enough on its own. Say that its value cannot be changed while the program is running, and give a benefit: it only has to be updated in one place.
A phone number is a STRING, not an INTEGER: storing it as a number would lose the leading zero, and nobody adds or multiplies phone numbers.
OUTPUT "Total" displays the word Total; OUTPUT Total displays the value stored in the variable Total. Check your quotation marks.
Sequence means statements run in order, one after another. Selection means the program chooses which statements to run by testing a condition that is either TRUE or FALSE. An IF statement runs the THEN branch when the condition is TRUE and the optional ELSE branch when it is FALSE. A nested IF is an IF inside another IF. A CASE statement compares one variable with several single values and runs only the first match; OTHERWISE catches every other value.
Fig. 1: an IF statement follows one of two paths, then both paths meet again at ENDIF
Worked example: Dry run
What does the program above output when Mark is 70, and when Mark is 39?
Mark = 70: is 70 >= 70? TRUE, so output Distinction. The ELSE branch (and the inner IF) is skipped.
Mark = 39: is 39 >= 70? FALSE, so go to ELSE.
Inner IF: is 39 >= 40? FALSE, so the inner ELSE runs.
Answer: 70 gives Distinction; 39 gives Fail
Condition, then branch.
IF: IF condition, THEN, optional ELSE, ENDIF.
Boundaries: decide whether the boundary value passes: > or >=.
Nested IF: test the highest band first; close every IF with its own ENDIF.
CASE: one variable, single values, first match only, OTHERWISE last.
Watch out!
Check the boundary. With IF Age > 18 an 18-year-old would be told they are too young. Use >= when the boundary value itself should pass.
Test the highest band first. If the program tested Mark >= 40 first, a mark of 85 would output Pass and never reach Distinction.
OTHERWISE must be the last case, and it runs only if none of the cases above it match. Use an IF, not CASE, when a branch depends on a range such as Mark >= 40.
3Iteration: count-controlled, pre-condition and post-condition loops
Syllabus 8.1
Iteration means repeating a group of statements. A count-controlled loop (FOR ... NEXT) runs a set number of times. A pre-condition loop (WHILE ... DO ... ENDWHILE) tests its condition before each pass, so it may run zero times. A post-condition loop (REPEAT ... UNTIL) tests its condition after each pass, so it always runs at least once. Totalling (Total ← Total + Number) and counting (Count ← Count + 1) are done inside loops.
Fig. 1: the three loop types differ in when the condition is checked
Worked example: Counting passes
How many times does the body of FOR X ← 3 TO 12 STEP 4 run, and with which values of X?
X starts at 3: 3 <= 12, run the body.
X ← 7: run. X ← 11: run.
X ← 15 goes past 12, so the loop ends.
Answer: 3 times, with X = 3, 7 and 11
Know when it stops.
FOR: known number of passes; the end value is included.
WHILE: tested first, may run 0 times, continues while TRUE.
REPEAT: tested last, runs at least once, stops when the UNTIL condition is TRUE.
Totals and counts: set to 0 before the loop, update inside it, output after it.
Watch out!
A FOR loop in pseudocode includes the end value: FOR Count ← 1 TO 5 runs 5 times. Python's range(1, 5) would stop at 4, so do not mix the two up.
The REPEAT condition says when to stop; the WHILE condition says when to keep going. Turning one into the other means reversing the condition.
Put Total ← 0 before the loop. If it is inside the loop, the total is reset on every pass and only the last mark is kept.
A string is a sequence of characters. LENGTH(s) returns the number of characters, spaces included. SUBSTRING(s, start, length) returns length characters starting at position start. UCASE and LCASE return the string in upper or lower case. In 0478 pseudocode the first character is generally at position 1; many programming languages, including Python, start at 0.
Fig. 1: SUBSTRING takes a start position and a number of characters
Worked example: Counting positions
What is output by the pseudocode above?
Number the characters: C1 O2 M3 P4 U5 T6 E7 R8.
SUBSTRING(Word, 4, 3) starts at position 4 and takes 3 characters: P, U, T.
LENGTH(Word) is 8, so SUBSTRING(Word, 8, 1) is the last character.
Answer: PUT, then R
Number the characters.
Write positions under each character, starting at 1. Spaces count.
SUBSTRING(s, start, length): the third value is how many characters, not where to stop.
Case: convert with UCASE or LCASE before comparing.
Every character: FOR Index ← 1 TO LENGTH(s) with SUBSTRING(s, Index, 1).
Watch out!
Spaces and punctuation are characters too. LENGTH("Hi there!") is 9, not 7.
The third value is a length, not an end position. Characters 3 to 6 are SUBSTRING(Word, 3, 4), not SUBSTRING(Word, 3, 6).
Without LCASE the capital E at the start of Eleven would not equal 'e', and the program would output 2.
Arithmetic operators: + - * / ^ (raised to the power of), plus MOD and DIV. Relational operators: = < <= > >= and <> (not equal to); they compare two values and always give a BOOLEAN result. Logical operators: AND (TRUE only if both sides are TRUE), OR (TRUE if either side is TRUE) and NOT (reverses TRUE and FALSE). Powers are worked out first, then * and /, then + and -; brackets make the order explicit.
Fig. 1: the three groups of operators in 0478 pseudocode
Worked example: Area of a circle
Evaluate Area ← 3.142 * 5 ^ 2.
The power is worked out first: 5 ^ 2 = 25.
Then the multiplication: 3.142 * 25.
Answer: 78.55
Brackets first.
Order: brackets, powers (^), then * and /, then + and -.
A procedure is a named block of code that performs a task; it is run with CALL as a statement on its own and does not return a value. A function is a named block of code that returns a single value, so it is used inside an expression; its header states the data type it RETURNS. Parameters are the variables in the header that receive the values passed in when it is called (up to three in the exam). A local variable is declared inside a subroutine and can only be used there; a global variable is declared in the main program and can be used anywhere.
Fig. 1: control passes to the subroutine and back; a function also hands back a value
Worked example: Two calls
Using the procedure above, the main program is CALL Stars(2) then CALL Stars(1). How many stars are output?
The first call sets Number to 2: the loop outputs 2 stars.
Control returns, then the second call sets Number to 1: 1 star.
Answer: 3 stars
Procedure or function?
Procedure: PROCEDURE ... ENDPROCEDURE, run with CALL, returns nothing.
Function: FUNCTION ... RETURNS type ... RETURN value ... ENDFUNCTION, used in an expression.
Parameters: name and data type in the header; values passed in the call, in the same order.
Scope: local inside a subroutine only; global anywhere in the program.
Watch out!
A procedure with no parameters is still called with CALL, e.g. CALL DrawLine. Do not write a procedure call inside an expression: it has no value to give back.
Never use CALL with a function. Its value must be used: assigned, output or part of a calculation, e.g. Total ← SumSquare(2, 3).
The lab program outputs Local Total 6 and then Global Total 10: assigning to a local variable with the same name never touches the global one.
A library routine is a pre-written, pre-tested subroutine that comes with a programming language. DIV(a, b) returns the whole-number quotient of a divided by b, with the fractional part discarded. MOD(a, b) returns the remainder. ROUND(x, places) returns x rounded to that number of decimal places. RANDOM() returns a random number between 0 and 1 inclusive.
Fig. 1: DIV counts the full groups; MOD counts what is left over
Worked example: Splitting a number
Evaluate DIV(472, 100), MOD(472, 10) and MOD(DIV(472, 10), 10).
472 ÷ 100 = 4 remainder 72, so DIV gives 4.
472 ÷ 10 = 47 remainder 2, so MOD gives 2.
DIV(472, 10) = 47, then MOD(47, 10) = 7.
Answer: 4, 2 and 7: the hundreds, units and tens digits
Divide, then split.
DIV(a, b): whole number of times b goes into a.
MOD(a, b): the remainder left over. Check: DIV × b + MOD = a.
ROUND(x, n): look at the next decimal place; 5 or more rounds up.
RANDOM(): 0 to 1; multiply, ROUND to 0 places, then add to set the range.
Watch out!
MOD gives the remainder, not the decimal part: MOD(7, 2) is 1, not 0.5. DIV(7, 2) is 3, not 3.5.
ROUND returns a new value; it does not change the variable unless you assign the result back, e.g. Price ← ROUND(Price, 2).
ROUND(RANDOM() * 6, 0) gives 0 to 6, which is seven possible values, not a dice roll. Check the smallest and largest values of your expression.
A maintainable program is easy for another programmer to understand, correct and update. Use meaningful identifiers for variables, constants, arrays, procedures and functions, so each name says what it holds or does. Add comments (starting with // in pseudocode) to explain the purpose of sections of code; the computer ignores them. Use constants for fixed values and procedures and functions to split the program into named, reusable parts.
Fig. 1: both programs do the same job, but only one explains itself
Worked example: Useful or not?
Which comment is more useful above the line Count ← Count + 1 inside a validation loop: (A) // add 1 to Count, or (B) // count the number of failed attempts?
Comment A only repeats what the code already says.
Comment B explains the purpose: what the count is for.
Answer: B: comments should explain why, not repeat the code
Name, explain, reuse.
Identifiers: meaningful names for variables, constants, arrays, procedures and functions.
Comments: // in pseudocode; explain purpose, not every line.
Constants: one place to change a fixed value.
Subroutines: write once, call many times, test separately.
Watch out!
"Use good variable names" is too vague for a mark. Say meaningful identifiers and explain the benefit: another programmer can see what each variable stores, so the code is easier to understand and update.
Comments are ignored by the translator, so they do not make the program run faster or slower, and they do not fix errors. They help people.
An array is a data structure that holds a fixed number of elements of the same data type under one identifier. Each element is reached by its index, written in square brackets: Scores[3]. Declare it with its lower and upper bounds: DECLARE Scores : ARRAY[1:5] OF INTEGER. The first index can be 0 or 1 (exam pseudocode generally uses 1). Because the index can be a variable, a FOR loop can visit every element in turn.
Fig. 1: a one-dimensional array of five integers
Worked example: Finding the largest
Scores holds 12, 7, 15, 9, 11. Trace this code and give the output. Highest ← Scores[1], then FOR Index ← 2 TO 5: IF Scores[Index] > Highest THEN Highest ← Scores[Index]; after the loop, OUTPUT Highest.
Highest starts as Scores[1] = 12.
Index 2: 7 > 12? No. Index 3: 15 > 12? Yes, Highest ← 15.
Index 4: 9 > 15? No. Index 5: 11 > 15? No.
Answer: 15
Identifier, index, element.
Declare: DECLARE Name : ARRAY[1:n] OF type.
Access: Name[Index], where Index can be a variable or expression.
Loop: FOR Index ← 1 TO n to input, total or search every element.
Max and min: start with the first element, then compare the rest.
Watch out!
Using an index outside the bounds, such as Scores[6] or Scores[0] for ARRAY[1:5], is an error: that element does not exist.
Start Highest at the first element, not at 0: if every value were negative, a starting value of 0 would be wrongly output as the largest.
A two-dimensional (2D) array is a table of elements of the same data type, with two indexes: one for the row and one for the column. Declare it with two sets of bounds: DECLARE Sales : ARRAY[1:3, 1:4] OF INTEGER (3 rows, 4 columns, 12 elements). Access an element with Sales[Row, Column]. To process every element, use nested loops: the inner loop runs completely for every pass of the outer loop.
Fig. 1: a 2D array of sales for 3 shops (rows) over 4 weeks (columns)
Worked example: Row totals
Using the Sales table, what does the program above output?
Row 1: RowTotal resets to 0, then 5 + 8 + 2 + 6 = 21.
Variables are held in main memory and are lost when the program ends. Storing data in a file keeps it permanently in secondary storage, so it can be used again later, by this or another program. In pseudocode: OPENFILE "Names.txt" FOR READ or FOR WRITE, then READFILE to read the next line into a variable, WRITEFILE to write a value, and CLOSEFILE when finished. Opening a file FOR WRITE creates a new file: any existing data in it is lost.
Fig. 1: WRITEFILE copies data from a variable into the file; READFILE copies it back
Worked example: Running it twice
The program above is run with the inputs Ali, Bea and Chen. It is then run again with Dev, Eve and Fay. What does Names.txt contain at the end?
First run: the file holds Ali, Bea, Chen, one per line.
Second run: OPENFILE ... FOR WRITE creates a new file, so the old names are lost.
The three new names are written.
Answer: Dev, Eve and Fay only
Open, use, close.
Purpose: data in a file is kept after the program ends and can be used again.
Open: OPENFILE "name" FOR READ or FOR WRITE; one mode at a time.
Use: READFILE "name", Variable reads the next line; WRITEFILE "name", Value writes one.
Close: CLOSEFILE "name". WRITE mode replaces any existing contents.
Watch out!
"Files save data" earns little. Say that data in variables is lost when the program ends, but data in a file is stored permanently so it can be accessed again later.
Opening an existing file in WRITE mode wipes it. Only one mode is used at a time, so to read and then rewrite a file, close it and open it again in the other mode.
Always CLOSEFILE when you have finished with a file. Closing it makes sure the data is saved and lets the file be opened again, for example in the other mode.