Skip to the page
Year 10 Β· Computer Science Β· Summer 1 Β· Programming

Strings, operators and library routines

What this lesson covers

8.1 Programming concepts

Cambridge IGCSE Computer Science 0478 Β· Topic 8: Programming Β· Paper 2

You will learn to

  • Use the string functions LENGTH, SUBSTRING, UCASE and LCASE.
  • Use arithmetic, relational and logical operators, including MOD and DIV.
  • Use the library routines ROUND and RANDOM.
  • Create a password checker and a dice game in Python and in pseudocode.

Success criteria

  • I can work out 17 MOD 5 and 17 DIV 5.
  • I can take the first three letters of a name with SUBSTRING.
  • I can simulate a dice roll and round a result to 2 decimal places.
The syllabus points for this section
  • Declare variables and constants and choose the right data type.
  • Use input, output, sequence, selection (IF and CASE) and the three types of loop.
  • Use totalling, counting, string handling and arithmetic, relational and logical operators.
  • Write procedures and functions with parameters, and explain local and global scope.
  • Use the library routines MOD, DIV, ROUND and RANDOM, and write maintainable programs.

Key words

Say each word, then read what it means. Every one is in the glossary too.

Variable
A named place in memory whose value can change while the program runs.
Constant
A named value that is set once and cannot change while the program runs.
Identifier
The name given to a variable, constant, array or subroutine.
Data type
The kind of value stored: INTEGER, REAL, CHAR, STRING or BOOLEAN.
Assignment
Storing a value in a variable, written with ← in pseudocode.
Sequence
Statements run one after another in the order they are written.
Selection
Choosing which statements to run using a condition (IF or CASE).
Iteration
Repeating a block of statements in a loop.
Count-controlled loop
A FOR loop that repeats a set number of times.
Pre-condition loop
A WHILE loop that checks its condition before each pass, so it may run zero times.
Post-condition loop
A REPEAT UNTIL loop that checks its condition after each pass, so it runs at least once.
Totalling
Keeping a running total by adding each value to a total variable.
Counting
Adding 1 to a counter variable each time something happens.
Procedure
A named subroutine that does a task and is run with CALL; it does not return a value.
Function
A named subroutine that returns a single value to where it was called.
Parameter
A variable in a subroutine heading that receives a value when the subroutine is called.
Local variable
A variable declared inside a subroutine that can only be used inside it.
Global variable
A variable declared in the main program that can be used anywhere in the program.
Library routine
A ready-made, tested subroutine provided with the language, such as ROUND or RANDOM.
Array
A data structure holding many values of the same data type under one name, each found by its index.

The explanation

Read it here, or open the study page below to go one step at a time with things to try.

Variables: named boxes in memory

A variable is a named place in memory that holds one value. The value can change while the program runs.

The name is called an identifier. Cambridge pseudocode writes identifiers in PascalCase, such as `TotalScore`.

`DECLARE` gives the name and the data type before the variable is used.

The arrow `←` means assignment: work out the value on the right, then store it in the variable on the left.

e.g.Example
Score ← 0 stores 0. Score ← Score + 5 reads the old value (0), adds 5, and stores 5. Output: 5
DECLARE Score : INTEGER
Score ← 0
Score ← Score + 5
OUTPUT Score
score = 0
score = score + 5
print(score)
?Why?

Python does not need a declaration. It works out the type from the value. Cambridge pseudocode declares every variable so the type is clear to the reader.

!Watch out

Read `Score ← Score + 5` from right to left. It is not a maths equation. It means: work out Score + 5, then put the answer back in Score.

Constants: values that never change

A constant is a named value that is set once. It cannot change while the program runs.

In pseudocode write `CONSTANT`, the name, `←` and the value. No data type is given: the value shows it.

Python has no true constants. Programmers write the name in CAPITALS to mean: do not change this.

e.g.Example
Spain's standard VAT (IVA) is 21%, so the rate is 0.21. 50.0 Γ— (1 + 0.21) = 50.0 Γ— 1.21 = 60.5 Output: Price with VAT: 60.5
CONSTANT VATRate ← 0.21
DECLARE Price : REAL
Price ← 50.0
OUTPUT "Price with VAT: ", Price * (1 + VATRate)
VAT_RATE = 0.21
price = 50.0
print("Price with VAT:", price * (1 + VAT_RATE))
?Why?

If the VAT rate changes, you edit one line instead of every line that uses 0.21. The name also tells the reader what 0.21 means. The program cannot change it by mistake.

!Watch out

Use a constant only for a value that is fixed for the whole run, like a tax rate or the size of an array. A value that the program updates, like a score, must be a variable.

The five data types

A data type says what kind of value a variable holds. It decides how the value is stored and what you can do with it.

Cambridge uses five data types. A CHAR goes in single quotes. A STRING goes in double quotes.

Data typeWhat it holdsExamplesPython
INTEGERA whole number: positive, negative or zero25, -3, 0int
REALA number with a decimal part3.142, -0.5, 19.99float
CHARExactly one character'A', '7', '?'str of length 1 (no separate char type)
STRINGZero or more characters (text)"Madrid", "28013", ""str
BOOLEANOnly TRUE or FALSETRUE, FALSETrue, False
DECLARE Age : INTEGER
DECLARE Height : REAL
DECLARE Grade : CHAR
DECLARE FirstName : STRING
DECLARE IsMember : BOOLEAN
Age ← 15
Height ← 1.68
Grade ← 'A'
FirstName ← "Lucia"
IsMember ← TRUE
age = 15
height = 1.68
grade = "A"
first_name = "Lucia"
is_member = True
print(type(age), type(height), type(grade), type(first_name), type(is_member))
?Why?

The type decides which operations make sense. You can add two INTEGERs. You cannot multiply two names.

Choosing the right data type

Ask two questions. Will I do maths with it? Can it have a decimal part?

A phone number or a postcode is a STRING. You never add phone numbers, and an INTEGER would lose a leading 0.

Use BOOLEAN for anything with only two states: paid or not paid, logged in or not.

DataBest typeReason
Number of pupils in a class: 28INTEGERCounted, so always whole
Price of a metro ticket: 1.50REALHas a decimal part
Shoe size: 38.5REALCan have a half
Exam grade: 'B'CHARAlways one character
Barcelona postcode: "08001"STRINGStarts with 0 and no maths is done on it
Has the pupil paid for the trip?BOOLEANOnly two answers
!Watch out

Do not store a phone number as INTEGER. 0034 912 345 678 would lose its zeros and spaces. Exam answers need a reason: STRING, because it can start with 0 and no calculations are done on it.

Input and output

Input is data going into the program, usually typed by the user. `INPUT Name` waits and stores what is typed in Name.

Output is data coming out, usually on screen. `OUTPUT` can show text and variables separated by commas.

Always show a message before an INPUT so the user knows what to type. This message is a prompt.

In Python, `input()` always gives a string. Wrap it in `int()` or `float()` to get a number.

e.g.Example
The user types Lucia, then 15. Age + 1 = 15 + 1 = 16 Output: Hello Lucia, next year you will be 16
DECLARE Name : STRING
DECLARE Age : INTEGER
OUTPUT "Enter your name"
INPUT Name
OUTPUT "Enter your age"
INPUT Age
OUTPUT "Hello ", Name, ", next year you will be ", Age + 1
name = input("Enter your name: ")
age = int(input("Enter your age: "))
print("Hello " + name + ", next year you will be", age + 1)
!Watch out

Forgetting `int()` is the most common Python bug here. Without it, age holds the text "15". Then `age + 1` crashes, because Python cannot add text and a number.

Sequence: one step after another

Sequence means the statements run one after another, in the order they are written.

The order matters. If a value is used before it is worked out, the answer is wrong.

e.g.Example
Three cinema tickets at 7.50 euros each. Total = 3 Γ— 7.50 = 22.50 Output: Total to pay: 22.5
CONSTANT TicketPrice ← 7.50
DECLARE Tickets : INTEGER
DECLARE Total : REAL
Tickets ← 3
Total ← Tickets * TicketPrice
OUTPUT "Total to pay: ", Total
TICKET_PRICE = 7.50
tickets = 3
total = tickets * TICKET_PRICE
print("Total to pay:", total)
!Watch out

Swap the last two lines and the program outputs Total before it has a value. Exam questions often ask you to find statements in the wrong order.

Selection with IF

Selection means the program chooses which statements to run, using a condition.

A condition is a question with a TRUE or FALSE answer, such as `Mark >= 50`.

The THEN part runs when the condition is TRUE. The ELSE part runs when it is FALSE. ELSE is optional. ENDIF closes the IF.

e.g.Example
Mark = 62. Is 62 >= 50? TRUE, so the output is Pass. Mark = 49. Is 49 >= 50? FALSE, so the output is Fail.
DECLARE Mark : INTEGER
OUTPUT "Enter the mark"
INPUT Mark
IF Mark >= 50
  THEN
    OUTPUT "Pass"
  ELSE
    OUTPUT "Fail"
ENDIF
mark = int(input("Enter the mark: "))
if mark >= 50:
    print("Pass")
else:
    print("Fail")
?Why?

Python uses a colon and indentation to show which lines belong to the IF. Pseudocode uses THEN, ELSE and ENDIF. Both mean the same thing.

Nested IF: up to three levels

A nested IF is an IF inside another IF. Use it when the next question depends on the first answer.

Cambridge questions use nesting up to three levels deep. More than that is hard to read.

In pseudocode the next IF goes inside the ELSE. Python can shorten ELSE followed by IF to `elif`.

e.g.Example
Mark = 58. Level 1: is 58 >= 70? FALSE, so go to ELSE. Level 2: is 58 >= 55? TRUE, so output Grade B. Level 3 is never checked. Output: Grade B
DECLARE Mark : INTEGER
Mark ← 58
IF Mark >= 70
  THEN
    OUTPUT "Grade A"
  ELSE
    IF Mark >= 55
      THEN
        OUTPUT "Grade B"
      ELSE
        IF Mark >= 40
          THEN
            OUTPUT "Grade C"
          ELSE
            OUTPUT "Ungraded"
        ENDIF
    ENDIF
ENDIF
mark = 58
if mark >= 70:
    print("Grade A")
elif mark >= 55:
    print("Grade B")
elif mark >= 40:
    print("Grade C")
else:
    print("Ungraded")
!Watch out

Test the highest boundary first. If you test `Mark >= 40` first, a mark of 85 outputs Grade C and stops. Every IF needs its own ENDIF.

Selection with CASE

`CASE OF` picks one path from many, using the value of one variable.

Each line has a value, a colon, then the statement to run. `OTHERWISE` catches every value that is not listed. ENDCASE closes it.

CASE is neater than a long chain of IFs when one variable is compared with fixed values.

Python 3.10 and later has `match` and `case`. `case _` works like OTHERWISE. Older Python uses if, elif and else.

e.g.Example
The user types S. 'A'? No. 'S'? Yes, so output Subtracting and leave the CASE. The user types X: no value matches, so OTHERWISE outputs Unknown choice.
DECLARE Choice : CHAR
OUTPUT "A = add, S = subtract, Q = quit"
INPUT Choice
CASE OF Choice
  'A' : OUTPUT "Adding"
  'S' : OUTPUT "Subtracting"
  'Q' : OUTPUT "Goodbye"
  OTHERWISE : OUTPUT "Unknown choice"
ENDCASE
choice = input("A = add, S = subtract, Q = quit: ")
match choice:
    case "A":
        print("Adding")
    case "S":
        print("Subtracting")
    case "Q":
        print("Goodbye")
    case _:
        print("Unknown choice")
!Watch out

CASE compares one variable with exact values. For a condition that joins two tests, like `Mark >= 50 AND Attendance > 90`, use IF.

Relational and logical operators

Relational operators compare two values. The answer is always TRUE or FALSE.

Logical operators join conditions. `AND` needs both to be TRUE. `OR` needs at least one TRUE. `NOT` swaps TRUE and FALSE.

The table uses Age = 15.

PseudocodePythonMeaningExampleResult
===equal toAge = 15TRUE
<>!=not equal toAge <> 15FALSE
<<less thanAge < 12FALSE
<=<=less than or equal toAge <= 15TRUE
>>greater thanAge > 12TRUE
>=>=greater than or equal toAge >= 16FALSE
ANDandboth are TRUEAge > 11 AND Age < 19TRUE
ORorat least one is TRUEAge < 5 OR Age > 65FALSE
NOTnotthe oppositeNOT (Age = 15)FALSE
e.g.Example
A metro discount is for under-26s or over-65s who have a travel card. Age < 26 β†’ TRUE. Age >= 65 β†’ FALSE. TRUE OR FALSE β†’ TRUE. HasCard = TRUE β†’ TRUE. TRUE AND TRUE β†’ TRUE. Output: Discount fare
DECLARE Age : INTEGER
DECLARE HasCard : BOOLEAN
Age ← 15
HasCard ← TRUE
IF (Age < 26 OR Age >= 65) AND HasCard = TRUE
  THEN
    OUTPUT "Discount fare"
  ELSE
    OUTPUT "Full fare"
ENDIF
age = 15
has_card = True
if (age < 26 or age >= 65) and has_card == True:
    print("Discount fare")
else:
    print("Full fare")
!Watch out

In pseudocode `=` compares. In Python `=` stores a value and `==` compares. `if age = 15:` is a syntax error in Python. Use brackets when you mix AND and OR, so the order is clear.

Arithmetic operators, DIV and MOD

Cambridge uses seven arithmetic operators: `+`, `-`, `*`, `/`, `^`, `DIV` and `MOD`.

`/` gives the full answer, which can have a decimal part. `DIV` gives only the whole-number part. `MOD` gives the remainder.

You may see `DIV(17, 5)` or `17 DIV 5`. Both mean the same.

Try the toy: share 17 sweets between 5 friends. Each friend gets DIV(17, 5) = 3. MOD(17, 5) = 2 sweets are left over.

PseudocodePythonMeaningExampleResult
++add7 + 29
--subtract7 - 25
**multiply7 * 214
//divide7 / 23.5
^**raise to the power2 ^ 38
DIV//whole-number divisionDIV(7, 2)3
MOD%remainder after divisionMOD(7, 2)1
e.g.Example
A film lasts 135 minutes. DIV(135, 60) = 2, because 60 fits into 135 two whole times. MOD(135, 60) = 135 - (2 Γ— 60) = 135 - 120 = 15 Output: 2 hours and 15 minutes
DECLARE Minutes : INTEGER
Minutes ← 135
OUTPUT DIV(Minutes, 60), " hours and ", MOD(Minutes, 60), " minutes"
minutes = 135
print(minutes // 60, "hours and", minutes % 60, "minutes")
?Why?

MOD is very useful. `MOD(Number, 2) = 0` is TRUE when a number is even. `MOD(Number, 10)` gives the last digit, as used in check digits.

!Watch out

In Python `^` does something else, so use `**` for power. Also, Python `/` always gives a REAL: `6 / 2` gives `3.0`.

There is something to try for this step in the IGCSE library.

Iteration: the count-controlled FOR loop

Iteration means repeating a block of statements. A block that repeats is called a loop.

A count-controlled loop repeats a set number of times. Cambridge writes it `FOR … TO … NEXT`.

The loop variable counts for you. `STEP` sets how much it goes up, or down, each time.

e.g.Example
First loop: Count takes 1, 2, 3, 4, 5. Output: 3, 6, 9, 12, 15 (one per line) Second loop: Count goes 10, 8, 6, 4, 2, 0.
DECLARE Count : INTEGER
FOR Count ← 1 TO 5
  OUTPUT Count * 3
NEXT Count
FOR Count ← 10 TO 0 STEP -2
  OUTPUT Count
NEXT Count
for count in range(1, 6):
    print(count * 3)
for count in range(10, -1, -2):
    print(count)
!Watch out

Python `range` stops before its end value. `FOR Count ← 1 TO 5` becomes `range(1, 6)`. Counting down to 0 becomes `range(10, -1, -2)`.

The pre-condition WHILE loop

A pre-condition loop checks its condition before each pass. Cambridge writes it `WHILE … DO … ENDWHILE`.

It repeats while the condition is TRUE. If the condition is FALSE at the start, the loop body never runs.

Use it when you do not know how many passes are needed.

e.g.Example
1000 euros grows by 10% a year. When does it reach 1500? 1000 < 1500 TRUE β†’ 1100, Years 1 1100 < 1500 TRUE β†’ 1210, Years 2 1210 < 1500 TRUE β†’ 1331, Years 3 1331 < 1500 TRUE β†’ 1464.10, Years 4 1464.10 < 1500 TRUE β†’ 1610.51, Years 5 1610.51 < 1500 FALSE β†’ stop Output: Years needed: 5
DECLARE Savings : REAL
DECLARE Years : INTEGER
Savings ← 1000.0
Years ← 0
WHILE Savings < 1500 DO
  Savings ← Savings * 1.1
  Years ← Years + 1
ENDWHILE
OUTPUT "Years needed: ", Years
savings = 1000.0
years = 0
while savings < 1500:
    savings = savings * 1.1
    years = years + 1
print("Years needed:", years)
!Watch out

Something inside the loop must change the condition. If Savings never changed, the loop would never stop. This is an infinite loop.

The post-condition REPEAT UNTIL loop

A post-condition loop checks its condition after each pass. Cambridge writes it `REPEAT … UNTIL`.

The body always runs at least once. The loop stops when the condition becomes TRUE.

It suits validation: ask for the input, and ask again until it is acceptable.

Python has no REPEAT UNTIL. Use `while True:` and `break` out of the loop when the stop condition is TRUE.

e.g.Example
The user types 150: condition FALSE, so repeat. The user types -3: FALSE, so repeat. The user types 72: TRUE, so stop. Output: Accepted: 72
DECLARE Mark : INTEGER
REPEAT
  OUTPUT "Enter a mark from 0 to 100"
  INPUT Mark
UNTIL Mark >= 0 AND Mark <= 100
OUTPUT "Accepted: ", Mark
while True:
    mark = int(input("Enter a mark from 0 to 100: "))
    if mark >= 0 and mark <= 100:
        break
print("Accepted:", mark)
!Watch out

WHILE keeps going while its condition is TRUE. UNTIL stops when its condition is TRUE. So the conditions are opposites. `WHILE Mark < 0 OR Mark > 100` matches `UNTIL Mark >= 0 AND Mark <= 100`.

Choosing the right loop

First ask: do I know how many times? If yes, use FOR.

If not, ask: must it run at least once? If yes, use REPEAT UNTIL. If it might need to run zero times, use WHILE.

LoopCondition checkedRuns at least once?Use it whenExample
FOR (count-controlled)No condition: it countsRuns a fixed number of timesYou know how many timesEnter 30 marks
WHILE (pre-condition)Before each passNo, it can run 0 timesUnknown number of times, maybe noneAdd sales until the target is reached
REPEAT UNTIL (post-condition)After each passYes, alwaysUnknown number, but at least oneAsk for a PIN until it is correct
!Watch out

If a question says 'use a pre-condition loop', you must use WHILE. Using a different loop loses marks, even if the program works.

Totalling and counting

Totalling keeps a running total: `Total ← Total + Value`.

Counting adds 1 each time something happens: `Count ← Count + 1`.

Set both to 0 before the loop starts.

e.g.Example
Marks typed: 45, 72, 60, 38, 90 Total = 45 + 72 + 60 + 38 + 90 = 305 Average = 305 / 5 = 61 (Python shows 61.0) Passes (50 or more): 72, 60, 90, so PassCount = 3
DECLARE Total : INTEGER
DECLARE PassCount : INTEGER
DECLARE Mark : INTEGER
DECLARE Count : INTEGER
Total ← 0
PassCount ← 0
FOR Count ← 1 TO 5
  OUTPUT "Enter mark"
  INPUT Mark
  Total ← Total + Mark
  IF Mark >= 50
    THEN
      PassCount ← PassCount + 1
  ENDIF
NEXT Count
OUTPUT "Total: ", Total
OUTPUT "Average: ", Total / 5
OUTPUT "Passes: ", PassCount
total = 0
pass_count = 0
for count in range(1, 6):
    mark = int(input("Enter mark: "))
    total = total + mark
    if mark >= 50:
        pass_count = pass_count + 1
print("Total:", total)
print("Average:", total / 5)
print("Passes:", pass_count)
!Watch out

If `Total ← 0` is inside the loop, it resets on every pass. The final total is then only the last mark.

String handling: LENGTH, UCASE, LCASE

A string is a sequence of characters. Each character has a position number.

`LENGTH(s)` gives the number of characters, and spaces count.

`UCASE(s)` gives the string in capitals. `LCASE(s)` gives it in lower case. The variable itself only changes if you assign the result back.

PseudocodePythonWhat it gives
LENGTH(s)len(s)number of characters
UCASE(s)s.upper()the string in capitals
LCASE(s)s.lower()the string in lower case
SUBSTRING(s, start, length)s[start-1 : start-1+length]part of the string
e.g.Example
"Madrid Spain" has 6 letters + 1 space + 5 letters = 12 characters. Output: 12 MADRID SPAIN madrid spain
DECLARE City : STRING
City ← "Madrid Spain"
OUTPUT LENGTH(City)
OUTPUT UCASE(City)
OUTPUT LCASE(City)
city = "Madrid Spain"
print(len(city))
print(city.upper())
print(city.lower())
?Why?

UCASE and LCASE make comparisons fair. A user may type yes, YES or Yes. `IF UCASE(Answer) = "YES"` accepts all three.

SUBSTRING and the first position: 1 or 0

`SUBSTRING(s, start, length)` takes a piece out of a string. You give the start position and how many characters you want.

In Cambridge pseudocode the first character is position 1. In Python the first character is position 0.

Python uses slicing: `s[start:end]` takes characters from start up to, but not including, end.

Try the toy: type MADRID as the string. Set the start to 4 and the length to 3, and check you get RID. Then try LENGTH, UCASE and LCASE on the same string.

CharacterMADRID
Pseudocode position123456
Python index012345
e.g.Example
SUBSTRING("MADRID", 4, 3): start at position 4 (R) and take 3 characters β†’ RID. Python: start = 4 - 1 = 3. End = 3 + 3 = 6. word[3:6] β†’ "RID". Rule: Python start = pseudocode start - 1. Python end = Python start + length.
DECLARE Word : STRING
Word ← "MADRID"
OUTPUT SUBSTRING(Word, 1, 3)
OUTPUT SUBSTRING(Word, 4, 3)
OUTPUT SUBSTRING(Word, 1, 1)
word = "MADRID"
print(word[0:3])
print(word[3:6])
print(word[0])
!Watch out

The exam says whether the first character is 0 or 1, so read the question. The third value in SUBSTRING is a length, not an end position.

There is something to try for this step in the IGCSE library.

Procedures and parameters

A subroutine is a named block of code that does one job. You write it once and call it whenever you need it.

A procedure is a subroutine that does a task but does not give a value back. You run it with `CALL`.

A parameter is a variable in the heading that receives a value when the subroutine is called. Cambridge uses up to three.

The value you pass in is called the argument. Here "Ana" and 2 are the arguments.

e.g.Example
CALL Greet("Ana", 2) puts "Ana" in Name and 2 in Times. The loop runs 2 times. Output: Hello Ana Hello Ana
PROCEDURE Greet(Name : STRING, Times : INTEGER)
  DECLARE Count : INTEGER
  FOR Count ← 1 TO Times
    OUTPUT "Hello ", Name
  NEXT Count
ENDPROCEDURE

CALL Greet("Ana", 2)
def greet(name, times):
    for count in range(1, times + 1):
        print("Hello", name)

greet("Ana", 2)
?Why?

Subroutines stop you repeating code. The program is shorter, each part can be tested on its own, and a fix is made in one place.

Functions: subroutines that return a value

A function is a subroutine that returns a value to the place where it was called.

The heading gives the type of the value it returns, such as `RETURNS REAL`. `RETURN` sends the value back.

A function gives a value, so you use it inside an expression or an OUTPUT. You do not use CALL.

ProcedureFunction
Returns a value?NoYes, with RETURN
PseudocodePROCEDURE … ENDPROCEDUREFUNCTION … RETURNS type … ENDFUNCTION
How it is usedCALL Name(…) on its own lineInside an expression: X ← Name(…)
Pythondef, with no return valuedef, with return
e.g.Example
Average(70, 64, 85) (70 + 64 + 85) / 3 = 219 / 3 = 73 The function returns 73, which is stored in Result. Output: Average: 73 (Python shows 73.0)
FUNCTION Average(Mark1 : REAL, Mark2 : REAL, Mark3 : REAL) RETURNS REAL
  RETURN (Mark1 + Mark2 + Mark3) / 3
ENDFUNCTION

DECLARE Result : REAL
Result ← Average(70, 64, 85)
OUTPUT "Average: ", Result
def average(mark1, mark2, mark3):
    return (mark1 + mark2 + mark3) / 3

result = average(70, 64, 85)
print("Average:", result)
!Watch out

A function must RETURN a value of the type in its heading. Writing CALL before a function, or RETURN inside a procedure, loses marks.

Local and global variables

Scope means the part of the program where a variable can be used.

A global variable is declared in the main program. Every part of the program can use it.

A local variable is declared inside a subroutine. It exists only while that subroutine runs, and nothing outside can see it.

In Python a function can read a global variable. To change it, the function must first say `global`.

e.g.Example
Bonus = 5, so Doubled = 5 Γ— 2 = 10. Score = 0 + 10 = 10. Output: 10 OUTPUT Doubled in the main program would be an error: Doubled no longer exists.
DECLARE Score : INTEGER        // global
Score ← 0

PROCEDURE AddBonus(Bonus : INTEGER)
  DECLARE Doubled : INTEGER    // local
  Doubled ← Bonus * 2
  Score ← Score + Doubled
ENDPROCEDURE

CALL AddBonus(5)
OUTPUT Score
score = 0  # global

def add_bonus(bonus):
    global score
    doubled = bonus * 2  # local
    score = score + doubled

add_bonus(5)
print(score)
?Why?

Local variables keep each subroutine separate. Two subroutines can both use a variable called Count without clashing. The memory is freed when the subroutine ends.

!Watch out

Too many global variables make bugs hard to find, because any line could change them. Pass values in as parameters and return results instead.

Library routines: MOD, DIV, ROUND, RANDOM

A library routine is a ready-made, tested subroutine that comes with the language. You use it without writing it.

Cambridge expects four: `MOD`, `DIV`, `ROUND` and `RANDOM`. MOD and DIV were in the arithmetic step.

`ROUND(Value, Places)` rounds to a number of decimal places. `ROUND(6.97354, 2)` gives 6.97.

`RANDOM()` gives a random REAL number from 0 to 1. Multiply it and round it to get the range you want.

e.g.Example
ROUND(19.987, 2) = 19.99 Say RANDOM() gives 0.62. 0.62 Γ— 5 = 3.1. ROUND(3.1, 0) = 3. 3 + 1 = 4. Output: You rolled 4 RANDOM() Γ— 5 is from 0 to 5, so Dice is always from 1 to 6.
DECLARE Price : REAL
DECLARE Dice : INTEGER
Price ← 19.987
OUTPUT ROUND(Price, 2)
Dice ← ROUND(RANDOM() * 5, 0) + 1
OUTPUT "You rolled ", Dice
import random
price = 19.987
print(round(price, 2))
dice = random.randint(1, 6)
print("You rolled", dice)
?Why?

Library routines save time. They are already tested, so they are reliable.

!Watch out

Python's `round()` sends an exact half to the nearest even number: `round(2.5)` gives 2 and `round(3.5)` gives 4. Cambridge pseudocode questions expect normal rounding, where 2.5 becomes 3.

Writing maintainable programs

A maintainable program is easy for another programmer, or you months later, to read, fix and update.

Use meaningful identifiers: `TotalPrice`, not `tp` or `x`.

Add comments that explain what a part does and why. Pseudocode comments start with `//`. Python comments start with `#`.

Use procedures and functions so each job lives in one named place. Use constants for fixed values, and indent code inside IFs, loops and subroutines.

e.g.Example
Hard to maintain: x ← y / 30 + 8.5 Maintainable (above): 600 / 30 = 20. 20 + 8.5 = 28.5 Output: Cost per pupil: 28.5
// Works out the cost of a school trip for one pupil
CONSTANT CoachCost ← 600.0
CONSTANT EntryFee ← 8.5

FUNCTION CostPerPupil(Pupils : INTEGER) RETURNS REAL
  // the coach is shared, the entry fee is paid by each pupil
  RETURN CoachCost / Pupils + EntryFee
ENDFUNCTION

OUTPUT "Cost per pupil: ", CostPerPupil(30)
# Works out the cost of a school trip for one pupil
COACH_COST = 600.0
ENTRY_FEE = 8.5

def cost_per_pupil(pupils):
    # the coach is shared, the entry fee is paid by each pupil
    return COACH_COST / pupils + ENTRY_FEE

print("Cost per pupil:", cost_per_pupil(30))
?Why?

Real programs are changed for years by many people. Clear code is cheaper to fix and less likely to get new bugs.

Study it

Open the study page and go one step at a time.

The steps for this lesson

Try it

The maths

Symbols first, then the words, then the equation. Change the numbers to try your own.

Check yourself

One question at a time. The reason shows after each answer.

Saved on this device.