An original Thinka practice paper modelled on the structure and difficulty of the Nov 2024 (V1) Cambridge International A Level Computer Science (9618) paper. Not affiliated with or reproduced from Cambridge.
PastPaper.section Programming Fundamentals and Modular Design
Answer all questions. Show clear workspace layout for pseudocode developments. Ensure correct type reference.
8 PastPaper.question · 60 PastPaper.marks
PastPaper.question 1 · short-answer
4 PastPaper.marks
In modular programming, variables can have different scopes. State what is meant by the 'scope' of a variable, and explain two benefits of using local variables rather than global variables in a program.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
1. Scope: This refers to the block or region of a program's code where a variable is recognized, defined, and can be accessed. 2. Benefits of local variables: (a) Local variables are only accessible within the subroutine they are declared in, which prevents other subroutines from accidentally modifying their values (avoiding side-effects). (b) Local variables are dynamic; they occupy memory only when the subroutine is executing and are destroyed afterward, conserving system memory.
PastPaper.markingScheme
1 mark for defining 'scope' (e.g., the region of the program where a variable is visible/accessible). 1 mark for identifying a benefit (e.g., prevents accidental changes/side-effects). 1 mark for explaining that benefit (e.g., code is easier to debug because changes are isolated). 1 mark for identifying/explaining a second benefit (e.g., memory is released when the subroutine finishes, or name reuse without conflict).
PastPaper.question 2 · short-answer
4 PastPaper.marks
In modular programming, parameters can be passed to subroutines either 'by value' (BYVAL) or 'by reference' (BYREF). Explain the difference between these two parameter-passing methods, describing the effect of each on the value of the original variable in the calling program.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
By Value (BYVAL): A copy of the value is made and passed to the subroutine. The subroutine operates on this local copy. Consequently, any changes made to the parameter within the subroutine have no effect on the original variable in the calling environment. By Reference (BYREF): The memory address of the actual variable is passed to the subroutine. The subroutine operates directly on the original memory location. Consequently, any changes made to the parameter inside the subroutine are immediately reflected in the original variable in the calling environment.
PastPaper.markingScheme
1 mark: Correctly describes passing 'by value' (a copy of the value is passed). 1 mark: States the effect of BYVAL (no change to the original variable). 1 mark: Correctly describes passing 'by reference' (the memory address/reference of the variable is passed). 1 mark: States the effect of BYREF (changes are made to the original variable).
PastPaper.question 3 · Structured Pseudocode Logic Construction
6 PastPaper.marks
A software developer needs to implement a procedure called AdjustScores to update candidate scores in an exam system. Write pseudocode to define the procedure AdjustScores, which receives: - Scores: a 1D array of 50 integers (index 1 to 50) passed by reference. - Threshold: an integer passed by value. - Bonus: an integer passed by value. - CountUpdated: an integer passed by reference.
The procedure must perform the following actions: 1. Reset CountUpdated to 0. 2. Iterate through the array Scores. 3. For any score that is strictly less than Threshold, add the Bonus to that score. 4. If an updated score exceeds 100, it must be capped at 100. 5. CountUpdated must track the total number of scores that were modified.
Use structured 9618 pseudocode for your solution.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
The procedure is designed with appropriate pass-by-reference (`BYREF`) and pass-by-value (`BYVAL`) modifiers matching the specifications.
``` PROCEDURE AdjustScores(BYREF Scores : ARRAY[1:50] OF INTEGER, BYVAL Threshold : INTEGER, BYVAL Bonus : INTEGER, BYREF CountUpdated : INTEGER) DECLARE Index : INTEGER CountUpdated <- 0 FOR Index <- 1 TO 50 IF Scores[Index] < Threshold THEN Scores[Index] <- Scores[Index] + Bonus IF Scores[Index] > 100 THEN Scores[Index] <- 100 ENDIF CountUpdated <- CountUpdated + 1 ENDIF NEXT Index ENDPROCEDURE ```
PastPaper.markingScheme
1 mark: Correct procedure header including BYREF and BYVAL keywords with parameter types. 1 mark: Initializing CountUpdated to 0 before the loop. 1 mark: Loop syntax indexing from 1 to 50. 1 mark: Correct comparison condition checking if Scores[Index] < Threshold. 1 mark: Correct score update logic, including capping at 100 if the new score exceeds 100. 1 mark: Incrementing CountUpdated inside the comparison block and appropriate structure closures (ENDIF, NEXT, ENDPROCEDURE).
PastPaper.question 4 · Structured Pseudocode Logic Construction
6 PastPaper.marks
A programmer needs a recursive function CleanString to strip out all space characters (' ') from a given string. Write pseudocode to define the recursive function CleanString, which takes a string InString as a parameter and returns a string with all space characters removed.
You should assume the following built-in string handling functions are available: - LENGTH(s) : returns the number of characters in string s - LEFT(s, n) : returns the left-most n characters of string s - RIGHT(s, n) : returns the right-most n characters of string s - MID(s, start, length) : returns a substring of length characters starting at position start
Your solution must be recursive and must not use any loop structures.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
The function processes the first character of the string, recursively cleans the remainder of the string, and combines them depending on whether the character is a space.
1 mark: Correct FUNCTION header defining parameter InString : STRING and returning STRING. 1 mark: Base case condition to check for empty string/length 0 and returning "". 1 mark: Correct extraction of the first character using MID or LEFT. 1 mark: Correct extraction of the remaining substring using RIGHT/MID combined with LENGTH. 1 mark: Selection statement comparing the extracted character to ' '. 1 mark: Correct recursive calls returning the concatenated rest of string or just the recursive call if a space is found, with correct ENDFUNCTION.
PastPaper.question 5 · Structured Pseudocode Logic Construction
6 PastPaper.marks
A software module manages active users. Write pseudocode for a function RegisterUser that validates and inserts a new username into a 1D array of active users. The function should take the following parameters: - UserArray: a 1D array of 200 strings (index 1 to 200) passed by reference. - ActiveCount: an integer tracking the current number of valid users in the array, passed by reference. - NewUser: a string representing the new username, passed by value.
The function must do the following: 1. Check if the array is already full (contains 200 users). If so, return FALSE. 2. Check if NewUser is an empty string. If so, return FALSE. 3. Search UserArray from index 1 up to ActiveCount to check if NewUser already exists. If it exists, return FALSE. 4. If all validations pass, insert NewUser at the next available position in the array, increment ActiveCount by 1, and return TRUE.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
The function performs a sequence of boundary, presence, and uniqueness validation checks before modifying the array elements and counter passed by reference.
``` FUNCTION RegisterUser(BYREF UserArray : ARRAY[1:200] OF STRING, BYREF ActiveCount : INTEGER, BYVAL NewUser : STRING) RETURNS BOOLEAN DECLARE Index : INTEGER IF ActiveCount >= 200 THEN RETURN FALSE ENDIF IF NewUser = "" THEN RETURN FALSE ENDIF FOR Index <- 1 TO ActiveCount IF UserArray[Index] = NewUser THEN RETURN FALSE ENDIF NEXT Index ActiveCount <- ActiveCount + 1 UserArray[ActiveCount] <- NewUser RETURN TRUE ENDFUNCTION ```
PastPaper.markingScheme
1 mark: Correct function header with parameters declared using appropriate BYREF/BYVAL modifiers and returning BOOLEAN. 1 mark: Checking if active count indicates a full array and returning FALSE. 1 mark: Checking for an empty string input and returning FALSE. 1 mark: Loop structure from 1 to ActiveCount comparing each element with NewUser and returning FALSE upon match. 1 mark: Correctly inserting NewUser at the next index (ActiveCount + 1) and incrementing ActiveCount. 1 mark: Returning TRUE upon successful completion of insertions, with correct ENDFUNCTION.
PastPaper.question 6 · written-answer
9 PastPaper.marks
In software development, robust file handling is essential. Write a pseudocode procedure, ReadTemperatures(Filename : STRING), that reads integer temperature readings from a text file, where each line of the file contains a single temperature. The procedure must calculate and output the average of the valid temperatures read. Your pseudocode must include exception handling to: (1) Catch any file-related error (such as file not found) and output 'Error: File could not be opened'. (2) Catch any conversion error if a line does not contain a valid integer, outputting 'Warning: Invalid data ignored on line ' followed by the line number, and then continue processing the rest of the file. Ensure that if the file was successfully opened, it is safely closed before the procedure terminates.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
The proposed solution uses structured exception handling (TRY...CATCH...ENDTRY) to manage runtime errors during file operations and string-to-integer conversions. [Pseudocode Structure]: PROCEDURE ReadTemperatures(Filename : STRING) DECLARE Line : STRING DECLARE Temp, Total, Count, LineNum : INTEGER DECLARE FileOpen : BOOLEAN Total <- 0 Count <- 0 LineNum <- 0 FileOpen <- FALSE TRY OPENFILE Filename FOR READ FileOpen <- TRUE WHILE NOT EOF(Filename) READFILE Filename, Line LineNum <- LineNum + 1 TRY Temp <- STRING_TO_NUM(Line) Total <- Total + Temp Count <- Count + 1 CATCH OUTPUT "Warning: Invalid data ignored on line ", LineNum ENDTRY ENDWHILE IF Count > 0 THEN OUTPUT "Average temperature: ", Total / Count ELSE OUTPUT "No valid data to calculate average." ENDIF CATCH OUTPUT "Error: File could not be opened" ENDTRY IF FileOpen = TRUE THEN CLOSEFILE Filename ENDIF ENDPROCEDURE
PastPaper.markingScheme
1 mark: Correct PROCEDURE header with string parameter 'Filename'. 1 mark: Outer TRY...CATCH block containing the OPENFILE statement. 1 mark: Reading the file in a loop until EOF(Filename) is TRUE. 1 mark: Correctly incrementing and maintaining a line counter variable. 1 mark: Nested TRY...CATCH block inside the loop to isolate conversion errors. 1 mark: Correct conversion of string to integer (e.g., using STRING_TO_NUM or equivalent cast) and updating accumulator/counter. 1 mark: Outputting the correct warning message with the line number when a conversion fails. 1 mark: Outputting the 'Error: File could not be opened' message in the outer CATCH block. 1 mark: Ensuring that CLOSEFILE is executed if and only if the file was successfully opened (using a flag or safe status check).
An airline company assigns flight codes to its fleet. Each flight code must follow a strict validation format: - Must be exactly 9 characters long. - The first two characters must be uppercase letters (e.g., 'AB'). - The third character must be a hyphen '-'. - The remaining six characters must be digits (e.g., '123456').
An example of a valid flight code is 'QA-908123'.
The validation architecture utilizes a modular design. Two helper functions already exist: - IsUpperAlpha(Ch : CHAR) RETURNS BOOLEAN: returns TRUE if Ch is an uppercase letter ('A' to 'Z') and FALSE otherwise. - IsDigit(Ch : CHAR) RETURNS BOOLEAN: returns TRUE if Ch is a numerical digit ('0' to '9') and FALSE otherwise.
(a) Write pseudocode for the function ValidateCode(Code : STRING) RETURNS BOOLEAN. Your function must make use of the existing helper functions IsUpperAlpha and IsDigit to perform the validation. [6 marks]
(b) The development team wants to verify the robustness of this validation module. Complete a test plan by describing four distinct test cases in a table layout. You must include: - One Normal test case - One Boundary test case - Two Erroneous test cases testing different error conditions For each test case, state the Test Data, Type of Test Data, Expected Outcome, and Reason. [4 marks]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
Part (a) Pseudocode Solution:
FUNCTION ValidateCode(Code : STRING) RETURNS BOOLEAN DECLARE I : INTEGER
IF LENGTH(Code) <> 9 THEN RETURN FALSE ENDIF
IF NOT IsUpperAlpha(MID(Code, 1, 1)) OR NOT IsUpperAlpha(MID(Code, 2, 1)) THEN RETURN FALSE ENDIF
IF MID(Code, 3, 1) <> \"-\" THEN RETURN FALSE ENDIF
FOR I <- 4 TO 9 IF NOT IsDigit(MID(Code, I, 1)) THEN RETURN FALSE ENDIF ENDFOR
RETURN TRUE ENDFUNCTION
Part (b) Test Plan Table:
1. Normal: - Test Data: \"QA-908123\" - Type: Normal - Expected Outcome: TRUE - Reason: Standard valid format meeting all specifications.
2. Boundary: - Test Data: \"AZ-099999\" - Type: Boundary - Expected Outcome: TRUE - Reason: Verifies extreme outer range bounds for uppercase characters ('A', 'Z') and digits ('0', '9').
3. Erroneous 1: - Test Data: \"QA-12345\" - Type: Erroneous - Expected Outcome: FALSE - Reason: Violates total length requirement (8 characters instead of 9).
4. Erroneous 2: - Test Data: \"qa-123456\" - Type: Erroneous - Expected Outcome: FALSE - Reason: Violates character class restriction (lowercase alphabetic characters used).
PastPaper.markingScheme
Part (a) [6 Marks Total]: - 1 Mark: Correct function header and ENDFUNCTION with appropriate parameters/return type. - 1 Mark: Checks total length is exactly 9. - 1 Mark: Uses IsUpperAlpha to validate first two positions. - 1 Mark: Validates the third position is exactly a hyphen. - 1 Mark: Implements a loop from index 4 to 9. - 1 Mark: Uses IsDigit within the loop to validate remaining characters, returning TRUE only if all pass.
Part (b) [4 Marks Total]: - 1 Mark: Valid Normal test case with expected output TRUE and logical reason. - 1 Mark: Valid Boundary test case with expected output TRUE testing character domain limits. - 1 Mark: Valid Erroneous test case 1 with expected output FALSE and logical explanation (e.g. length, structural mismatch). - 1 Mark: Valid Erroneous test case 2 testing a DIFFERENT error vector with expected output FALSE and logical explanation (e.g. lowercase letters, invalid characters).
PastPaper.question 8 · Complete Data Array Handling Class Solution
15 PastPaper.marks
A software system is being developed to manage store inventory using object-oriented programming. The system uses an Item class to represent individual stock items. The Item class has the following attributes and methods: - ItemID : STRING - Quantity : INTEGER - Price : REAL - GetItemID() RETURNS STRING - SetQuantity(QtyIn : INTEGER) - GetQuantity() RETURNS INTEGER - SetPrice(PriceIn : REAL) - GetPrice() RETURNS REAL
Write pseudocode to declare the class InventoryTracker. The class must include: - A private array Stock of 100 Item objects. - A private integer NumItems to store the current number of unique items in the stock array. - A constructor NEW() to initialize NumItems to 0. - A function AddItem(ID : STRING, Qty : INTEGER, Pr : REAL) RETURNS BOOLEAN. This function checks if an item with the given ID already exists in the Stock array. If it exists, the function updates its quantity and price to the new values and returns TRUE. If it does not exist, and there is space in the array, it creates a new Item object at the next available position, increments NumItems, and returns TRUE. If the array is full, it returns FALSE. - A function CalculateTotalValue() RETURNS REAL. This function calculates and returns the total value of all active stock items by multiplying each item's quantity by its price.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
CLASS InventoryTracker PRIVATE Stock : ARRAY[0:99] OF Item PRIVATE NumItems : INTEGER
PUBLIC PROCEDURE NEW() NumItems <- 0 ENDPROCEDURE
PUBLIC FUNCTION AddItem(ID : STRING, Qty : INTEGER, Pr : REAL) RETURNS BOOLEAN DECLARE Index : INTEGER FOR Index <- 0 TO NumItems - 1 IF Stock[Index].GetItemID() = ID THEN Stock[Index].SetQuantity(Qty) Stock[Index].SetPrice(Pr) RETURN TRUE ENDIF NEXT Index
PUBLIC FUNCTION CalculateTotalValue() RETURNS REAL DECLARE Total : REAL DECLARE Index : INTEGER Total <- 0.0 FOR Index <- 0 TO NumItems - 1 Total <- Total + (Stock[Index].GetQuantity() * Stock[Index].GetPrice()) NEXT Index RETURN Total ENDFUNCTION ENDCLASS
PastPaper.markingScheme
1 mark: CLASS InventoryTracker and ENDCLASS headers. 2 marks: Private attributes declared correctly (Stock as ARRAY[0:99] OF Item, NumItems as INTEGER). 1 mark: Constructor NEW() correctly sets NumItems to 0. 1 mark: Function header for AddItem with correct parameters and BOOLEAN return type. 2 marks: Correct loop structure in AddItem to check existing Stock up to NumItems - 1. 2 marks: Correct condition checking for existing ID, updating Quantity, Price, and returning TRUE. 1 mark: Correct boundary check checking if NumItems is 100 (or >= 100) and returning FALSE. 2 marks: Correct instantiation of a new Item object at Stock[NumItems], incrementing NumItems, and returning TRUE. 1 mark: Function header for CalculateTotalValue returning REAL. 2 marks: Correct loop inside CalculateTotalValue summing (Quantity * Price) for each active item, and returning the accumulated sum.