An original Thinka practice paper modelled on the structure and difficulty of the Jun 2024 (V2) Cambridge International A Level Computer Science (9618) paper. Not affiliated with or reproduced from Cambridge.
Paper 12: Theory Fundamentals
Answer all questions. Dark blue/black ink only. No calculators.
8 PastPaper.question · 75 PastPaper.marks
PastPaper.question 1 · Short Answer
5 PastPaper.marks
Perform the subtraction of the denary number 54 from the denary number -43 using 8-bit two's complement binary addition. That is, calculate \(-43 - 54\).
Show all your working by converting both numbers into 8-bit two's complement representation, adding them, and state whether an overflow error has occurred with a suitable justification.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
1. Convert -43 to 8-bit two's complement: +43 in binary is 00101011. Invert bits: 11010100. Add 1: 11010101. 2. Convert -54 to 8-bit two's complement: +54 in binary is 00110110. Invert bits: 11001001. Add 1: 11001010. 3. Add the two binary numbers: 11010101 (-43) + 11001010 (-54) ----------- 110011111 (9-bit result, discard the carry out of MSB to get 8-bit result: 10011111). 4. 10011111 in two's complement represents -97. 5. Overflow check: The result -97 is within the valid range for 8-bit signed two's complement numbers (which is -128 to +127). Alternatively, the sign bit of both operands is 1 (negative) and the sign bit of the sum is 1 (negative), meaning the sign is correct, so no overflow occurred.
PastPaper.markingScheme
1 mark: Correct 8-bit two's complement representation for -43 (11010101) 1 mark: Correct 8-bit two's complement representation for -54 (11001010) 1 mark: Attempting addition of the two two's complement values (showing carry bits or sum process) 1 mark: Correct 8-bit binary sum (10011111) 1 mark: Correctly stating that NO overflow occurred with a valid explanation (e.g. -97 is within range [-128, +127], or adding two negative numbers yielded a negative number / carry-in to MSB equals carry-out of MSB)
PastPaper.question 2 · Short Answer
5 PastPaper.marks
The fetch stage of the Fetch-Execute cycle can be described using Register Transfer Notation (RTN).
(a) Write down the four main steps of the fetch stage using Register Transfer Notation (RTN). [4] (b) Describe how the Program Counter (PC) and the Memory Address Register (MAR) cooperate during the very first step of this stage. [1]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
The Fetch stage consists of transferring the instruction address from the Program Counter to the Memory Address Register, incrementing the PC to point to the next instruction, reading the instruction from memory into the Memory Data Register, and finally transferring it to the Current Instruction Register.
Steps in RTN: 1. MAR <- [PC] (or MAR <- PC) 2. PC <- [PC] + 1 (or PC <- PC + 1) 3. MDR <- [[MAR]] (or MDR <- [Memory(MAR)]) 4. CIR <- [MDR] (or CIR <- MDR)
For part (b), the PC holds the address of the next instruction to be fetched. This address is copied to the MAR, which acts as the physical interface to the address bus, so the control unit can retrieve the instruction from that memory location.
PastPaper.markingScheme
Part (a) [4 marks]: - 1 mark: MAR <- [PC] - 1 mark: PC <- [PC] + 1 - 1 mark: MDR <- [[MAR]] - 1 mark: CIR <- [MDR] (Accept equivalent standard notations, e.g., MAR <- PC, MDR <- [MAR])
Part (b) [1 mark]: - 1 mark: Explanation that PC contains the address of the next instruction to be executed, which must be loaded into MAR so that the address bus can reference that specific memory address to fetch the instruction.
PastPaper.question 3 · Short Answer
5 PastPaper.marks
A student database table, `STUDENT_ENROLMENT`, contains the following attributes: `StudentID`, `StudentName`, `CourseCode`, `CourseTitle`, `TutorName`, `TutorOffice`
The primary key is the composite key `(StudentID, CourseCode)`. Each student has only one name. Each course has a single course title and is taught by exactly one tutor who has one office.
(a) Explain why this table is in First Normal Form (1NF). [1] (b) Identify the partial key dependencies in this table and explain how they violate Second Normal Form (2NF). [2] (c) Describe the table structures (including primary keys) resulting from converting this relation into 2NF. [2]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) The table is in 1NF because there are no repeating groups of attributes and all data values are atomic (each cell contains a single value). (b) Partial dependencies exist because: - `StudentName` depends only on `StudentID`, which is only part of the composite primary key `(StudentID, CourseCode)`. - `CourseTitle`, `TutorName`, and `TutorOffice` depend only on `CourseCode`, which is also only part of the composite primary key. This violates 2NF because 2NF requires that all non-key attributes have full functional dependency on the entire primary key. (c) To convert to 2NF, we remove partial dependencies by creating three tables: 1. `STUDENT` with primary key `StudentID` and attribute `StudentName`. 2. `COURSE` with primary key `CourseCode` and attributes `CourseTitle`, `TutorName`, `TutorOffice`. 3. `ENROLMENT` with composite primary key `(StudentID, CourseCode)` to link students and courses.
PastPaper.markingScheme
Part (a) [1 mark]: - 1 mark: Explaining that all attributes are atomic / there are no repeating groups / a unique primary key is defined.
Part (b) [2 marks]: - 1 mark: Identifying at least one partial key dependency (e.g., StudentName depends on StudentID, OR CourseTitle/Tutor depends on CourseCode). - 1 mark: Explaining that 2NF is violated because these non-key attributes depend on only part of the composite primary key rather than the entire key.
Part (c) [2 marks]: - 1 mark: Correctly listing the three split entities: Student, Course, and the link/enrolment table. - 1 mark: Identifying the correct primary keys for all three tables (StudentID for Student, CourseCode for Course, (StudentID, CourseCode) for Enrolment).
PastPaper.question 4 · Short Answer
5 PastPaper.marks
An IP address is given as `192.168.45.138` with a subnet mask of `255.255.255.224`.
(a) Write the subnet mask `255.255.255.224` in 32-bit binary notation (grouped as four 8-bit octets). [1] (b) Calculate the Network ID (subnet address) for this IP address. Show your working by demonstrating the bitwise AND process on the last octet in binary. [3] (c) State the address class of the IP address `192.168.45.138`. [1]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) The subnet mask 255.255.255.224 converted to binary: - 255 = 11111111 - 224 = 11100000 (since 128 + 64 + 32 = 224) So, the binary is `11111111.11111111.11111111.11100000`.
(b) The first three octets of the subnet mask are 255, so the first three octets of the Network ID remain unchanged: `192.168.45`. For the fourth octet: - IP address octet 138 in binary: `10001010` (since 128 + 8 + 2 = 138) - Subnet mask octet 224 in binary: `11100000` - Perform bitwise AND: 10001010 AND 11100000 -------- 10000000 - Convert `10000000` back to denary: 128. Therefore, the Network ID is `192.168.45.128`.
(c) The first octet is 192. IP addresses starting with 192 to 223 belong to Class C.
PastPaper.markingScheme
Part (a) [1 mark]: - 1 mark: Correctly writing the 32-bit binary representation: `11111111.11111111.11111111.11100000` (allow spaces or dots as separators).
Part (b) [3 marks]: - 1 mark: Converting 138 to binary `10001010` and 224 to binary `11100000`. - 1 mark: Showing bitwise AND operation resulting in `10000000`. - 1 mark: Correct final Network ID in dotted decimal notation: `192.168.45.128`.
Part (c) [1 mark]: - 1 mark: Identifying Class C.
PastPaper.question 5 · Structured
13.75 PastPaper.marks
### Part (a) Compare the ASCII and Unicode character representation standards. Your answer should explain why Unicode was developed and the impact of using Unicode on data transmission and storage. [5]
### Part (b) An analogue audio signal is converted into a digital format. Describe how the sampling rate and sampling resolution affect: 1. the quality of the recorded sound. 2. the size of the resulting audio file. [5]
### Part (c) An audio engineer records a 40-second audio track. The track is stereo (2 channels). The audio is sampled at a frequency of 48 kHz. Each sample is encoded using a 16-bit resolution.
Calculate the file size of the uncompressed audio recording in Megabytes (MB). Assume \(1 \text{ MB} = 1,000,000 \text{ bytes}\). Show all your working. [3.75]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
### Part (a) - ASCII uses 7 or 8 bits per character, limiting it to 128 or 256 characters. - ASCII can represent standard English but lacks support for multi-lingual alphabets and complex symbols (e.g., Chinese, Arabic, emojis). - Unicode was developed to provide a universal, unique standard where every character in every language can be represented. - Unicode uses larger widths (typically 8 to 32 bits, such as UTF-8 or UTF-16). - Impact: Using larger bit representations increases file size, requires more storage space, and increases transmission time/bandwidth requirements over networks.
### Part (b) 1. Quality of recorded sound: - Sampling rate (frequency of sampling) determines how closely the digital wave matches the original analogue wave; higher rates reduce aliasing and accurately capture higher frequency sounds. - Sampling resolution (bit depth) determines the precision of each sample; higher resolutions reduce quantization noise/error and provide a greater dynamic range. 2. Size of resulting audio file: - Increasing either the sampling rate or resolution means more binary data is captured and stored per second, leading directly to larger file sizes.
### Part (a) [Max 5 marks] - 1 mark: ASCII uses 7 or 8 bits representing 128 or 256 characters. - 1 mark: ASCII is limited to English/Latin characters, unable to support global scripts. - 1 mark: Unicode was designed to support all world languages and special characters. - 1 mark: Unicode uses variable or fixed larger sizes (e.g., 8, 16, or 32 bits). - 1 mark: Unicode results in larger file sizes / transmission latency compared to ASCII.
### Part (b) [Max 5 marks] - 1 mark: Defining sampling rate (samples per second) and sampling resolution (bits per sample). - 1 mark: Higher sampling rate improves accuracy of the frequency reproduction / captures higher frequencies. - 1 mark: Higher sampling resolution reduces quantization errors / improves amplitude accuracy. - 1 mark: Raising either parameter directly increases the quantity of data stored. - 1 mark: Explaining that file size increases because more bits are saved per second.
### Part (c) [3.75 marks] - 1 mark: Correct formula or approach (Rate * Resolution * Channels * Duration). - 0.75 marks: Substitution of values: \( 48000 \times 16 \times 2 \times 40 \). - 1 mark: Correct step dividing by 8 to get bytes (\( 7,680,000 \text{ bytes} \)). - 1 mark: Correct conversion to MB (\( 7.68 \text{ MB} \) using decimal, or \( 7.32 \text{ MiB} \) if binary division is explicitly shown).
PastPaper.question 6 · Structured
13.75 PastPaper.marks
### Part (a) The Fetch-Execute (F-E) cycle is the foundational process of a CPU. Describe the role and changes in contents of the following registers during the **fetch** phase of the cycle: 1. Program Counter (PC) 2. Memory Address Register (MAR) 3. Memory Data Register (MDR) [6]
### Part (b) The system bus consists of the Address Bus, Data Bus, and Control Bus. 1. Explain how the width of the **Address Bus** affects the computer's memory capacity. [2] 2. Explain how the width of the **Data Bus** affects system performance. [2]
### Part (c) In assembly language, different addressing modes are used to access data. Consider the following two addressing modes: - **Direct Addressing** (e.g., `LDD 200`) - **Indirect Addressing** (e.g., `LDI 200`)
Describe the difference between these two addressing modes in terms of how the actual data is retrieved from memory, and identify how many memory read operations are required for each mode to obtain the operand value. [3.75]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
### Part (a) 1. Program Counter (PC): - Holds the address of the next instruction to be fetched from memory. - At the start of the fetch phase, the address in the PC is copied to the MAR. - The PC is then immediately incremented to point to the next instruction in sequence. 2. Memory Address Register (MAR): - Receives the address copied from the PC. - Holds this address on the address bus to signal the location in RAM to be read. 3. Memory Data Register (MDR): - Receives the instruction or data sent from RAM via the data bus. - Holds the data temporarily before it is passed to the Current Instruction Register (CIR).
### Part (b) 1. Address Bus Width: - The number of lines in the address bus determines the maximum number of unique memory locations that can be directly addressed (\( 2^n \) locations, where \( n \) is the width). - A wider address bus directly increases the maximum physical memory capacity (RAM) the processor can support. 2. Data Bus Width: - The width of the data bus determines how many bits of data can be transferred simultaneously in a single clock cycle. - A wider data bus increases data throughput and minimizes the number of memory transfer operations needed for large data types, enhancing processing speed.
### Part (c) - Direct Addressing (`LDD 200`): The operand address field (200) holds the actual memory address where the target data is stored. The CPU reads memory address 200 directly to retrieve the value. This requires **1 memory read** operation. - Indirect Addressing (`LDI 200`): The address field (200) holds another address. The CPU reads memory address 200 to obtain a second address (e.g., 500), and then reads address 500 to find the actual data value. This requires **2 memory read** operations.
PastPaper.markingScheme
### Part (a) [Max 6 marks] - PC (Max 2 marks): - 1 mark: Holds the address of the next instruction. - 1 mark: Value is copied to the MAR at the start of the fetch phase. - 1 mark: PC is incremented to point to the next instruction. - MAR (Max 2 marks): - 1 mark: Receives/holds the address of the memory location to be accessed. - 1 mark: Directs this address to memory via the address bus. - MDR (Max 2 marks): - 1 mark: Receives/holds the instruction/data retrieved from RAM. - 1 mark: Receives this data from the data bus.
### Part (b) [Max 4 marks] - 1 mark: Address bus width determines the address space (number of addressable locations). - 1 mark: Formula explanation: \( 2^n \) unique locations, thus a wider bus supports more RAM. - 1 mark: Data bus width determines the word size / bits transferred at once. - 1 mark: Wider data bus reduces memory-CPU read/write cycles, improving execution speed.
### Part (c) [3.75 marks] - 1 mark: Correct explanation of Direct Addressing (address contains actual operand data value). - 0.75 marks: States Direct Addressing requires 1 memory read operation. - 1 mark: Correct explanation of Indirect Addressing (address contains pointer/address to the actual operand data value). - 1 mark: States Indirect Addressing requires 2 memory read operations.
PastPaper.question 7 · Structured
13.75 PastPaper.marks
### Part (a) A school database stores student enrollment information in a single, unnormalized table: `EnrollmentSummary(StudentID, StudentName, CourseID, CourseTitle, Instructor, Grade)`
The composite primary key for this table is `(StudentID, CourseID)`.
1. Explain why this table is in First Normal Form (1NF) but **not** in Second Normal Form (2NF). Refer to specific fields in your explanation. [3] 2. Describe the steps required to normalize this table to 2NF. Show the resulting table structures, clearly identifying the primary keys and foreign keys. [3]
### Part (b) In relational databases: 1. Define the term **referential integrity** and explain how it is enforced using foreign keys. [2] 2. Explain the difference between a **primary key** and a **candidate key**. [2]
### Part (c) Write a SQL query to display the `StudentID`, `StudentName`, and `Grade` for all students who scored a grade of 'A' or 'A+' in the course with `CourseTitle` equal to 'Computer Science'. You must use the normalized 2NF tables: - `STUDENT(StudentID, StudentName)` - `COURSE(CourseID, CourseTitle, Instructor)` - `ENROLLMENT(StudentID, CourseID, Grade)` [3.75]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
### Part (a) 1. Why 1NF but not 2NF: - The table is in 1NF because there are no repeating groups of columns, and all attribute values are atomic (each cell contains one value). - The table is not in 2NF because it contains partial key dependencies. A partial key dependency occurs when a non-key attribute depends on only part of the composite primary key `(StudentID, CourseID)`. - Specifically, `StudentName` depends only on `StudentID`, while `CourseTitle` and `Instructor` depend only on `CourseID`.
2. Steps to normalize to 2NF and relations: - Create separate relations to isolate partial key dependencies: - **STUDENT**(StudentID, StudentName) - Primary Key: `StudentID` - **COURSE**(CourseID, CourseTitle, Instructor) - Primary Key: `CourseID` - **ENROLLMENT**(StudentID, CourseID, Grade) - Composite Primary Key: `(StudentID, CourseID)` - Foreign keys are defined in the ENROLLMENT table: - `StudentID` references `STUDENT(StudentID)` - `CourseID` references `COURSE(CourseID)`
### Part (b) 1. Referential Integrity: - Referential integrity is the property ensuring that relationships between tables remain consistent. Every foreign key value must match an existing primary key value in the parent table (or be NULL). - It is enforced by the DBMS checking/restricting database modifications (e.g., rejecting attempts to delete a parent record when child records reference it, or using cascade-delete). 2. Primary Key vs Candidate Key: - A candidate key is any attribute or combination of attributes that uniquely identifies a record in a table without redundant data. - The primary key is the specific candidate key selected by the database designer to uniquely identify records and establish relations.
### Part (c) ```sql SELECT STUDENT.StudentID, STUDENT.StudentName, ENROLLMENT.Grade FROM STUDENT INNER JOIN ENROLLMENT ON STUDENT.StudentID = ENROLLMENT.StudentID INNER JOIN COURSE ON ENROLLMENT.CourseID = COURSE.CourseID WHERE COURSE.CourseTitle = 'Computer Science' AND (ENROLLMENT.Grade = 'A' OR ENROLLMENT.Grade = 'A+'); ```
PastPaper.markingScheme
### Part (a) [Max 6 marks] - 1 mark: Defines 1NF (atomic values, no repeating groups). - 1 mark: Defines partial key dependency (non-key attribute depends on part of a composite key). - 1 mark: Identifies partial dependencies in the scenario (StudentName depends on StudentID; CourseTitle/Instructor depend on CourseID). - 1 mark: Explains the process of isolating dependent attributes into new tables. - 1 mark: Correct table structures with designated Primary Keys (STUDENT, COURSE, ENROLLMENT). - 1 mark: Correctly identifies Foreign Keys in ENROLLMENT referencing the other tables.
### Part (b) [Max 4 marks] - 1 mark: Defines referential integrity as database consistency across related tables. - 1 mark: Explains enforcement: foreign key value must point to a valid parent primary key (or be null/prevent deletion of referenced data). - 1 mark: Defines candidate key as any unique attribute/set of attributes capable of identifying a row. - 1 mark: Identifies primary key as the chosen candidate key used by the database.
### Part (c) [3.75 marks] - 1 mark: Correct `SELECT` statement specifying `STUDENT.StudentID, STUDENT.StudentName, ENROLLMENT.Grade` (or matching columns). - 1.25 marks: Correct table join syntax linking `STUDENT`, `ENROLLMENT`, and `COURSE` via foreign keys. - 0.75 marks: Correct WHERE clause condition for course title (`COURSE.CourseTitle = 'Computer Science'`). - 0.75 marks: Correct conditional logic for Grades (`ENROLLMENT.Grade = 'A' OR ENROLLMENT.Grade = 'A+'` or `ENROLLMENT.Grade IN ('A', 'A+')`).
PastPaper.question 8 · Structured
13.75 PastPaper.marks
### Part (a) An IP address is used to identify a device on a network. 1. Describe the structure of an IPv4 address, explaining the role of the **network ID** and **host ID** parts of the address. [3] 2. An organization is assigned the classless IP block `192.168.10.0/26`. Explain the purpose of the `/26` CIDR notation (subnet mask) and calculate how many unique host addresses are available for use in this subnet. [3]
### Part (b) When data is transmitted across the internet, packet switching is used. Describe the role of a **router** in a packet-switched network, including how it uses routing tables and headers to direct packets to their destination. [4]
### Part (c) Compare the **Client-Server** and **Peer-to-Peer (P2P)** network models. State **one** advantage and **one** disadvantage of using a Peer-to-Peer model instead of a Client-Server model. [3.75]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
### Part (a) 1. Structure of IPv4: - An IPv4 address is a 32-bit binary number, represented as four denary octets separated by dots. - Network ID: Represents the specific physical network segment. Routers use this to forward packets to the destination network. - Host ID: Identifies the unique device/node on that network segment. 2. Subnet notation `/26` and host calculation: - The `/26` CIDR notation indicates that the first 26 bits of the 32-bit IP address are the subnet mask / network prefix, leaving 6 bits (32 - 26 = 6) for hosting devices. - The total number of addresses is \( 2^6 = 64 \). - The number of unique host addresses available is \( 64 - 2 = 62 \) (subtracting the network identifier `.0` and the broadcast address `.63`).
### Part (b) - Routers act as nodes connecting multiple networks together. - When a router receives a packet, it reads the packet header to extract the destination IP address. - It consults its routing table (which maps destination networks to optimal next hops). - It determines the most efficient path/interface to transmit the packet. - If network links are congested, the router dynamically updates path selections to route around congestion.
### Part (c) - **Client-Server Model**: Dedicated servers manage resources, security, and services which client devices access. Resources are centralized. - **Peer-to-Peer (P2P) Model**: Every node (peer) acts as both a client and a server, directly sharing resources/files with others without central authority. - **Advantage of P2P (over Client-Server)**: Easier/cheaper to set up as no specialized central server hardware or administrative software is required; resilient as there is no single point of failure. - **Disadvantage of P2P**: Security is decentralized and harder to manage; data backups are inconsistent since they must be done individually per peer; performance can suffer when multiple peers download from a single machine.
PastPaper.markingScheme
### Part (a) [Max 6 marks] - 1 mark: IPv4 is a 32-bit binary structure (often 4 decimal octets). - 1 mark: Network ID identifies the specific network block to route traffic. - 1 mark: Host ID identifies the individual node within that network. - 1 mark: `/26` indicates 26 network/subnet bits (and 6 host bits). - 1 mark: Calculation of total addresses (\( 2^6 = 64 \)). - 1 mark: Identifies subtraction of 2 (network address and broadcast address) to yield 62 usable hosts.
### Part (b) [Max 4 marks] - 1 mark: Router connects separate networks/subnets. - 1 mark: Inspects the packet header to extract the destination IP address. - 1 mark: Uses a routing table to find the next hop/best path. - 1 mark: Forwards the packet to the next router/destination node. - 1 mark: Performs dynamic routing to handle congestion/broken paths.
### Part (c) [3.75 marks] - 1 mark: Contrast Client-Server (central server) with P2P (equal status nodes sharing resources directly). - 1 mark: Identifies a valid advantage of P2P (e.g., lower hardware costs, easy setup, no single point of failure). - 1 mark: Identifies a valid disadvantage of P2P (e.g., security risks, hard to run backups, network performance dependent on peers). - 0.75 marks: Clarity of comparative analysis demonstrating a strong understanding of both architectures.
Paper 22: Problem-solving & Programming Skills
Answer all pseudocode design challenges. Use variables from the given insert listings.
A meteorology station records daily temperatures in a 1D array of Real values. You are required to write a pseudocode function `LongestRisingStreak` to find the longest continuous sequence of days where the temperature strictly increases from one day to the next.
The function takes two parameters: 1. `TempArray`: A 1D array of Real numbers. 2. `NumDays`: An Integer representing the total number of elements in the array.
The function must return an Integer representing the length of the longest streak. A streak is defined as the number of days in the continuous sequence (for example, if temperatures are `[12.5, 13.0, 14.2, 11.0]`, the temperatures increase from 12.5 to 13.0, and 13.0 to 14.2, which is a streak of 3 days. A single day on its own has a streak of 1).
If the array has fewer than 1 element, the function should return 0.
Assume 1-based indexing for the array.
Write the pseudocode for the function `LongestRisingStreak`.
FOR Index <- 2 TO NumDays IF TempArray[Index] > TempArray[Index - 1] THEN CurrentStreak <- CurrentStreak + 1 ELSE IF CurrentStreak > MaxStreak THEN MaxStreak <- CurrentStreak ENDIF CurrentStreak <- 1 ENDIF NEXT Index
IF CurrentStreak > MaxStreak THEN MaxStreak <- CurrentStreak ENDIF
RETURN MaxStreak ENDFUNCTION
PastPaper.markingScheme
Total Marks: 10 - 1 mark: Correct function header with parameters (`TempArray` and `NumDays`) and return type (`INTEGER`). - 1 mark: Correctly handles empty / invalid array bounds (returning 0 if `NumDays <= 0`). - 1 mark: Initializes both `MaxStreak` and `CurrentStreak` to 1. - 1 mark: Correct loop structure starting from index 2 up to `NumDays`. - 2 marks: Correct conditional check comparing `TempArray[Index]` with `TempArray[Index - 1]`. - 1 mark: Correctly increments `CurrentStreak` when condition is met. - 1 mark: Correctly resets `CurrentStreak` to 1 when condition is not met. - 1 mark: Updates `MaxStreak` correctly when `CurrentStreak` exceeds it (handles reset transition). - 1 mark: Final comparison after the loop to capture a streak extending to the final element, and correct return statement.
A program contains a sorted 1D array of strings named `NameList` of size 100 (indexed 1 to 100).
Write a recursive pseudocode function `RecursiveSearch` that searches for a specific string target in the array.
The function takes three parameters: 1. `Target` : the String to find. 2. `Low` : the starting index of the search range (Integer). 3. `High` : the ending index of the search range (Integer).
The function must return the Integer index of the target string if found, or -1 if the target string is not in the array.
You may assume `NameList` is globally accessible and already declared and populated with sorted strings.
Write the pseudocode for the recursive function `RecursiveSearch`.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
FUNCTION RecursiveSearch(Target : STRING, Low : INTEGER, High : INTEGER) RETURNS INTEGER DECLARE Mid : INTEGER
IF Low > High THEN RETURN -1 ENDIF
Mid <- (Low + High) DIV 2
IF NameList[Mid] = Target THEN RETURN Mid ELSE IF NameList[Mid] > Target THEN RETURN RecursiveSearch(Target, Low, Mid - 1) ELSE RETURN RecursiveSearch(Target, Mid + 1, High) ENDIF ENDIF ENDFUNCTION
PastPaper.markingScheme
Total Marks: 10 - 1 mark: Correct function header with three parameters and return type `INTEGER`. - 2 marks: Correct recursive base case for not found condition (`Low > High` returning -1). - 2 marks: Correct calculation of middle element (`Mid <- (Low + High) DIV 2`). - 1 mark: Base case checking if `NameList[Mid]` equals `Target` and returning `Mid`. - 2 marks: Correct conditional block checking if mid element is greater than `Target` and recursively calling `RecursiveSearch` with updated high bound (`Mid - 1`). - 1 mark: Correct recursive call in the alternative branch with updated low bound (`Mid + 1`). - 1 mark: Returning the results of the recursive function calls.
A circular queue is implemented using a 1D array `QueueData` of size 10 (indexed 1 to 10). The following global pointers and variables are used: - `HeadPointer` : Integer pointing to the index of the first item in the queue. - `TailPointer` : Integer pointing to the index of the last item in the queue. - `NumItems` : Integer representing the current number of items in the queue. - `MaxItems` : Integer constant initialized to 10.
When the queue is empty, `NumItems` is 0, `HeadPointer` is 0, and `TailPointer` is 0.
Write a pseudocode procedure `Enqueue` that takes a string parameter `NewItem` and attempts to add it to the circular queue.
The procedure must: 1. Check if the queue is full. If it is full, display an appropriate error message and do not add the item. 2. If the queue is empty, update both pointers correctly to insert the first element. 3. If the queue is not empty and not full, update `TailPointer` correctly (handling circular wrap-around) and insert the item. 4. Increment `NumItems` accordingly.
Write the pseudocode for the procedure `Enqueue`.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
PROCEDURE Enqueue(NewItem : STRING) IF NumItems = MaxItems THEN OUTPUT "Error: Queue is full" ELSE IF NumItems = 0 THEN HeadPointer <- 1 TailPointer <- 1 ELSE IF TailPointer = MaxItems THEN TailPointer <- 1 ELSE TailPointer <- TailPointer + 1 ENDIF ENDIF QueueData[TailPointer] <- NewItem NumItems <- NumItems + 1 ENDIF ENDPROCEDURE
PastPaper.markingScheme
Total Marks: 10 - 1 mark: Correct procedure header taking a single parameter of String type. - 2 marks: Correct condition testing if queue is full (`NumItems = MaxItems` or equivalent logic) and outputting an error message. - 2 marks: Correct condition checking if queue is empty (`NumItems = 0`) and setting both pointers to 1. - 2 marks: Correct implementation of circular pointer wrapping logic for `TailPointer` (either by nested comparison or using modulo arithmetic). - 1 mark: Assigning `NewItem` to the correct array slot `QueueData[TailPointer]`. - 1 mark: Incrementing the `NumItems` count by 1. - 1 mark: Clean structure showing nested structures correctly closed (`ENDIF`, `ENDPROCEDURE`).
A software application stores employee data in a text file named `"Employees.txt"`. Each line of the file contains the record for one employee in comma-separated value (CSV) format: `EmployeeID,Department,Salary` (for example, `"1094,Finance,52000"`).
Write a pseudocode procedure `FilterDepartment` that takes a string parameter `DeptName`.
The procedure must: 1. Open the file `"Employees.txt"` for reading. 2. Create or overwrite a text file named `DeptName & ".txt"` (for example, if `DeptName` is `"Finance"`, the file created is `"Finance.txt"`) to store the filtered results. 3. Read `"Employees.txt"` line by line until the end of the file is reached. 4. Extract the individual fields (`EmployeeID`, `Department`, `Salary`) from each line. You may assume a pre-existing function `GetField(Line : STRING, FieldNum : INTEGER) RETURNS STRING` is available, which returns the specified field (1 for ID, 2 for Department, 3 for Salary) from a comma-separated string. 5. If the extracted department matches `DeptName` (case-sensitive), write a new line to the output file containing only the `EmployeeID` and `Salary` separated by a comma. 6. Close both files.
Use the standard Cambridge pseudocode file-handling operations: - `OPENFILE FOR READ` - `OPENFILE FOR WRITE` - `READFILE , ` - `WRITEFILE , ` - `CLOSEFILE ` - `EOF()`
Write the pseudocode for the procedure `FilterDepartment`.
Total Marks: 10 - 1 mark: Correct procedure declaration with standard header and parameter. - 1 mark: Correct construct of dynamic output filename by concatenating `DeptName` and `".txt"`. - 1 mark: Opening raw input file `"Employees.txt"` for reading using standard syntax. - 1 mark: Opening output file for writing using standard syntax. - 2 marks: Correct loop condition utilizing `WHILE NOT EOF("Employees.txt")` and reading lines correctly. - 1 mark: Correct call of helper function `GetField` to extract department value and matching check with parameter `DeptName`. - 1 mark: Retrieving `EmployeeID` and `Salary` fields using `GetField`. - 1 mark: Correct format concatenation when writing to output file (`EmpID & "," & EmpSalary`). - 1 mark: Properly closing both files at termination of search.
Run-length encoding (RLE) is a basic data compression technique where consecutive identical characters are recorded as a single character value and a count of its repetitions.
Write a pseudocode function `CompressString` that takes a single string parameter `InputStr` consisting only of uppercase letters (for example, `"AAAAABBBCCDA"`). The function must return the compressed version of the string where each consecutive run of a character is replaced by the number of occurrences followed immediately by that character (for example, `"5A3B2C1D1A"`).
If `InputStr` is empty, the function must return an empty string.
You can use the following standard string functions: - `LENGTH(s : STRING) RETURNS INTEGER` : returns the number of characters in string `s`. - `SUBSTR(s : STRING, start : INTEGER, length : INTEGER) RETURNS STRING` : returns a substring from `s` starting at position `start` (1-indexed) with the specified `length`. - `NUM_TO_STR(n : NUMERIC) RETURNS STRING` : converts a numeric value to its string representation.
Write the pseudocode for the function `CompressString`.
Total Marks: 10 - 1 mark: Correct function declaration and parameter matching return type `STRING`. - 1 mark: Guard clause verifying empty string and returning `""`. - 1 mark: Initializing output string variable to `""`, first char holder, and integer count tracking value to 1. - 2 marks: Loop starting at position 2 up to the total length of the string. - 2 marks: Correct conditional checks comparing substring index character to current stored tracking character. - 1 mark: Incrementing counter variable on identical sequential matches. - 1 mark: Appending serialized count and tracking character correctly to output string and resetting variables on new non-match sequences. - 1 mark: Appending final block run to output string outside / after loop and returning output.
PastPaper.question 6 · text
8.33 PastPaper.marks
A system is designed to manage library book returns. A modular program is planned using a Structure Chart.
The module `ProcessReturns` performs the following steps: 1. Calls `GetBookDetails` which prompts the user for the `BookID`. It returns `BookID` (String) and a boolean flag `IsValid`. 2. If the book is valid (determined by `IsValid`), it calls `CalculateFine` which takes `BookID` as an input parameter and returns a real value `FineAmount` and a boolean flag `IsOverdue`. 3. If the book is overdue (determined by `IsOverdue`), it calls `UpdateRecords` which takes `BookID` and `FineAmount` as parameters. 4. Finally, it calls `PrintReceipt` which takes `BookID` and `FineAmount` as parameters.
(a) Complete the following interface table for the parameters passed between modules. For each entry, specify the module calling, the module called, the parameter name, the data type, and the direction (In, Out, or Both).
(b) Describe how selection (conditional module execution) is represented visually in a Structure Chart.
(c) State the difference between a 'data couple' and a 'control couple' in a Structure Chart. Give an example of a control couple used in this library system.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
Q1 Solution Breakdown: (a) The student must identify the parameters passed, their data type, and direction: 1. GetBookDetails returns BookID (String) and IsValid (Boolean) to ProcessReturns, so direction is OUT. 2. CalculateFine receives BookID (String) (IN) and returns FineAmount (Real) (OUT) and IsOverdue (Boolean) (OUT). 3. UpdateRecords receives BookID (String) (IN) and FineAmount (Real) (IN). 4. PrintReceipt receives BookID (String) (IN) and FineAmount (Real) (IN).
(b) Explain that the diamond symbol is placed on the parent module's bottom edge or connection line. Branches to alternative child modules emerge from this single diamond.
(c) Explain the visual symbols (open circle vs. filled circle) and their conceptual differences (data value vs. system execution flag). Identify 'IsValid' or 'IsOverdue' as the system flag.
PastPaper.markingScheme
- Part (a): 4 Marks - 1 Mark: Correct GetBookDetails parameters, types (BookID: String, IsValid: Boolean) and direction (Out). - 1 Mark: Correct CalculateFine parameters, types (BookID: String, FineAmount: Real, IsOverdue: Boolean) and direction (In for BookID, Out for the rest). - 1 Mark: Correct UpdateRecords parameters, types (BookID: String, FineAmount: Real) and direction (In). - 1 Mark: Correct PrintReceipt parameters, types (BookID: String, FineAmount: Real) and direction (In). - Part (b): 2 Marks - 1 Mark: Identifies the use of a diamond symbol at the connection branching point. - 1 Mark: Explains that conditional module lines branch out from this diamond. - Part (c): 2 Marks - 1 Mark: Explains that data couples transfer data values (open circle arrow) whereas control couples transfer status/control flags (filled circle arrow). - 1 Mark: Correctly names either 'IsValid' or 'IsOverdue' as a control couple.
PastPaper.question 7 · text
8.33 PastPaper.marks
A programmer designs the following flowchart to count how many operations it takes to reduce a positive integer \( N \) to 1.
``` [Start] | V [Read N] | V [Count <- 0] | +--->+ | | | V | < N > 1 > ----(No)----> [Print Count] ---> [Stop] | | | (Yes) | | | V | < N MOD 2 = 0 > ---(Yes)---> [N <- N / 2] | | | | (No) | | | V | +-----------------------> [Count <- Count + 1] | | +----------------------------------+ ```
(a) Complete the trace table below for the input value \( N = 4 \).
| N | Count | N > 1 | N MOD 2 = 0 | |---|-------|-------|-------------| | | | | |
(b) Identify the critical logical error that occurs when an odd value of \( N \) (such as \( N = 5 \)) is processed, and explain why this error happens.
(c) Describe how the flowchart should be modified to resolve this issue, ensuring that odd numbers are decremented by 1 (to make them even) before dividing by 2 on the next loop iteration, while counting each decrement as an operation.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
Q2 Solution Breakdown: (a) Step-by-step trace: - Start: N=4, Count=0 - N > 1 (4 > 1) is True - 4 MOD 2 = 0 is True. N becomes 4/2 = 2. Count becomes 0 + 1 = 1. - N > 1 (2 > 1) is True - 2 MOD 2 = 0 is True. N becomes 2/2 = 1. Count becomes 1 + 1 = 2. - N > 1 (1 > 1) is False. Output is 2. Loop terminates.
(b) Analysis of odd values: if N=5, 5 > 1 is True. 5 MOD 2 = 0 is False. No assignment to N occurs. Count becomes 1. Loop repeats with N=5. Infinite execution loop occurs.
(c) Correction: By subtracting 1 from N on the 'No' route (e.g., N <- N - 1), we turn the odd number into an even number, which then successfully gets halved in subsequent iterations, preventing the infinite loop and correctly accounting for the step.
PastPaper.markingScheme
- Part (a): 3 Marks - 1 Mark: Correct first iteration row showing N updated to 2 and Count updated to 1. - 1 Mark: Correct second iteration row showing N updated to 1 and Count updated to 2. - 1 Mark: Correct termination showing N > 1 is False and final output is 2. - Part (b): 2 Marks - 1 Mark: States that an infinite loop / non-termination error occurs. - 1 Mark: Explains that because there is no operation on N along the 'No' path, the value of N never changes, so the loop condition 'N > 1' remains True forever. - Part (c): 3 Marks - 1 Mark: States to place a process/assignment box in the 'No' branch of the 'N MOD 2 = 0' decision block. - 1 Mark: Specifies the expression inside the process box as 'N <- N - 1'. - 1 Mark: Indicates that the flow must then lead to the 'Count <- Count + 1' block and then loop back, ensuring the subtraction is counted as an operation and the loop repeats.
PastPaper.question 8 · text
8.33 PastPaper.marks
A state transition diagram is used to design a compiler's lexical analyzer that validates variable names.
The rules for a valid variable name are: 1. It must start with a lowercase or uppercase letter (character class Letter). 2. It can be followed by any number of letters or digits (character class Digit). 3. It must end with a single underscore '_' character. 4. Any input containing characters outside these classes, or additional characters after the underscore, must transition to an error state SE.
The system has four states: - S0: Start State - S1: Variable Name Body (after first letter read) - S2: Terminal / Accept State (after valid underscore) - SE: Error State (invalid sequence/character)
(a) Complete the State Transition Table below by writing the next state for each combination of current state and input type.
| Current State | Input: Letter | Input: Digit | Input: Underscore | Input: Other | |---------------|---------------|--------------|-------------------|--------------| | S0 | | | | | | S1 | | | | | | S2 | | | | | | SE | | | | |
(b) Trace the state transitions for the following two inputs, starting from state S0. List each state transitioned through (e.g., S0 -> ...): 1. Input string: "x3_" 2. Input string: "7a_"
(c) Explain why this system is classified as a Deterministic Finite Automaton (DFA) / Finite State Machine (FSM).
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
Q3 Solution Breakdown: (a) Filling table: - In S0, only Letter leads to S1. Any other input is invalid at start, leading to SE. - In S1, any Letter or Digit keeps the state in S1. An Underscore completes the identifier, transitioning to S2. Other inputs go to SE. - In S2, the identifier is already complete; any further input is invalid, transitioning to SE. - In SE (Error state), any input keeps it in SE.
(b) Step-by-step tracing: - Input "x3_": - 'x' is a Letter: S0 -> S1 - '3' is a Digit: S1 -> S1 - '_' is an Underscore: S1 -> S2 (Ends in S2, which is the final/terminal accept state). - Input "7a_": - '7' is a Digit: S0 -> SE - 'a' is a Letter: SE -> SE - '_' is an Underscore: SE -> SE (Ends in SE, rejected).
(c) A State Machine has a finite set of states, a start state, an input alphabet, and transitions. It is Deterministic because there is no choice or non-deterministic choice for transitions (each input from a given state leads to exactly one state).
PastPaper.markingScheme
- Part (a): 4 Marks - 1 Mark: Correct S0 transition row (S1, SE, SE, SE). - 1 Mark: Correct S1 transition row (S1, S1, S2, SE). - 1 Mark: Correct S2 transition row (SE, SE, SE, SE). - 1 Mark: Correct SE transition row (SE, SE, SE, SE). - Part (b): 2 Marks - 1 Mark: Correct trace for "x3_": S0 -> S1 -> S1 -> S2, and indicates it is valid/accepted. - 1 Mark: Correct trace for "7a_": S0 -> SE -> SE -> SE, and indicates it is invalid/rejected. - Part (c): 2 Marks - 1 Mark: Explains "Finite State" (contains a limited/countable number of possible states, which is exactly 4 here). - 1 Mark: Explains "Deterministic" (for every input symbol and state, there is exactly one single destination state with no ambiguity).
Paper 32: Advanced Theory
Answer all complex database, Prolog and system architecture questions.
Explain, with reference to the facts and rules provided, how the logic interpreter uses backtracking and unification to resolve the query: `?- ancestor(arthur, diana).`
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
1. The query `?- ancestor(arthur, diana).` is entered. 2. The interpreter searches the database from top to bottom. It first attempts to unify the query with the head of the first rule: `ancestor(X, Y) :- parent(X, Y).` with `X = arthur` and `Y = diana`. 3. This creates the subgoal `parent(arthur, diana)`. The interpreter searches the facts, but no such fact exists. This subgoal fails. 4. The interpreter backtracks to the original goal and tries the next matching rule: `ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).` with `X = arthur` and `Y = diana`. 5. This creates two subgoals: `parent(arthur, Z)` and `ancestor(Z, diana)`. 6. The interpreter searches for a match for `parent(arthur, Z)`. It unifies with the fact `parent(arthur, bill)`, binding `Z = bill`. 7. The interpreter now evaluates the second subgoal with the bound variable: `ancestor(bill, diana)`. 8. This recursive call first tries the first rule of `ancestor`: `ancestor(bill, diana) :- parent(bill, diana)`. 9. The interpreter searches the facts for `parent(bill, diana)`. It finds a direct match in the database. 10. Since the subgoal `parent(bill, diana)` succeeds, the recursive call succeeds, which in turn satisfies the parent goal, and the query returns `true` (or `Yes`).
PastPaper.markingScheme
Max 6.8 marks: - 1 mark: Explaining the initial attempt to unify with the first ancestor rule and showing why it fails (parent(arthur, diana) does not exist). - 1 mark: Explaining backtracking to the second ancestor rule. - 1 mark: Explaining the binding of Z to 'bill' through unification with parent(arthur, Z). - 1 mark: Stating the formulation of the recursive subgoal ancestor(bill, diana). - 1 mark: Explaining the evaluation of the recursive subgoal using the first ancestor rule (parent(bill, diana)). - 1 mark: Identifying the direct match of parent(bill, diana) in the facts database. - 0.8 marks: Correct use of terminology (unification, backtracking, subgoals, binding) throughout the explanation.
In the context of database management systems (DBMS), describe the structural differences and operational roles of: (a) Entity Integrity vs. Referential Integrity. (b) Explain how the DBMS checks and maintains referential integrity when an instruction is executed to delete a record from a parent table that has corresponding records in a child table.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) - Entity integrity is a mechanism that requires every table to have a unique primary key, and this key cannot contain null values. This ensures that every row can be uniquely identified. - Referential integrity is a relationship-based rule asserting that a foreign key value in a child table must match a valid, existing primary key value in the parent table. This prevents orphaned records.
(b) When a deletion in the parent table is attempted: 1. The DBMS searches the child table's foreign key column for any values matching the primary key value of the record marked for deletion. 2. If no matches are found, the deletion proceeds normally. 3. If a match is found, the DBMS enforces one of the predefined referential integrity actions: - RESTRICT / REJECT: The DBMS blocks the deletion and returns an error to the user. - CASCADE: The DBMS automatically deletes all corresponding records in the child table along with the parent record. - SET NULL: The DBMS updates the matching foreign key fields in the child table to NULL while deleting the parent record (provided the foreign key column allows null values).
PastPaper.markingScheme
Max 6.8 marks: - 2 marks: Accurate contrast of Entity Integrity (must have unique PK, cannot be null) and Referential Integrity (FK must match a valid PK in parent table). - 1.8 marks: Clear step-by-step description of DBMS checking child tables for foreign key references before executing the delete. - 3 marks: Detailing the three possible integrity actions (1 mark for RESTRICT, 1 mark for CASCADE, 1 mark for SET NULL) and their direct operational impact.
Many modern development environments compile source code into intermediate code (such as Java bytecode or Common Intermediate Language) rather than native machine code.
(a) Explain two distinct benefits of using intermediate code. (b) Describe how a Virtual Machine (VM) utilizes this intermediate code to run the program on a specific target computer, and explain how Just-In-Time (JIT) compilation improves execution speed.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) 1. Portability: Code only needs to be compiled once into intermediate code. Any system with a compatible Virtual Machine installed can run the program without recompilation, regardless of the underlying processor architecture. 2. Code Optimization and Security: The intermediate code compiler can perform high-level optimizations. At runtime, the virtual machine can analyze/sandbox the intermediate code before execution to ensure it does not perform unauthorized actions.
(b) - The Virtual Machine acts as an abstraction layer. It reads the intermediate bytecode and translates it into the host machine's specific machine instructions using an interpreter. - Just-In-Time (JIT) compilation improves this process by compiling frequently executed blocks of bytecode (such as loops) into native machine code on-the-fly during execution. Subsequent calls to these blocks run directly on the hardware at native speed, bypassing the slow interpretation phase.
PastPaper.markingScheme
Max 6.8 marks: - 2 marks: Two well-explained benefits of intermediate code (1 mark for portability explanation, 1 mark for security/verification or compiler optimization explanation). - 2 marks: Clear explanation of how the VM acts as an interpreter (translating bytecode to host machine code at runtime). - 2.8 marks: Comprehensive explanation of JIT compilation (detecting 'hot' code blocks, translating to native machine code at runtime, caching/storing compiled code, and execution speed benefit).
Compare the imperative programming paradigm with the declarative programming paradigm.
(a) Describe how execution control and state management differ between the two paradigms. (b) Consider the list format `[Head | Tail]` in declarative programming (Prolog). Explain how recursion is used to process lists, and construct a logical rule `list_length(List, Length)` that recursively calculates the size of a list.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) - Imperative Paradigm: The programmer explicitly defines the step-by-step sequence of instructions that the computer must execute to change the program's state. It relies heavily on variables, assignments, and control loops (for, while). - Declarative Paradigm: The programmer defines the logic and relationships of the problem using facts and rules. The underlying inference engine (or interpreter) decides the execution path (e.g., using backtracking and pattern matching) to find a solution. There are no explicit state changes or loops.
(b) - In declarative programming, a list is recursively processed by matching the current list to the pattern `[Head | Tail]`. The head represents the first element, and the tail is the remaining list. - The base case specifies the length of an empty list `[]` as `0`. - The recursive rule matches a non-empty list, ignores the head element, recursively calls the predicate on the tail to find its length, and then adds 1 to that result to find the final length. - Prolog definition: `list_length([], 0).` `list_length([_ | Tail], Length) :- list_length(Tail, TailLen), Length is TailLen + 1.`
PastPaper.markingScheme
Max 6.8 marks: - 2 marks: Clear contrast of Imperative (step-by-step, states, variables, loops) and Declarative (facts, rules, relationships, implicit execution control). - 1.8 marks: Explanation of the recursive head/tail split and the need for a terminating base case. - 3 marks: Correct Prolog code / logic structure (1 mark for correct base case `list_length([], 0).`, 1 mark for correct recursive head/tail split `[_ | Tail]`, 1 mark for calculating the final length `Length is TailLen + 1`).
A relational database table is defined with the following schema to store details of training sessions: `TrainingSession(SessionID, TrainerID, TrainerName, VenueID, VenueAddress, Date)`
The following functional dependencies exist in the relation: - `SessionID -> TrainerID, VenueID, Date` - `TrainerID -> TrainerName` - `VenueID -> VenueAddress`
(a) Explain why this relation is not in Third Normal Form (3NF). (b) Normalize the schema into 3NF, clearly identifying the primary keys and foreign keys for each resulting table.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) - A relation is in 3NF if it is in 2NF and has no transitive functional dependencies (i.e., non-key attributes must depend only on the primary key, and not on other non-key attributes). - In the given relation, `SessionID` is the primary key. - `TrainerName` functionally depends on `TrainerID`, which is a non-key attribute. This is a transitive dependency (`SessionID -> TrainerID -> TrainerName`). - Similarly, `VenueAddress` functionally depends on `VenueID`, which is also a non-key attribute (`SessionID -> VenueID -> VenueAddress`). Therefore, it violates 3NF.
(b) To normalize the schema to 3NF, the transitive dependencies must be removed and placed in separate tables:
Max 6.8 marks: - 1 mark: Define the requirement for 3NF (must be in 2NF and contain no transitive dependencies). - 2.8 marks: Clearly identify the specific transitive dependencies in the schema (`TrainerID -> TrainerName` and `VenueID -> VenueAddress`). - 3 marks: Provide the normalized 3NF schema (1 mark for Trainer table with PK, 1 mark for Venue table with PK, 1 mark for TrainingSession table with primary and foreign keys correctly configured).
A virtual machine (VM) can provide hardware emulation or process-level isolation.
(a) Explain the difference between a Type 1 (bare-metal) hypervisor and a Type 2 (hosted) hypervisor. (b) Analyze the advantages and disadvantages of using a Virtual Machine to run legacy system software on modern computer hardware.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) - Type 1 (Bare-metal) Hypervisor: Runs directly on the physical host machine's hardware. It has direct access to the CPU, memory, and storage, making it highly efficient. Examples include VMware ESXi and Microsoft Hyper-V. - Type 2 (Hosted) Hypervisor: Runs as a software application layer on top of an existing host operating system. Hardware requests must pass through the host OS, resulting in higher execution overhead. Examples include VirtualBox and VMware Workstation.
(b) - Advantages: 1. Compatibility: It allows legacy software designed for obsolete hardware and operating systems to run on modern, high-performance physical computers without modifying the code. 2. Isolation & Security: The guest OS is completely sandboxed. If the legacy system crashes or is compromised, the host computer and other VM instances remain unaffected. - Disadvantages: 1. Performance Overhead: Because the VM must emulate hardware instructions, translation delays occur, making software run slower than on bare-metal systems. 2. Resource Allocation: Running a virtual machine consumes significant physical system resources (RAM, disk space, and CPU cores) to support both host and guest environments.
PastPaper.markingScheme
Max 6.8 marks: - 2.8 marks: Clear comparison of Type 1 (bare-metal, direct hardware access, higher efficiency) and Type 2 (hosted, runs on host OS, higher overhead) hypervisors. - 2 marks: Two well-explained advantages of using a VM for legacy software (e.g., compatibility, hardware independence, isolation/sandboxing). - 2 marks: Two well-explained disadvantages of using a VM (e.g., execution overhead, high resource consumption, emulation latency).
(a) Explain how dynamic binding operates and state how it supports the implementation of polymorphism. (b) Describe how the runtime environment utilizes a Virtual Method Table (VMT) to resolve polymorphic method calls during execution.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) - Dynamic binding (or late binding) is the mechanism where the decision of which specific method implementation to execute is deferred until runtime, based on the actual class of the object instantiated, rather than the static type declared at compile-time. - This supports polymorphism because a single interface or base class pointer can refer to objects of different subclasses. When an overridden method is invoked, dynamic binding ensures the subclass's specific implementation is executed.
(b) - For every class that defines or overrides virtual methods, the compiler creates a Virtual Method Table (VMT) containing an array of pointers to the actual machine code of those methods. - Each object of such a class contains a hidden pointer (usually at the start of the object's memory structure) referencing its class's VMT. - When a polymorphic method is called, the runtime environment does not call a hardcoded address. Instead, it looks up the object's VMT pointer, finds the method index (offset) corresponding to the method name, and jumps to the memory address stored at that index to execute the subclass's method.
PastPaper.markingScheme
Max 6.8 marks: - 2 marks: Clear explanation of dynamic binding (runtime resolution of method calls based on actual object type). - 1.8 marks: Explaining the link to polymorphism (allowing overridden methods in subclass hierarchies to be called correctly via base-class references). - 3 marks: Detailed step-by-step operation of the VMT (1 mark for defining the VMT as an array of method pointers, 1 mark for explaining the object's pointer to the VMT, 1 mark for describing the runtime lookup and resolution using offsets/indexes).
(a) Explain the purpose and operation of the anonymous variable `_` in both rules. (b) Walk through the step-by-step execution and search tree of the query: `?- member(green, [red, blue, green]).` Explicitly mention where unification succeeds or fails, and where recursion occurs.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) - The anonymous variable `_` is used as a wildcard placeholder when the actual value of a list element or variable is irrelevant to the rule's logic. - In the first rule `member(X, [X | _])`, it indicates that the tail of the list is ignored once the head matches `X`. - In the second rule `member(X, [_ | Tail])`, it indicates that the head element is discarded because it did not match `X`, allowing the algorithm to focus solely on checking the `Tail`. - Using `_` prevents compilation warnings about unused variables and improves execution efficiency.
(b) Trace of `?- member(green, [red, blue, green]).`: 1. **Call 1**: `member(green, [red, blue, green])` - Attempt to unify with Rule 1: `member(X, [X | _])`. Here, `X` must be `green`. The head of the list is `red`. Since `green` does not equal `red`, unification fails. - Move to Rule 2: `member(X, [_ | Tail])`. This unifies because the list has head `red` and tail `[blue, green]`. The interpreter sets `Tail = [blue, green]` and sets up the recursive subgoal: `member(green, [blue, green])`.
2. **Call 2**: `member(green, [blue, green])` - Attempt to unify with Rule 1: `X` is `green`, head of list is `blue`. Unification fails. - Move to Rule 2: The list has head `blue` and tail `[green]`. The interpreter sets `Tail = [green]` and recursively calls: `member(green, [green])`.
3. **Call 3**: `member(green, [green])` - Attempt to unify with Rule 1: `X` is `green`, head of list is `green`. Unification succeeds! - Since a base case/rule match has succeeded, the interpreter stops searching and returns `true` (or `Yes`).
PastPaper.markingScheme
Max 6.8 marks: - 2.8 marks: Explanation of the anonymous variable `_` (1.8 marks for stating it acts as a wildcard/placeholder for ignored values, 1 mark for identifying its specific roles in discarding the tail in Rule 1 and discarding the head in Rule 2). - 4 marks: Trace accuracy (1 mark for Call 1 showing failure of Rule 1 and instantiation of recursive call with tail `[blue, green]`, 1 mark for Call 2 showing failure of Rule 1 and instantiation of recursive call with tail `[green]`, 1 mark for Call 3 showing successful unification with Rule 1, 1 mark for correct identification of variable states and success declaration).
(a) State the goal/query that would find all courses that `lucas` is eligible to take, and describe how backtracking is used by the interpreter to resolve this query. [3.8 marks]
(b) Define a recursive rule `deep_prereq(X, Y)` that is true if course `Y` is a direct or indirect prerequisite of course `X`. [3 marks]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) The correct query is `can_take(lucas, Course).` Backtracking is the mechanism where the Prolog engine, upon finding a solution or encountering a failure, returns to the most recent choice point (where alternative clauses could have matched) to attempt to satisfy the subgoals using alternative bindings.
(b) The recursive rule must model the transitive prerequisite relationship: - Base case: `Y` is a direct prerequisite of `X` if `prereq(Y, X)` exists. - Recursive case: `Y` is an indirect prerequisite of `X` if there exists some intermediate course `Z` such that `Z` is a direct prerequisite of `X` (`prereq(Z, X)`) and `Y` is a direct/indirect prerequisite of `Z` (`deep_prereq(Z, Y)`).
PastPaper.markingScheme
(a) [Total: 3.8 marks] - Correct query: `can_take(lucas, Course).` (Accept any correct variable name) [1 mark] - Explanation that backtracking occurs when a subgoal fails or a new solution is sought, reversing to the previous decision point. [1 mark] - Describes the role of variable binding/unbinding during the search. [1 mark] - Explicitly points out that when checking `Course = 301`, the subgoal `completed(lucas, 201)` fails, which triggers backtracking to find alternative rules/facts. [0.8 marks]
(b) [Total: 3 marks] - Correct base case: `deep_prereq(X, Y) :- prereq(Y, X).` [1.5 marks] - Correct recursive case: `deep_prereq(X, Y) :- prereq(Z, X), deep_prereq(Z, Y).` (or logically equivalent variable order matching the base case) [1.5 marks]
An instruction pipeline has five stages: 1. Instruction Fetch (IF) 2. Instruction Decode (ID) 3. Operand Fetch (OF) 4. Instruction Execute (EX) 5. Write Back (WB)
(a) Explain how instruction pipelining improves processor performance and describe what is meant by a "pipeline hazard" (specifically a data hazard). [3.8 marks]
(b) Consider the following sequence of instructions: ```assembly ADD R1, R2, R3 ; R1 <- R2 + R3 SUB R4, R1, R5 ; R4 <- R1 - R5 ``` Explain the specific pipelining problem that occurs with this sequence of instructions and describe one software or hardware solution to resolve it. [3 marks]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) Pipelining divides instruction execution into discrete stages. Multiple instructions are processed simultaneously in different stages of the pipeline. While this does not reduce the latency (the time taken for a single instruction to complete), it significantly increases the instruction throughput of the CPU. A data hazard occurs because of data dependency; the pipeline must be stalled or modified because the operands required for an instruction are not yet available from a preceding instruction.
(b) In a standard 5-stage pipeline without forwarding: - Instruction 1 (ADD) writes to R1 during stage 5 (WB). - Instruction 2 (SUB) attempts to read R1 during stage 3 (OF). Because Instruction 2 is only 1 cycle behind Instruction 1, it will read the old (stale) value of R1. This is a classic RAW (Read-After-Write) hazard. Solutions include: - Hardware forwarding: routing the ALU output directly back to the ALU input. - Software compiler: inserting NOP (no-operation) instructions between ADD and SUB.
PastPaper.markingScheme
(a) [Total: 3.8 marks] - Explains overlapping stages / parallel processing of different instruction phases. [1 mark] - Identifies that pipelining increases instruction throughput (or reduces clock cycles per instruction). [1 mark] - Defines pipeline hazard as a condition that prevents the next instruction from executing immediately. [1 mark] - Defines data hazard as a conflict occurring when instructions depend on uncompleted read/write operations of prior instructions. [0.8 marks]
(b) [Total: 3 marks] - Identifies the RAW hazard / dependency on register R1. [1 mark] - Explains the temporal mismatch (SUB reads R1 at OF / Stage 3 before ADD writes R1 at WB / Stage 5). [1 mark] - Correctly describes one resolution: data forwarding/bypassing OR pipeline stalls/bubbles/NOP insertion. [1 mark]
In database transaction management, concurrency control is essential to ensure data integrity when multiple users access the database simultaneously.
(a) Explain what is meant by a "dirty read" (uncommitted dependency) in database transactions, and describe how the use of a lock can prevent this problem. [3.8 marks]
(b) Explain how the use of database locks can lead to a "deadlock", and describe one technique used by a Database Management System (DBMS) to resolve a deadlock. [3 marks]
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
(a) A dirty read (uncommitted dependency) violates the Isolation property of ACID. When transaction T1 updates a row and transaction T2 reads that row before T1 commits, T2 has performed a dirty read. If T1 rolls back, T2's data is invalid. This is resolved by locking (specifically shared/exclusive locks or two-phase locking protocols) where exclusive locks prevent any read/write operations by other transactions until commitment.
(b) Lock-based concurrency control can cause transactions to wait for locks to be released. If Transaction 1 holds Lock X and wants Lock Y, while Transaction 2 holds Lock Y and wants Lock X, they enter a deadlock state. The DBMS must resolve this by either detecting the cycle and aborting one transaction, or by preventing it (e.g., using lock ordering, or timestamp-based protocols like wound-wait / wait-die).
PastPaper.markingScheme
(a) [Total: 3.8 marks] - Definition of dirty read: reading data modified by another transaction that has not yet been committed. [1.5 marks] - Explanation of the issue with rollback: if the first transaction aborts/rolls back, the read data becomes invalid/non-existent. [0.8 marks] - Prevention explanation: Exclusive lock prevents other transactions from reading or writing the locked item until the lock is released (on commit/abort). [1.5 marks]
(b) [Total: 3 marks] - Explanation of deadlock: circular dependency where two or more transactions are blocked waiting for locks held by each other. [1.5 marks] - Description of resolution: e.g., Deadlock detection via wait-for graphs and aborting/rolling back a victim transaction; OR deadlock prevention via lock ordering/timestamps. [1.5 marks]
Paper 42: Practical
Solve practical requirements using Java, Python or Visual Basic. Capture execution screenshots.
3 PastPaper.question · 75 PastPaper.marks
PastPaper.question 1 · coding
25 PastPaper.marks
Create a new project in your chosen programming language (Python, Java, or Visual Basic). Save your source files.
You are implementing a computerized library management system. Write code to represent the resources held by the library.
1. Define a base class `Resource` with the following: - Private attributes: - `ResourceID` of type String - `Title` of type String - A constructor that accepts the resource ID and title as parameters. - Public getter methods `GetResourceID()` and `GetTitle()` that return their respective values. - An abstract or virtual method `CalculateFine(DaysOverdue : Integer)` which returns a real value representing the penalty fee.
2. Define a subclass `Book` that inherits from `Resource` and includes: - An additional private attribute `Author` of type String. - A constructor that accepts resource ID, title, and author. It must call the parent constructor with the appropriate arguments. - An overridden version of the method `CalculateFine(DaysOverdue : Integer)`. The fine is calculated as $0.50 per day overdue. Returns the fine as a real number.
3. Define a subclass `Journal` that inherits from `Resource` and includes: - An additional private attribute `IssueNumber` of type Integer. - A constructor that accepts resource ID, title, and issue number. It must call the parent constructor with the appropriate arguments. - An overridden version of the method `CalculateFine(DaysOverdue : Integer)`. The fine is calculated as a flat fee of $2.00, plus $1.00 for every day overdue. Returns the fine as a real number.
### Task 2: Main Program and Output Demonstration
Write main program code to perform the following operations:
1. Declare a 1D array or list named `ResourceList` containing 4 elements of type `Resource`. 2. Instantiate the following objects and store them in the array: - `Book` with ID: "B01", Title: "Algorithms", Author: "T. Cormen" - `Book` with ID: "B02", Title: "Computer Networks", Author: "A. Tanenbaum" - `Journal` with ID: "J01", Title: "IEEE Software", Issue Number: 42 - `Journal` with ID: "J02", Title: "ACM Transactions", Issue Number: 109 3. Write a procedure `DisplayFines(Days : Integer)` which: - Iterates through each object in `ResourceList`. - Outputs the `ResourceID`, the `Title`, and the calculated fine for that resource given the number of days overdue. Format the fine to 2 decimal places. 4. From the main program, call `DisplayFines` passing `5` as the parameter.
Take a screenshot of the main program's output showing the calculated fines.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
```python from abc import ABC, abstractmethod
# Base Class class Resource(ABC): def __init__(self, resource_id: str, title: str): self.__resource_id = resource_id self.__title = title
def display_fines(days: int): print(f"Fines for {days} days overdue:") for res in resource_list: fine = res.calculate_fine(days) print(f"ID: {res.get_resource_id()} | Title: {res.get_title()} | Fine: ${fine:.2f}")
# Run code display_fines(5) ```
PastPaper.markingScheme
### Mark Breakdown:
**Class `Resource` implementation:** [Total: 5 marks] * **1 Mark:** Attributes `ResourceID` and `Title` declared as private. * **1 Mark:** Constructor implemented correctly accepting ID and Title as parameters. * **1 Mark:** `GetResourceID()` public getter returns correct value. * **1 Mark:** `GetTitle()` public getter returns correct value. * **1 Mark:** `CalculateFine()` declared as abstract/virtual method.
**Class `Book` implementation:** [Total: 5 marks] * **1 Mark:** Subclass `Book` inherits from `Resource`. * **1 Mark:** Private attribute `Author` declared. * **1 Mark:** Constructor accepts all arguments and calls `super()` with ID and Title, and assigns `Author`. * **2 Marks:** Overridden `CalculateFine()` calculates and returns correct fine: \(DaysOverdue \times 0.50\).
**Class `Journal` implementation:** [Total: 5 marks] * **1 Mark:** Subclass `Journal` inherits from `Resource`. * **1 Mark:** Private attribute `IssueNumber` declared. * **1 Mark:** Constructor accepts all arguments and calls parent constructor, and assigns `IssueNumber`. * **2 Marks:** Overridden `CalculateFine()` calculates and returns correct fine: \(2.00 + DaysOverdue \times 1.00\).
**Main Program & Demonstration:** [Total: 7 marks] * **1 Mark:** Main program declares `ResourceList` container of size 4. * **2 Marks:** Code correctly instantiates 2 Books and 2 Journals with specified details and adds them to `ResourceList`. * **3 Marks:** Procedure `DisplayFines(Days)` correctly loops through list, retrieves data via getters, calls the polymorphic method `CalculateFine`, and prints them. * **1 Mark:** Procedure called from main with parameter `5`.
Create a new project in your chosen programming language (Python, Java, or Visual Basic). Save your source files.
### Task 1: Node Representation of Binary Search Tree
You need to implement a Binary Search Tree (BST) using a static array of nodes to store string values.
1. Define a class `Node` with the following private attributes: - `Data` of type String - `LeftPointer` of type Integer - `RightPointer` of type Integer It must have: - A constructor that accepts a String parameter to initialize `Data`. `LeftPointer` and `RightPointer` must be initialized to -1. - Public getter and setter methods for all three attributes: `GetData()`, `SetData()`, `GetLeft()`, `SetLeft()`, `GetRight()`, `SetRight()`.
2. Define a class `BinaryTree` with the following private attributes: - `Tree` as an array of 10 `Node` elements - `RootPointer` of type Integer - `FreePointer` of type Integer
The constructor of `BinaryTree` must: - Initialize `RootPointer` to -1. - Initialize `FreePointer` to 0. - Instantiate all 10 nodes in the array with empty data `""`. - Programmatically set the `LeftPointer` of each node to link to the index of the next node (index 0 links to 1, index 1 to 2, ..., index 8 to 9, and index 9 to -1). This forms the free list structure. (The `RightPointer` of each node should remain -1).
3. Write a public method `Insert(NewData : String)` inside `BinaryTree` which: - Checks if there are no free nodes (i.e., `FreePointer` is -1). If so, prints "Tree is full" and returns False. - Retrieves the node at index `FreePointer` to store `NewData`. - Updates `FreePointer` to point to the `LeftPointer` of the node being used. - Initializes the used node's `LeftPointer` and `RightPointer` to -1. - If `RootPointer` is -1, set `RootPointer` to this node index and return True. - Otherwise, traversers the tree iteratively from `RootPointer` to find the correct insertion position based on standard BST behavior (if `NewData` < current node's data, go left; else go right) and links the parent node to this node index. Returns True.
4. Write a recursive helper method `InOrderTraversal(NodePointer : Integer)` that performs an in-order print of the elements. 5. Write a public method `PrintAll()` which starts the recursive `InOrderTraversal` from `RootPointer`.
### Task 2: Main Program and Output Demonstration
Write main program code to perform the following: 1. Instantiate a `BinaryTree` object. 2. Insert the following 6 values in this precise order: "Mango", "Apple", "Peach", "Banana", "Cherry", "Plum". 3. Call `PrintAll()` to print the contents of the tree.
Take a screenshot of the main program's output showing the items sorted alphabetically.
PastPaper.showAnswersPastPaper.hideAnswers
PastPaper.workedSolution
```python class Node: def __init__(self, data: str): self.__data = data self.__left_pointer = -1 self.__right_pointer = -1
class BinaryTree: def __init__(self): self.__tree = [Node("") for _ in range(10)] self.__root_pointer = -1 self.__free_pointer = 0 # Initialize free list for i in range(9): self.__tree[i].set_left(i + 1) self.__tree[9].set_left(-1)
def insert(self, new_data: str) -> bool: if self.__free_pointer == -1: print("Tree is full") return False
# Set data and clear pointers self.__tree[new_node_index].set_data(new_data) self.__tree[new_node_index].set_left(-1) self.__tree[new_node_index].set_right(-1)
if self.__root_pointer == -1: self.__root_pointer = new_node_index return True else: current = self.__root_pointer while True: if new_data < self.__tree[current].get_data(): if self.__tree[current].get_left() == -1: self.__tree[current].set_left(new_node_index) return True else: current = self.__tree[current].get_left() else: if self.__tree[current].get_right() == -1: self.__tree[current].set_right(new_node_index) return True else: current = self.__tree[current].get_right()
def print_all(self): if self.__root_pointer == -1: print("Tree is empty") else: self.in_order_traversal(self.__root_pointer)
# Main tree = BinaryTree() items = ["Mango", "Apple", "Peach", "Banana", "Cherry", "Plum"] for item in items: tree.insert(item) tree.print_all() ```
PastPaper.markingScheme
### Mark Breakdown:
**Class `Node` implementation:** [Total: 4 marks] * **1 Mark:** Attributes `Data`, `LeftPointer`, `RightPointer` are encapsulated as private. * **1 Mark:** Constructor sets pointers to -1, data to parameter. * **2 Marks:** Getters and setters for data, left, and right pointers work correctly.
**Class `BinaryTree` constructor:** [Total: 5 marks] * **1 Mark:** `Tree` declared with 10 Node objects. * **1 Mark:** `RootPointer` and `FreePointer` initialized correctly (-1 and 0). * **3 Marks:** Loop properly initializes the static array's left pointers to form a free list (0 to 1, ..., 9 to -1).
**Method `Insert`:** [Total: 8 marks] * **1 Mark:** Check if `FreePointer == -1` and return False. * **2 Marks:** Correctly pop/retrieve next free index and advance `FreePointer` to `LeftPointer` of the node. * **1 Mark:** Store `NewData` and set left/right children of new node to -1. * **1 Mark:** Correctly handle empty tree case when `RootPointer == -1`. * **3 Marks:** Iterative while/recursion loops, correctly branching left/right depending on lexicographical value comparison and assigning child index to the parent.
**Main & Evidence:** [Total: 4 marks] * **2 Marks:** Correctly instantiating tree and sequential insertion of the 6 items. * **2 Marks:** Console screenshot showing alphabetical traversal output: Apple, Banana, Cherry, Mango, Peach, Plum.
PastPaper.question 3 · coding
25 PastPaper.marks
Create a new project in your chosen programming language (Python, Java, or Visual Basic). Save your source files.
### Task 1: Stack Abstract Data Type (ADT) with Search
You need to implement a static array-based stack class named `CargoStack` with custom recursive search properties.
1. Define a class `CargoStack` with the following private attributes: - `StackData` : an array of 8 String elements - `TopPointer` : Integer representing the top index of the stack.
2. Write a constructor that: - Initializes `TopPointer` to -1. - Initializes all elements of the `StackData` array to empty strings `""`.
3. Write the following public methods inside `CargoStack`: - `Push(Item : String)` which returns a Boolean: - If the stack is full (holds 8 elements), returns False. - Otherwise, increments `TopPointer`, saves `Item` to that position in the array, and returns True. - `Pop()` which returns a String: - If the stack is empty, returns an empty string `""`. - Otherwise, retrieves the string at `TopPointer`, replaces that stack slot with an empty string `""`, decrements `TopPointer`, and returns the retrieved string. - `RecursiveSearch(Item : String, CurrentIndex : Integer)` which returns an Integer: - A recursive search method that checks for `Item` starting from `CurrentIndex` (initially called with `TopPointer`) going down to index 0. - If `CurrentIndex < 0`, it means the item was not found; return -1. - If the element in `StackData[CurrentIndex]` matches `Item`, return `CurrentIndex`. - Otherwise, return the result of recursively calling `RecursiveSearch` with the same `Item` and `CurrentIndex - 1`.
### Task 2: Demonstration and Output Capture
Write main program code to perform the following operations in sequence:
1. Create an instance of `CargoStack`. 2. Attempt to push the following strings sequentially into the stack: "Cargo_A", "Cargo_B", "Cargo_C", "Cargo_D", "Cargo_E", "Cargo_F". Print the returned boolean value for each push attempt to confirm success. 3. Perform a recursive search for "Cargo_C" starting from the current `TopPointer`. Print whether it was found and its array index. 4. Perform a recursive search for "Cargo_Z" starting from the current `TopPointer`. Print whether it was found. 5. Call `Pop()` three times, printing the popped values. 6. Search for "Cargo_E" again after the pop operations. Print whether it is still found.
Take a screenshot of your main program's terminal output.
# Main Program Execution if __name__ == "__main__": stack = CargoStack() items = ["Cargo_A", "Cargo_B", "Cargo_C", "Cargo_D", "Cargo_E", "Cargo_F"]
print("--- Pushing Elements ---") for it in items: success = stack.push(it) print(f"Pushing {it}: Success = {success}")
top = stack.get_top_pointer() print(" --- Searching Elements ---") idx_c = stack.recursive_search("Cargo_C", top) print(f"Searching 'Cargo_C': Found at index {idx_c}")
idx_z = stack.recursive_search("Cargo_Z", top) print(f"Searching 'Cargo_Z': Found at index {idx_z} (-1 means not found)")
print(" --- Popping 3 Elements ---") for _ in range(3): print(f"Popped: {stack.pop()}")
top_after = stack.get_top_pointer() print(" --- Re-searching Element ---") idx_e = stack.recursive_search("Cargo_E", top_after) print(f"Searching 'Cargo_E': Found at index {idx_e} (-1 means not found)") ```
PastPaper.markingScheme
### Mark Breakdown:
**Class `CargoStack` attributes and constructor:** [Total: 3 marks] * **1 Mark:** `StackData` declared as private array of 8 strings. * **1 Mark:** `TopPointer` declared as integer. * **1 Mark:** Constructor initializes array elements with `""` and sets `TopPointer` to -1.
**Method `Push` implementation:** [Total: 3 marks] * **1 Mark:** Checks if stack is full (`TopPointer == 7`) and handles bounds appropriately. * **1 Mark:** Increments `TopPointer` and writes `Item` into array index. * **1 Mark:** Returns Boolean showing completion status.
**Method `Pop` implementation:** [Total: 3 marks] * **1 Mark:** Checks if stack is empty (`TopPointer == -1`) and returns empty string. * **1 Mark:** Extracts element, clears index array cell to `""`. * **1 Mark:** Correctly decrements `TopPointer` and returns correct string.
**Method `RecursiveSearch` implementation:** [Total: 6 marks] * **1 Mark:** Correct function signature accepting String and index integer. * **1 Mark:** Base case recursive check for index < 0 (not found) returning -1. * **2 Marks:** Base case matching element at current index returning index. * **2 Marks:** Recursively calling itself decrementing index parameter by 1 and propagating returned value.
**Main Program & Simulation Run:** [Total: 7 marks] * **2 Marks:** Correct instantiation and sequential pushing of 6 elements with printed feedback. * **1 Mark:** Searching for "Cargo_C" from top of stack and displaying returned index (index 2). * **1 Mark:** Searching for "Cargo_Z" and outputting that it was not found. * **2 Marks:** Popping 3 items from stack and printing results (F, E, then D). * **1 Mark:** Re-searching for "Cargo_E" and reporting not found (since it was popped).
**Screenshot Evidence:** [Total: 3 marks] * **3 Marks:** Output screenshot showing accurate results matching all simulation steps.