Programming Concepts
Revise Programming Concepts for Computer Science 0478 (O Level) — revision notes and instant AI marking. Free to start.
Programming Concepts
Every program — no matter how complex — is just data being stored, moved, and controlled using a small toolkit of building blocks: variables, sequence, selection, iteration, and sub-programs. Master these building blocks and you can read or write any program in pseudocode or Python.
Quick Overview
- Variables & Constants — named boxes that store data; variables can change, constants can't.
- Data Types — INTEGER, REAL, CHAR, STRING, BOOLEAN — the "shape" of data.
- Input & Output — how a program talks to the user (keyboard in, screen out).
- Sequence — code runs top to bottom, one line at a time, in order.
- Selection — IF and CASE statements that make decisions and branch the flow.
- Iteration — FOR, WHILE, REPEAT loops that repeat code.
- Totalling & Counting — running-total and counter patterns inside loops.
- String Handling — case conversion, length, substrings.
- Operators — arithmetic (+ - * /), relational (== > <), Boolean (AND OR NOT).
- Procedures & Functions — reusable named blocks of code; functions return a value, procedures don't.
- Local & Global Variables — where a variable "lives" and who can see it.
- Library Routines — pre-built, tested code like RANDOM() and ROUND().
- Maintaining Programs — writing readable, well-structured code that's easy to fix later.
Variables & Constants
What's actually going on here?
Think of your computer's memory as a giant wall of lockers. A variable is a labelled locker where you can put something in, take it out, and swap it for something else — as many times as you like while the program runs. The label (the identifier) never changes, but the contents can.
A constant is also a labelled locker, but it's sealed with a value at the start and never opened again for the rest of the program's life. This matters more than it sounds — if you use the literal number 3.142 for π in fifteen different places in your code and then discover you need more precision, you have to hunt down and change all fifteen. If you'd used CONSTANT PI ← 3.142 instead, you change it in exactly one place.
Naming rules for identifiers
Cambridge is picky about this, and it's an easy mark to lose. An identifier (the name of a variable, constant, procedure, or function) must:
- Be in mixed case — also called Pascal case, e.g.
FirstName, notfirstnameorFIRSTNAME - Only contain letters (A–Z, a–z) and digits (0–9)
- Start with a capital letter — and never start with a digit
It's a visual convention. The moment you see HIGHSCORE written in a program, your eyes instantly know "this value never changes" without reading any more code. It's a readability signal, not a rule the computer enforces.
Declaring a variable
DECLARE <identifier> : <datatype>
DECLARE Age : INTEGER DECLARE Price : REAL DECLARE GameOver : BOOLEAN
score = int() # whole number cost = float() # decimal number light = bool() # True/False only
Declaring a constant
CONSTANT <identifier> ← <value>
CONSTANT PI ← 3.142 CONSTANT PASSWORD ← "letmein" CONSTANT HIGHSCORE ← 9999
PI = 3.142 VAT = 0.20 PASSWORD = "letmein"
Python has no built-in "constant" keyword — writing PI = 3.142 doesn't actually stop anyone from changing it later. The "constant-ness" in Python is a naming convention (ALL CAPS) rather than an enforced rule. In pseudocode exams, however, you MUST use the CONSTANT keyword — using DECLARE for something meant to never change will lose marks.
Explain, in your own words, why a programmer would use a constant called MAXPLAYERS instead of just typing the number 4 everywhere it's needed in the code.
Data Types
A data type tells the computer what kind of thing is being stored, which affects how much memory to allocate and what operations make sense on it. You wouldn't try to multiply someone's name by 2 — the data type system exists partly to catch that kind of nonsense.
| Data Type | Used For | Pseudocode | Example |
|---|---|---|---|
| Integer | Whole numbers | INTEGER | 10, -5, 0 |
| Real | Numbers with a decimal part | REAL | 3.14, -2.5, 0.0 |
| Character | A single character | CHAR | 'a', 'B', '6', '£' |
| String | A sequence of characters | STRING | "Hello world" |
| Boolean | True or false only | BOOLEAN | True, False |
Sometimes you need to convert data from one type to another — this is called casting. The classic example: input() in Python always returns a STRING, even if the user typed "25". If you want to do maths with it, you must cast it: age = int(input("Enter age: ")). Forget the cast and Python will crash trying to add a string to a number.
Name the most appropriate data type for each: (a) a person's exam mark out of 100, (b) whether a light switch is on, (c) a single grade letter like 'A'.
Input & Output
A program that never receives input and never produces output is basically useless — it would run once and always give the identical result, unable to react to the outside world. Input/output (I/O) is how the program connects to reality.
- Input devices: keyboard (standard for text input), mouse, sensors, microphone.
- Output devices: monitor (standard for text output), speaker, printer.
INPUT Name IF Name ← "James" OR Name ← "Rob" THEN OUTPUT "Love the name ", Name
name = input("Enter your name: ")
if name == "James" or name == "Rob":
print("Love the name " + name)
In the pseudocode example above, you'll spot Name ← "James" used inside an IF — that's actually testing for equality, similar to == in some pseudocode conventions. Always check your exam board's specific pseudocode guide, since CIE mostly uses = for comparison and ← for assignment.
Sequence
This is the simplest concept in the whole chapter, and also one students underestimate. Sequence just means: the computer executes instructions in the exact order they're written, one at a time, top to bottom. There's no "skipping ahead" or "guessing what you meant."
The danger is that if you get the order wrong, the program can behave in a way that looks almost right but is subtly broken, or it crashes outright.
A variable must be given a value BEFORE it is used.
A sequencing bug in action
Here's a function meant to calculate the area of a rectangle. Spot the problem before reading on:
FUNCTION CalculateArea(length, width) RETURN area area ← length * width END FUNCTION
This will crash (or return garbage) because RETURN area runs before area has ever been calculated. The line that assigns the value must come first:
FUNCTION CalculateArea(length, width) area ← length * width RETURN area END FUNCTION
A student swaps line 1 (OUTPUT "Enter the first number") and line 2 (INPUT Num1) in a program. What effect does this have when the program runs?
Selection
Selection is how a program makes decisions. Depending on whether a condition is true or false, the program takes a different path — like a fork in a road. This is what allows programs to validate data, react to user choices, and behave differently in different situations.
IF statements
IF <condition>
THEN
<statement>
ENDIF
| Concept | Pseudocode | Python |
|---|---|---|
| IF–THEN–ELSE | IF Answer ← "Yes" THEN OUTPUT "Correct" ELSE OUTPUT "Wrong"ENDIF |
if answer == "Yes": print("Correct")elif answer == "No": print("Wrong")else: print("Error") |
Nested Selection
Nested just means "stored inside the other" — an IF statement placed entirely inside the body of another IF statement. This lets you check a second condition, but only if the first one was already true.
test_score = int(input("Enter a number: "))
if test_score > 40:
if test_score > 70:
result = "Distinction"
elif test_score > 55:
result = "Merit"
else:
result = "Pass"
else:
result = "Fail"
print(result)
Read it like a flowchart: "Is the score above 40 at all? No → automatic Fail, stop here. Yes → okay, NOW let's figure out which grade band it falls into." The outer IF filters out the failing cases first, so the inner IF only ever has to worry about scores that are already passing.
CASE statements
A CASE statement is a cleaner way to write selection when you're comparing one single variable against several possible fixed values — it's less useful when your conditions involve ranges or multiple different variables (that's when IF is better).
CASE OF <identifier>
<value 1> : <statement>
<value 2> : <statement>
...
OTHERWISE <statement>
ENDCASE
INPUT Move CASE OF Move 'W' : Position ← Position - 10 'E' : Position ← Position + 10 'A' : Position ← Position - 1 'D' : Position ← Position + 1 OTHERWISE OUTPUT "Beep" ENDCASE
Write an algorithm using pseudocode that inputs 3 numbers and outputs the largest of the three.
Iteration
Iteration is repeating a line or block of code using a loop, so you don't have to copy-paste the same instructions over and over. There are three flavours: count-controlled, condition-controlled (two types), and nested.
Count-Controlled Loops (FOR)
Use this when you know exactly how many times the loop should run before it even starts.
FOR <identifier> ← <value1> TO <value2> STEP <increment>
<statements>
NEXT <identifier>
| Goal | Pseudocode | Python |
|---|---|---|
| Print "Hello" 10 times | FOR X ← 1 TO 10 OUTPUT "Hello"NEXT X |
for x in range(10): print("Hello") |
| Even numbers 2→10 | FOR X ← 2 TO 10 STEP 2 |
for x in range(2,12,2): |
| Countdown 10→0 | FOR X ← 10 TO 0 STEP -1 |
for x in range(10,-1,-1): |
Python's range(10) gives you 0–9 (excludes the end value), whereas pseudocode's FOR X ← 1 TO 10 is inclusive of both 1 AND 10. This is one of the most common sources of "off by one" errors when translating between the two — always double check your range's upper bound.
Condition-Controlled Loops
Use this when you don't know in advance how many times the loop needs to run — instead, it keeps going until some condition becomes true (or false).
| Type | Tests condition... | Runs at least once? | Pseudocode keyword |
|---|---|---|---|
| Post-condition | AFTER the loop body runs | ✅ Yes — always | REPEAT ... UNTIL |
| Pre-condition | BEFORE the loop body runs | ❌ Not necessarily | WHILE ... DO ... ENDWHILE |
REPEAT INPUT Guess UNTIL Guess = 42
WHILE Colour != "Red" DO INPUT Colour ENDWHILE
# Python equivalent
while colour != "Red":
colour = input("New colour")
Imagine a nightclub bouncer. A WHILE loop is a bouncer who checks your ID before letting you take a single step inside — if you fail, you never get in at all, not even once. A REPEAT...UNTIL loop is a bouncer who lets everyone walk in first, and only checks IDs on the way out — meaning everyone gets in at least once, even if they immediately get kicked out. That's the entire difference between pre-condition and post-condition loops.
Nested Iteration
A loop inside another loop. The inner loop completes its entire run for every single pass of the outer loop. This is exactly how multiplication tables, grids, and 2D arrays get processed.
outer_counter = 1
while outer_counter <= number:
inner_counter = 1
while inner_counter <= 10:
product = outer_counter * inner_counter
print(outer_counter, "x", inner_counter, "=", product)
inner_counter = inner_counter + 1
outer_counter = outer_counter + 1
A student wants a loop that keeps asking the user to enter a password, and must ask at least once even before checking anything. Which loop type should they use — WHILE or REPEAT — and why?
Totalling & Counting
These are two of the most exam-tested patterns in the whole syllabus, and they always follow the exact same shape:
- Initialise a variable to 0, before the loop starts.
- Update that variable inside the loop, once per iteration.
- Output the final value, after the loop ends.
The only difference between totalling and counting is what happens in step 2: totalling adds the actual value each time; counting adds exactly 1 each time a condition is met (it doesn't care about the value, only whether something happened).
| Pattern | Update line | What it tracks |
|---|---|---|
| Totalling | Total ← Total + Num | The sum of every value entered |
| Counting | Count ← Count + 1 | How many times something happened |
Total ← 0 ← BEFORE the loop
Total ← Total + Num ← INSIDE the loop
OUTPUT Total ← AFTER the loop
If you put Total ← 0 inside the loop, it would reset back to zero on every single pass, wiping out everything you'd added so far. This is one of the most common exam mistakes — always double-check the "reset to 0" line is outside and before the loop, not inside it.
Write an algorithm using pseudocode that inputs 20 numbers and outputs how many of these numbers are greater than 50.
String Handling
String manipulation means using code to modify, analyse, or extract information from text data. The three key operations tested are case conversion, length, and substrings.
Case Conversion
| Function | Pseudocode | Python | Example output |
|---|---|---|---|
| Uppercase | UCASE(Name) | Name.upper() | "SARAH" |
| Lowercase | LCASE(Name) | Name.lower() | "sarah" |
Length
Password ← "letmein" IF LENGTH(Password) >= 8 THEN OUTPUT "Password accepted" ELSE OUTPUT "Password too short" ENDIF
(This outputs "Password too short" since "letmein" has only 7 characters.)
Substring
A substring pulls out a chunk of characters from a bigger string. Pseudocode uses (start position, length). Python uses [start:end] slicing instead.
Pseudocode SUBSTRING starts counting from position 1
Python string slicing starts counting from position 0
| Pseudocode | Python | Output |
|---|---|---|
SUBSTRING(Word, 1, 3) | Word[0:3] | "Rev" (from "Revision") |
SUBSTRING(Word, 3, 6) | Word[2:8] | "vision" |
Students often forget the position offset between pseudocode (starts at 1) and Python (starts at 0). If a question is entirely in pseudocode, stick to position 1 for the first character. If it's Python, stick to index 0. Don't mix the two conventions in the same answer.
The function Length(x) finds the length of a string x. The function Substring(x,y,z) finds a substring of x starting at position y and z characters long (first character is position 1). Write pseudocode to store "Save my exams" in X, output its length, and extract and output the word "exams".
Arithmetic, Logical & Boolean Operators
An operator is a symbol that instructs the computer to perform a specific operation on one or more values. There are three families you need cold: arithmetic (maths), logical/relational (comparison), and Boolean (combining true/false conditions).
Arithmetic Operators
| Operation | Pseudocode | Python |
|---|---|---|
| Addition | + | + |
| Subtraction | - | - |
| Multiplication | * | * |
| Division | / | / |
| Modulus (remainder) | MOD | % |
| Quotient (whole division) | DIV | // |
| Exponentiation (power of) | ^ | ** |
number % 2 == 0 is true only when a number divides evenly by 2 — i.e. it's even. This single trick appears constantly in exam questions (checking odd/even, checking multiples, wrapping values around a range).
Logical (Relational) Operators
| Comparison | Pseudocode | Python |
|---|---|---|
| Equal to | == | == |
| Not equal to | <> | != |
| Less than | < | < |
| Less than or equal to | <= | <= |
| Greater than | > | > |
| Greater than or equal to | >= | >= |
Boolean Operators
- AND — True only if both conditions are true.
- OR — True if one or both conditions are true.
- NOT — Flips the result (True becomes False, and vice versa).
score = int(input("Enter the score: "))
if score >= 90 and score <= 100:
print("Grade: A")
elif score >= 80 and score < 90:
print("Grade: B")
elif score >= 70 and score < 80:
print("Grade: C")
elif score < 70:
print("Fail")
What will not (5 > 3 and 2 > 10) evaluate to, and why?
Procedures & Functions
As programs grow, cramming everything into one giant block of code becomes unmanageable. Sub-programs solve this by letting you package a sequence of instructions under one name, so you can reuse it, test it in isolation, and keep your main code short and readable.
A FUNCTION returns a value.
A PROCEDURE does not.
Parameters are values passed into a sub-program, written in brackets after its name, e.g. FUNCTION TaxCalculator(pay, taxcode). A sub-program can take multiple parameters, or none at all.
Procedures
PROCEDURE <identifier>(<param1>:<data type>, ...)
<statements>
ENDPROCEDURE
CALL <identifier>(Value1, Value2...)
PROCEDURE calculate_area(length: INTEGER, width: INTEGER) area ← length * width OUTPUT "The area is ", area ENDPROCEDURE CALL calculate_area(5, 3)
# Python
def calculate_area(length, width):
area = length * width
print("The area is", area)
calculate_area(5, 3)
Functions
FUNCTION <identifier>(<param1>:<data type>, ...) RETURNS <data type>
<statements>
ENDFUNCTION
FUNCTION calculate_area(length: INTEGER, width: INTEGER) area ← length * width RETURN area ENDFUNCTION OUTPUT calculate_area(5, 3)
In pseudocode, never write CALL calculate_area() for a function. Functions are called from directly within an expression, like OUTPUT calculate_area(5,3) or x ← calculate_area(5,3). The CALL keyword is reserved exclusively for procedures, which don't return anything to plug into an expression.
An economy ticket costs £199 and a first-class ticket costs £595. Create a function flightCost() that takes the number of passengers and the ticket type as parameters, and returns the total price. Then write code that outputs the price for 3 passengers flying economy.
Local & Global Variables
This is fundamentally about scope — where in the code a variable can be seen and used.
| Local Variable | Global Variable | |
|---|---|---|
| Declared where? | Inside a function/procedure | Outside any function/procedure, at the top level |
| Accessible from? | Only within that same block | Anywhere in the whole program |
| Lifetime | Destroyed when the block finishes running | Exists for the entire life of the program |
# LOCAL example — localVariable only exists inside printValue()
def printValue():
localVariable = 10
print("The value is:", localVariable)
printValue()
# GLOBAL example — globalVariable can be seen by any function
globalVariable = 10
def printValue():
global globalVariable
print("The value is:", globalVariable)
printValue()
Notice that in the second example, the function has to explicitly write global globalVariable before it can modify the outer variable. Without that line, Python assumes any variable you assign inside a function is a brand-new local variable, even if a global one with the same name already exists. This is a genuinely tricky Python quirk worth remembering.
It's tempting, but it's bad practice: global variables can be accidentally changed by any part of a large program, making bugs very hard to trace. Local variables keep each sub-program's data private and self-contained, which is safer and easier to debug.
Library Routines
A library routine is ready-made, already-tested code that you can just call instead of writing it yourself from scratch. Why reinvent a random number generator when a reliable, tested one already exists in a library?
| Concept | Pseudocode | Python |
|---|---|---|
| Random number | RANDOM(1,6) | random.randint(1,6) |
| Random choice | — | random.choice(list) |
| Round | ROUND(Cost,2) | round(number, 2) |
Cost ← 1.9556
OUTPUT ROUND(Cost, 2)
# Outputs 1.96
Simulating a dice roll, picking a random question from a numbered list, drawing national lottery numbers, or generating unpredictability for cryptography. Anywhere a program needs an element of "chance," a random library routine is the tool.
Maintaining Programs
Code isn't just written once — it gets read, fixed, and extended by other people (or by you, six months later, having forgotten everything). A program that's easy to maintain uses consistent techniques that make its structure and intent obvious at a glance.
- Layout — clear spacing between logical sections of code.
- Indentation — consistently shows which lines belong inside which block.
- Comments — explain why the code does something, not just what.
- Meaningful variable names —
studentAgebeatsxevery time. - White space — blank lines to visually separate ideas.
- Sub-programs — functions/procedures used where possible instead of repeating code.
If a question asks you to "improve the maintainability" of a piece of code, examiners are looking for specific named techniques from the list above — don't just say "make it neater." Say exactly which technique you'd apply and why (e.g. "rename variable x to totalScore so its purpose is clear").
What to Memorise
- Variable
- An identifier whose value CAN change during a program's execution.
- Constant
- An identifier whose value is set once and never changes.
- Casting
- Converting a value from one data type to another (e.g. string → integer).
- Sequence
- Instructions executed one at a time, in the exact order written.
- Selection
- Changing the flow of a program based on the result of a condition (IF / CASE).
- Iteration
- Repeating a block of code using a loop (FOR / WHILE / REPEAT).
- Count-controlled loop
- Repeats a fixed, known number of times — uses FOR.
- Condition-controlled loop
- Repeats until a condition is met — uses WHILE (pre-condition) or REPEAT (post-condition).
- Nested
- A statement stored entirely inside another statement of the same type.
- Function
- A sub-program that RETURNS a value; called within an expression.
- Procedure
- A sub-program that does NOT return a value; invoked using CALL.
- Parameter
- A value passed into a sub-program, written in brackets after its name.
- Local variable
- Declared inside a sub-program; only accessible within that block; destroyed when the block ends.
- Global variable
- Declared at the outermost level; accessible from anywhere in the program.
- Library routine
- Pre-written, reusable, pre-tested code (e.g. RANDOM(), ROUND()).
| Meaning | Pseudocode | Python |
|---|---|---|
| Modulus | MOD | % |
| Integer division | DIV | // |
| Power | ^ | ** |
| Not equal | <> | != |
| Function returns | RETURNS <type> | return |
Concepts Checklist
Tick off each concept once you're confident you could explain it without looking back.
Exam Tips
Never write CALL myFunction() — CALL is only for procedures. Functions are used inside expressions (OUTPUT myFunction()).
Total and Count variables must be initialised to 0 before the loop begins, never inside it — otherwise they get wiped out every single pass.
If you don't know exactly how many times something repeats, don't use FOR — you need WHILE or REPEAT instead.
Pseudocode substrings start counting at position 1. Python string slicing starts at index 0. Don't mix the two conventions.
For pseudocode structure questions (functions/procedures), marks are typically awarded for: (1) correct keyword — FUNCTION/PROCEDURE, (2) correct use of parameters and RETURN/OUTPUT, (3) correctly calling the sub-program from the main program. Get the structure right even if your logic has a small error — structural marks are often awarded independently.
When a question shows a loop and asks for the final output, don't try to do it in your head — draw a small trace table with a column for each variable and manually step through each iteration. This is the single most reliable way to avoid careless errors on loop-tracing questions.
- Variables & Constants
- Input & Output
- Totalling & Counting
- Arithmetic, Logical & Boolean Operators
- Procedures & Functions
- Local & Global Variables
Read the full Programming Concepts notes free
That's the preview — create a free account to read the rest, plus flashcards and practice questions with instant AI marking. No credit card.
Unlock the full notes free →