Skip to content

Manual Fixes to Course Prerequisites

JamesyJi edited this page Dec 21, 2021 · 30 revisions

Hardcoding Manual Fixes for Course Prerequisites

Status (top priority listed below):

  • (CODE): (PERSON) (STATUS)
  • COMP: (Adam) MERGED
  • ENGG (Gabriella), MERGED
  • ACCT (Adam), MERGED
  • FINS (James) MERGED
  • INFS (Jenn), MERGED
  • MARK (Kevin),MERGED
  • MATH (Sally), PR
  • PSYC (Sano) MERGED
  • COMM (Vincent rip) MERGED
  • ECON (Gabriella) MERGED
  • IBUS (Kevin) EMPTY
  • MGMT (Isaac) MERGED
  • TABL (James) MERGED
  • ACTL (Adam) MERGED
  • SENG (James) MERGED

Completion status: 8 / 122. To see all study areas, run cat conditionsProcessed.json | grep -Eo '"[A-Z]{4}' | sort | uniq | wc -l

To begin hardcoding, go to the manual-fixes branch and then create a branch off that titled, for example, COMP-manual-fixes.

When you have finished hardcoding for a faculty, submit a PR to merge into manual-fixes.

Ew hardcoding ... why?

Many of the prerequisites in the UNSW Handbook are hand-written by the relevant departments. We need to put them into a format that can be processed by our algorithm. The algorithm checks whether a student satisfies pre-requisites in order to enrol in a course.

What to Feed the Algorithm

The algorithm eats a simple diet with components clearly distinguished. It uses:

  • && for and and including
  • || for or
  • 'in' for uhh in and from, and
  • ( ) round brackets for grouping components.

These all help us demonstrate the relationships between components.

It can't digest complex handwritten text and only wants to eat simple course, program and/or specialisation codes. Any important requirement that can't be reduced to codes should go into a new 'warning' text pop-up (see Example 2 below).

How to Cook

The conditions are sitting in conditionsProcessed.json. You'll see the initial ingredients for a course:

"ACCT3202": {

    "original": "Prerequisite: Enrolment in Accounting Co-op Major (ACCTB13554)<br/><br/>",

    "processed": "Enrolment in Accounting Co-op Major (ACCTB13554)"
}

The original value is the pre-requisite text straight from the handbook. The processed value is ultimately what we want to feed the algorithm. It already looks different to the original text because we have run some regex magic on the file.

Here, the algorithm will be happy just with the program code. This means we should access the processed key and change its value to only include the specialisation code:

"ACCT3202": {

    "original": "Prerequisite: Enrolment in Accounting Co-op Major (ACCTB13554)<br/><br/>",

    "processed": "ACCTB13554"
}

Many of the pre-requisites are fine as is! For example, ACCT3610's processed value, depicted below, is already clear and has no issues with grouping or arbitrary plaintext. The regex magic worked and you don't need to do anything with it:

"ACCT3610": {
    "original": "Prerequisite: ACCT2542 and FINS1613<br/><br/>",
    "processed": "ACCT2542 && FINS1613"
},

Where to Cook

Take a look at the skeleton code in backend/data/processors/manualFixes/template.py and copy it into a new file.

I have been using functions for each change (or the same function if multiple courses have identical pre-requisites), but feel free to do it however you think is most efficient. I tend to name functions by the course code affected: e.g. COMP_1511() for COMP1511 or COMP_9301_3() for course codes COMP9301, COMP9302 and COMP9303 if they had the same change.

Common Ingredients and Allergies

Below are some common conventions for the transformations:

  • minimum WAM requirements, such as you need to have a WAM over 85 (rip), become 85WAM.
  • minimum course grade requirements similarly become XXGRADE.
  • general references to a faculty's majors/minors, like 102UOC in Computer Science majors, become 102UOC in COMP?1. For minors we would say COMP?2 and for honours COMP?H. The ? tells us that this needs to be mapped to some group of majors/minors/honours specialisations. In some cases, majors may also include honours so you would need to do COMP?H || COMP?1.
  • general references to a faculty's programs, like you gotta be in one of da Actuarial Studies programs, become ACTL#. We use the four letters associated with that faculty followed by a # (see Example 5).
  • general references to a specific subject area, like do 102UOC in compsci courses, become 102UOC in COMP. Here, we just use the first four letters.

Note: This can be a bit ambiguous with things. E.g. 12UOC in Business courses. Does this refer to ZBUS or F Business? As a last resort, can contact faculties via the official circles email to clarify.

  • any requirements described as a co-requisite should go inside square brackets, with the usual transformations inside. For example, "Co-requisite: COMP1511 and COMP1521" becomes [COMP1511 && COMP1521]

For the below, refer to the faculty and school mappings for the exact code:

  • general references to a faculty should change to, for example, F Engineering
  • general references to a school should change to, for example, S Chemistry

Allergy 1: Exclusions

'Exclusions' are a little spicy. If you see what looks like an exclusion, we need to put it in a different file called coursesProcessed.json. For our purposes, in the skeleton file we have pulled all course data into the global variable COURSES. All you need to do is add the excluded course / program / major to the exclusions key in the COURSES dictionary. For example: COURSES[courseCode]["exclusions"]["MATH1241"] = "Higher Level Mathematics 1B". The exclusion does not need to go into the processed value (see also Example 4 below).

Allergy 2: Complex text

If we have some text that can't be reduced to a simple operation, then you might need to create a new warning key with the requirement (see Example 2 below).

Example Menu

Below are examples of some transformations.

Example 0: COMP9461

This example shows a simple case of reducing to program codes:

"original": "Prerequisite: Students enrolled in program 4515 Bachelor of Computer Science (Hons) or program 3648.<br/><br/>",

"processed": "4515 || 3648"

Example 1: COMP4920

This example shows the use of UOC and some simple grouping:

"original": "Prerequisite: COMP2511 or COMP2911, and completion of 96 UOC in Computer Science.<br/><br/>",

"processed": "(COMP2511 || COMP2911) && 96UOC in COMP"

Example 2: COMP3901-2

This example shows how we deal with complex text and warnings:

"original": "Prerequisite: 80+ WAM in COMP, SENG or BINF courses, completion of all first and second year core requirements a CSE program, and agreement from a suitable CSE academic supervisor.<br/><br/>"

"processed": "80WAM in (COMP || SENG || BINF)"

"warning": "You must complete all first and second year core requirements of a CSE program and obtain agreement from a suitable CSE academic supervisor to enrol in this course."

Example 3: COMP9494

This example shows how we can reduce complex requirements to simple operations:

"original": "Two prerequisite conditions:<br/>1. Students have taken:<br/>6 UOC from the following: COMP3411; and<br/>12 UOC from the following: COMP9444/COMP9417/COMP9517/COMP4418<br/>2. Students must have a WAM of 70 or higher<br/><br/>",

"processed": "COMP3411 && 70WAM && 12UOC in (COMP9444 || COMP9417 || COMP9517 || COMP4418)"

Example 4: COMP6721

This example has an exclusion SENGAH that has been put into the COURSES dictionary. It does not need to go into the processed pre-requisite:

"original": "Pre-requisite: MATH1081 AND COMP2521 AND (not enrolled in SENGAH)<br/><br/>"

"processed": "MATH1081 && COMP2521"

Example 5: ACTL1101

This example has a general program mapping.

"ACTL1101": {
    "original": "Prerequisite: MATH1151 AND in Actuarial Studies programs.<br/><br/>",
    "processed": "MATH1151 && ACTL#"
},