Often we want to store data related to a particular entity as a single object - for example, rather than creating separate variables for a person's name, date of birth, gender, hobbies etc, we could store them all as a single record
While individual records are good, arrays of records are often even more useful - e.g. creating an array of a custom Person record that we created
Paper 2 theory questions often ask about the benefit of records - you can say:
- Keeps code organised/easier to understand/makes properties easy to access, since they're stored as a single object
- More flexible - can easily add/remove properties
If talking about arrays of records, as well as the above points, you can also say:
- Easier to add/remove instances by changing the array size - typing out creating 10 variables like Person1Name, Person2Name etc is very tedious
- Can loop through all records - e.g. to populate with them values from a file, search, sort them etc. You can't do this with individual variables
- Less code duplication - since we can access elements based on their index/in a loop, rather than having to have different statements for each item if using individual variables
Let's see some examples
1
Record Syntax
Records are defined with the TYPE keyword, followed by the record name, a list of declarations and finally the ENDTYPE keyword
In the example below, we will define a custom Person record with 4 fields/properties/attributes
We then need to declare an instance of the Person record which we call walter
To access individual fields, we use the dot e.g. walter.name
TYPE Person
DECLARE name : STRING
DECLARE dob : DATE
DECLARE isAlive : BOOLEAN
DECLARE hobbies : ARRAY[1:2] OF STRING
DECLARE icon : CHAR
ENDTYPE
DECLARE walter : Person
walter.name β "Walter White"
walter.dob β 07/09/1958
walter.isAlive β FALSE
walter.hobbies[1] β "Chemistry"
walter.hobbies[2] β "Business"
walter.icon β 'π§βπ¬'
OUTPUT walter.icon, " ", walter.name, " was born on ", walter.dob, " - they enjoy ", walter.hobbies[1], " and ", walter.hobbies[2], ". They are ", getLivingWord(walter.isAlive), "."
FUNCTION getLivingWord(isAlive : BOOLEAN) RETURNS STRING
IF isAlive = TRUE THEN
RETURN "alive"
ELSE
RETURN "dead"
ENDIF
ENDFUNCTION
2
People
Use the Person example above to create an array of 3 people and assign relevant values to each of the fields - you should then create a procedure to output all of the people's details
CONSTANT NUM_PEOPLE = 3
TYPE Person
DECLARE name : STRING
DECLARE dob : DATE
DECLARE isAlive : BOOLEAN
DECLARE hobbies : ARRAY[1:2] OF STRING
DECLARE icon : CHAR
ENDTYPE
DECLARE people : ARRAY[1:NUM_PEOPLE] OF Person
people[1].name β "Walter White"
people[1].dob β 07/09/1958
people[1].isAlive β FALSE
people[1].hobbies[1] β "Chemistry"
people[1].hobbies[2] β "Business"
people[1].icon β 'π§βπ¬'
people[2].name β "Sherlock Holmes"
people[2].dob β 01/06/1854
people[2].isAlive β FALSE
people[2].hobbies[1] β "Boxing"
people[2].hobbies[2] β "Violin"
people[2].icon β 'π΅οΈββοΈ'
people[3].name β "Tom Riddle"
people[3].dob β 31/12/1936
people[3].isAlive β FALSE
people[3].hobbies[1] β "Snakes"
people[3].hobbies[2] β "Artifacts"
people[3].icon β 'π§ββοΈ'
CALL OutputPeople()
PROCEDURE OutputPeople()
DECLARE index : INTEGER
FOR index β 1 TO 3
OUTPUT people[index].icon, " ", people[index].name, " was born on ", people[index].dob, " - they enjoy ", people[index].hobbies[1], " and ", people[index].hobbies[2], ". They are ", getLivingWord(people[index].isAlive), "."
NEXT index
ENDPROCEDURE
FUNCTION getLivingWord(isAlive : BOOLEAN) RETURNS STRING
IF isAlive = TRUE THEN
RETURN "alive"
ELSE
RETURN "dead"
ENDIF
ENDFUNCTION
3
Flight Booking
Create a program that can store the following information about 3 flights:
- Airline
- Departure city
- Destination city
- Date
- Price
- Number of seats available
You can either pre-populate the records, or have the user input them as the program runs
The main functionality is that the user should be able to specify the departure city, destination city, date and number of tickets they would like to buy - if a suitable flight is available, they should be notified of their successful booking, otherwise a relevant error message should be displayed
There should be some way of allowing the user to continue buying tickets, until they choose to quit
CONSTANT NUM_FLIGHTS = 3
TYPE Flight
DECLARE airline, departureCity, destinationCity : STRING
DECLARE flightDate : DATE
DECLARE seatsRemaining : INTEGER
DECLARE price : REAL
ENDTYPE
DECLARE flights : ARRAY[1:NUM_FLIGHTS] OF Flight
DECLARE departureCityChoice, destinationCityChoice : STRING
DECLARE flightDateChoice : DATE
DECLARE menuChoice : CHAR
DECLARE flightIndex, ticketNumChoice : INTEGER
DECLARE foundFlight : BOOLEAN
flights[1].airline β "Latam"
flights[1].departureCity β "Buenos Aires"
flights[1].destinationCity β "Sao Paolo"
flights[1].flightDate β 15/04/2025
flights[1].seatsRemaining β 3
flights[1].price β 150
flights[2].airline β "British Airways"
flights[2].departureCity β "Sydney"
flights[2].destinationCity β "London"
flights[2].flightDate β 22/06/2025
flights[2].seatsRemaining β 75
flights[2].price β 1000
flights[3].airline β "NASA"
flights[3].departureCity β "Earth"
flights[3].destinationCity β "Mars"
flights[3].flightDate β 01/01/2040
flights[3].seatsRemaining β 1
flights[3].price β 0
REPEAT
OUTPUT "Where would you like to depart from:"
INPUT departureCityChoice
OUTPUT "Where would you like to fly to:"
INPUT destinationCityChoice
OUTPUT "What date would you like to fly:"
INPUT flightDateChoice
OUTPUT "How many tickets would you like:"
INPUT ticketNumChoice
flightIndex β 0
foundFlight β FALSE
WHILE foundFlight = FALSE AND flightIndex < NUM_FLIGHTS DO
flightIndex β flightIndex + 1
IF departureCityChoice = flights[flightIndex].departureCity AND
destinationCityChoice = flights[flightIndex].destinationCity AND
flightDateChoice = flights[flightIndex].flightDate THEN
foundFlight β TRUE
ENDIF
ENDWHILE
IF foundFlight = TRUE THEN
IF ticketNumChoice <= flights[flightIndex].seatsRemaining THEN
OUTPUT "Purchased ", ticketNumChoice, " tickets for ", flights[flightIndex].airline, " flight from ", flights[flightIndex].departureCity, " to ", flights[flightIndex].destinationCity, " on ", flights[flightIndex].flightDate, " for πͺ", (flights[flightIndex].price * ticketNumChoice)
ELSE
OUTPUT "Couldn't book ", ticketNumChoice, " tickets - only ", flights[flightIndex].seatsRemaining, " seats available"
ENDIF
ELSE
OUTPUT "No flight for this route on that date is available"
ENDIF
OUTPUT "Would you like to book another flight? (y/n)"
INPUT menuChoice
UNTIL LCASE(menuChoice) = 'n'
OUTPUT "Have a safe flight!"
4
Football Clubs
Use the 20 Premier League FootballClubs.txt file - note that club details are grouped together in the form:
- Team name
- Year founded
- Stadium name
- Stadium capacity
- Yearly wage bill (GBP)
- Team captain
Create a program to read all the clubs into an array of records, then provide the user with a menu and implement the functionality to:
- Output club details
- Find club with a given captain
- Output all clubs founded in the 1800s
- Order the clubs in descending order of stadium capacity
- Show wage stats (min, max, average, total and range of yearly wages)
- Quit
TYPE FootballClub
DECLARE name, stadium, captain : STRING
DECLARE founded, capacity, wageBill : INTEGER
ENDTYPE
CONSTANT NUM_CLUBS = 20
DECLARE clubs : ARRAY[1:NUM_CLUBS] OF FootballClub
DECLARE line : STRING
DECLARE index, menuChoice : INTEGER
OPENFILE FootballClubs.txt FOR READ
WHILE NOT EOF(FootballClubs.txt) DO
index β index + 1
READFILE FootballClubs.txt, clubs[index].name
READFILE FootballClubs.txt, line
clubs[index].founded β STR_TO_NUM(line)
READFILE FootballClubs.txt, clubs[index].stadium
READFILE FootballClubs.txt, line
clubs[index].capacity β STR_TO_NUM(line)
READFILE FootballClubs.txt, line
clubs[index].wageBill β STR_TO_NUM(line)
READFILE FootballClubs.txt, clubs[index].captain
READFILE FootballClubs.txt, line
ENDWHILE
CLOSEFILE FootballClubs.txt
REPEAT
//
Output club details
// Find club with a given captain
// Output all clubs founded in the 1800s
// Order the clubs in descending order of stadium capacity
// Quit
OUTPUT "--- Menu ---
1) Output club details
2) Search club by captain
3) Show 1800s clubs
4) Order by stadium capacity
5) Show wage stats
6) Quit
Please choose an option:"
INPUT menuChoice
CASE OF menuChoice
1: CALL OutputAllClubs()
2: CALL SearchClubByCaptain()
3: CALL Show1800sClubs()
4: CALL OrderByStadiumCapacity()
5: CALL ShowWageStats()
ENDCASE
UNTIL menuChoice = 6
OUTPUT "Goodbye..."
PROCEDURE OutputAllClubs()
DECLARE n : INTEGER
FOR n β 1 TO NUM_CLUBS
OUTPUT n
CALL OutputClub(clubs[n])
OUTPUT ""
NEXT n
ENDPROCEDURE
PROCEDURE OutputClub(c : FootballClub)
OUTPUT c.name, " was founded in ", c.founded, " plays at the ", c.stadium, " with a capacity of ", c.capacity, ". Their yearly wage bill is Β£", c.wageBill, " and their captain is ", c.captain
ENDPROCEDURE
PROCEDURE SearchClubByCaptain()
DECLARE n : INTEGER
DECLARE found : BOOLEAN
DECLARE captain : STRING
found β FALSE
n β 1
OUTPUT "Enter captain to search for:"
INPUT captain
WHILE found = FALSE AND n <= NUM_CLUBS
IF clubs[n].captain = captain THEN
CALL OutputClub(clubs[n])
found β TRUE
ENDIF
n β n + 1
ENDWHILE
IF found = FALSE THEN
OUTPUT "No club with captain named ", captain
ENDIF
ENDPROCEDURE
PROCEDURE Show1800sClubs()
DECLARE n : INTEGER
FOR n β 1 TO NUM_CLUBS
IF clubs[n].founded < 1900 THEN
CALL OutputClub(clubs[n])
OUTPUT ""
ENDIF
NEXT n
ENDPROCEDURE
PROCEDURE OrderByStadiumCapacity()
DECLARE isSorted : BOOLEAN
DECLARE endIndex, n : INTEGER
isSorted β FALSE
endIndex β NUM_CLUBS - 1
WHILE isSorted = FALSE DO
isSorted β TRUE
FOR n β 1 TO endIndex
IF clubs[n].capacity < clubs[n + 1].capacity THEN
DECLARE tempClub : FootballClub
tempClub β clubs[n]
clubs[n] β clubs[n + 1]
clubs[n + 1] β tempClub
isSorted β FALSE
ENDIF
NEXT n
endIndex β endIndex - 1
ENDWHILE
FOR n β 1 TO NUM_CLUBS
CALL OutputClub(clubs[n])
OUTPUT ""
NEXT n
ENDPROCEDURE
PROCEDURE ShowWageStats()
DECLARE n, min, max, total : INTEGER
min β clubs[1].wageBill
max β clubs[1].wageBill
total β 0
FOR n β 1 TO NUM_CLUBS
IF clubs[n].wageBill < min THEN
min β clubs[n].wageBill
ENDIF
IF clubs[n].wageBill > max THEN
max β clubs[n].wageBill
ENDIF
total β total + clubs[n].wageBill
NEXT n
OUTPUT "--- Yearly Wage Stats ---"
OUTPUT "Min: ", min
OUTPUT "Max: ", max
OUTPUT "Total: ", total
OUTPUT "Average: ", total / NUM_CLUBS
OUTPUT "Range: ", max - min
ENDPROCEDURE