Tutorial 13

🔢

ENUMS

9618 A-Level


Another user-defined data type you will need to know about for both AS and A2 are ENUMs - or enumerated data types

ENUMs are a whitelist of labels representing a numeric value

You should look at the examples below to understand what enums are first, but in paper 2, it might be asked what the advantage of using ENUMs are - you could say:

  • Forces consistent format - e.g. if storing strings, one user might enter "Computer Science", another might enter "computerscience", another might "CS", another "IT" etc - all of those would be considered different. Enums enforce a whitelist of allowed values, so this issue of different strings is avoided
  • Allows comparison operations - e.g. storing priorities, days, months etc - not only can we compare whether two values are equal or not (like with strings), we can also compare which is greater/less than etc
  • Allow arithmetic operations - e.g. calculating the difference between two enums, which is something we can't do if using strings
  • Readability - using labels to represent integers is easier to understand than only using integers - e.g. Subject.CS, Subject.Maths, Subject.Physics is easier to read/remember/less prone to errors to hard-coding integers like 4, 7 and 2 representing each subject respectively
  • Easier to modify (refactor) - simply update the enum label and many IDEs (or use a find & replace) will update all occurances. Updating hard-coded integers is much harder
  • Uses less memory (generally) - the compiler/interpreter would convert an enum to a single integer, which will use less memory than storing longer strings

The list above is non-exhaustive, but should all be accepted in mark schemes - writing they use less memory would probably be less recommended, since Cambridge focuses more on concepts like readibility, ease of updating (refactoring), rather than hyperoptimisations, which aren't required at AS or A-Level

It's also worth-noting that enums are supported by many DBMSs for the reasons above - MySQL for example supports enums and includes an example of representing different shirt sizes as enums in their official documentation. Representing countries as enums is another common situation you might encounter

1

ENUM Syntax

Below, we can see we have defined an enum named MonthEnum via the TYPE keyword, followed by an equals sign and a whitelist of allowed values in brackets

The ENUM Jan would correspond to 1, while Dec would correspond to 12

In the new pseudocode guide, we don't need to use the enum name followed by a dot, then the specific enum value (e.g. MonthEnum.Jan) like we do for records - we can simply write the instance Jan directly - the site and examiners should support both the shorter and longer, more explicit syntax

We can also declare instances of enums the way we would other data types - see the SiteBirthday declaration below to create an instance of our custom MonthEnum - since it's a variable, we can re-assign a new value to it, perform arithmetic etc

As stated, since enums are ultimately an integer with a text label representation, we can use conditional operators (=, >, <, >=, <=, <> - see the nested IFs below) and arithmetic operators (+, -, *, /, ^ or **, MOD, DIV - see the calculations below calculating the difference between the CurrentMonth and the SiteBirthday) on them

TYPE MonthEnum = (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) OUTPUT "January is month number ", Jan OUTPUT "December is month number ", MonthEnum.Dec DECLARE SiteBirthday : MonthEnum DECLARE CurrentMonth : INTEGER SiteBirthday ← May CurrentMonth ← MONTH(TODAY()) OUTPUT "The current month is number: ", CurrentMonth IF SiteBirthday = CurrentMonth THEN OUTPUT "The site's birthday is this month!" ELSE IF SiteBirthday > CurrentMonth THEN OUTPUT "The site's birthday is in ", (SiteBirthday - CurrentMonth), " month(s)" ELSE OUTPUT "The site's birthday was ", (CurrentMonth - SiteBirthday), " month(s) ago" ENDIF ENDIF

2

Outputting Enum Label

Note: this is not included in the syllabus, but a few people have asked for a way to output the enum's name - just like we have NUM_TO_STR, I have also added the additional ENUM_TO_STR function that is available if the syllabus mode in the toolbar at the bottom of the page is set to "All Syllabuses & Extra Modules"

TYPE MonthEnum = (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) DECLARE Index : INTEGER DECLARE IndexMonth : MonthEnum FOR Index ← 1 TO 12 IndexMonth ← Index OUTPUT ENUM_TO_STR(IndexMonth), " is month ", Index NEXT Index

3

Enum Arithmetic

We have seen some examples of enum arithmetic in the first example - let's look at a few more

TYPE MonthEnum = (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) DECLARE CurrentMonth, PrevMonth, NextMonth : MonthEnum CurrentMonth ← Mar OUTPUT CurrentMonth CurrentMonth ← CurrentMonth * 4 OUTPUT CurrentMonth OUTPUT "The following line will cause an error - there is no enum corresponding to month 13! You can remove it - it's just included for demonstration" CurrentMonth ← CurrentMonth + 1 CurrentMonth ← (CurrentMonth + 1) MOD 12 //wraps around from Dec to Jan OUTPUT CurrentMonth

Note: examples 4 and 5 WON'T use the additional ENUM_TO_STR function since it's not in the syllabus, but you can to get more descriptive output if you want

4

Days of Week

Create a procedure to output the days of the week - Sunday will be the first day like the built-in function DAYINDEX assumes

Output in brackets the day that was yesterday, today and tomorrow in a format such as:

TYPE DayEnum = (Sun, Mon, Tue, Wed, Thu, Fri, Sat) DECLARE TodayIndex : DayEnum TodayIndex ← DAYINDEX(TODAY()) DECLARE index : INTEGER FOR index ← 1 TO 7 IF index = TodayIndex THEN OUTPUT "Day ", index, " (today)" ELSE IF index = TodayIndex - 1 OR index = 7 AND TodayIndex = 1 THEN OUTPUT "Day ", index, " (yesterday)" ELSE IF index = TodayIndex + 1 OR index = 1 AND TodayIndex = 7 THEN OUTPUT "Day ", index, " (tomorrow)" ELSE OUTPUT "Day ", index ENDIF ENDIF ENDIF NEXT index

5

Email Priorities

Create a program to represent an email inbox - it should:

  • Define email priorities of values Low, Medium and High
  • Define an email record containing the email message and priority
  • Populate (or randomly generate) the inbox with 5 emails
  • Sort these emails according to priority - i.e. High emails should be at the beginning of the inbox
  • Output all emails in the inbox
TYPE Priority = (Low, Medium, High) TYPE Email DECLARE msg : STRING DECLARE importance : Priority ENDTYPE DECLARE Emails : ARRAY[1:5] OF Email DECLARE Index, EndIndex : INTEGER DECLARE DidSwap : BOOLEAN DECLARE TmpEmail : Email FOR Index ← 1 TO 5 Emails[Index].msg ← CHR(64 + Index) Emails[Index].importance ← INT(RAND(3) + 1) NEXT Index DidSwap ← TRUE EndIndex ← 4 WHILE DidSwap = TRUE DO DidSwap ← FALSE FOR Index ← 1 TO EndIndex IF Emails[Index].importance < Emails[Index + 1].importance THEN TmpEmail ← Emails[Index] Emails[Index] ← Emails[Index + 1] Emails[Index + 1] ← TmpEmail DidSwap ← TRUE ENDIF NEXT Index EndIndex ← EndIndex - 1 ENDWHILE OUTPUT "Priority | Message" FOR Index ← 1 TO 5 OUTPUT "[", Emails[Index].importance, "] - ", Emails[Index].msg NEXT Index

6

Degree Level

Note: this program will require the use of the additional ENUM_TO_STR function (or additional arrays/records), so while you could do it in most real languages, it goes beyond the scope of A-Level

The goal is to create a program that prompts the user to enter their degree level as a string (Bachelors, Masters, PhD) until they enter a valid choice

Also note that Cambridge pseudocode doesn't provide a way to loop through or check ENUM values exist, so we will need to use an IF statement to check if the user's entry is valid

TYPE DegreeLevel = (Bachelors, Masters, PhD) DECLARE UserInput : STRING DECLARE Degree : DegreeLevel DECLARE Valid : BOOLEAN Valid ← FALSE OUTPUT "What degree level did you obtain?" REPEAT INPUT UserInput IF UserInput = ENUM_TO_STR(Bachelors) THEN Valid ← TRUE Degree ← Bachelors ELSE IF UserInput = ENUM_TO_STR(Masters) THEN Valid ← TRUE Degree ← Masters ELSE IF UserInput = ENUM_TO_STR(PhD) THEN Valid ← TRUE Degree ← PhD ELSE OUTPUT "Invalid degree level entered - try again:" ENDIF ENDIF ENDIF UNTIL Valid = TRUE OUTPUT "Congratulations on achieving your ", ENUM_TO_STR(Degree), " degree!"