Overview
GradTrak is an application that was morphed from the codebase of Address Book - Level 4. It was conceptualised and designed in mind to assist students of NUS to track their graduation progress and plan modules they want to take in the future.
I was involved in designing the functionality for users to track their course requirement. In the sections that follow, I will showcase my contributions to the project and also some of the section that I have written in the User and Developer’s Guides.
Summary of contributions
-
Major feature: added the functionality for users to track their graduation requirements
-
What it does: This feature allows the user to check against a list of modules they have taken or plan to take and informs them whether they have fulfilled the requirements. The feature also allows the users to know approximately, the extent of completion of these graduation requirements.
-
Why this feature: This feature is one of the core functionalities of GradTrak. This greatly enhances quality of life of students in NUS as it would allow them to find out their graduation requirements as well as how far are they away from fulfilling them.
-
Highlights: It is difficult to implement this feature because course requirements can vary greatly. As a course requirement can be composed of simpler course requirements, another technical difficulty that I faced was designing an interface that treats simple and more complex course requirements uniformly. To tackle this hurdle, I had to do some research on design patterns to understand how to come up with such design to suit the need of my project.
-
-
Minor enhancement:
-
created user editable files for users to store different courses and course requirements
-
added some sample courses into the application namely: Computer Science Algorithms, Artificial Intelligence and Software Engineering.
-
created utility for to load json file formats after exporting jar file. #94
-
-
Code contributed: [Project Code Dashboard]
-
Other contributions:
-
Project Management
-
Set up milestones, issue tracker (examples)
-
Added user stories (examples)
-
Reviewed and assigned issues to teammates in previous round of product testing (examples)
-
Managing release, v1.4 which should be up in a couple of days
-
-
Refactored Code and changed documentation from AddressBook - Level 4 code base
-
Renamed significant amount of variables, classes in Address Book - Level 4 code base #66
-
Changed some visuals for the User Guide, Developer Guide #90
-
Changed some of the prose of the User Guide, Developer Guide (see above Pull Request)
-
Modified irrelevant sections of User Guide, Developer Guide (see above Pull Request)
-
-
Contributions to the User Guide
In this section, I will highlight some of my contributions to the user guide namely,
the displayreq and study commands in GradTrak.
Display course requirements: displayreq
One of the core functions of GradTrak is to check whether the student has fulfilled his/her degree requirement.
As of v1.4 of the application, GradTrak currently only has course information of 3 Computer Science major Focus Areas, namely:
-
Algorithms
-
Artificial Intelligence
-
Software Engineering
The course of study can be changed by using the study command which will be outlined in the later sections of this guide.
Based off the modules you have passed and completed, or have planned to take in the future semesters, this command displays to you the degree to which you have completed your course requirements. It also displays other relevant information regarding your course’s requirements. This can be seen in the annotated screenshot below:
displayreq is invokedThese information are displayed in the result panel when displayreq is keyed in:
-
Name of the course requirement.
-
Description of the course requirement. Gives an overview of the modules the student should take to fulfill the requirement.
-
Requirement type. Informs the student the importance of the requirement in relation to their course of study.
-
Requirement progress bar and percentage. Informs the student the extent to which he/she have fulfilled the course requirement.
Format: displayreq
Set the current course of study: study
To set the desired course of study, the student can simply key in the following command:
Format: study COURSE
The parameter COURSE is case-sensitive.
|
As of v1.4, GradTrak has information to keep track of course requirement
from the courses mentioned below:
Example:
-
study Computer Science Algorithms
Sets the course of study to Computer Science with Focus Area Algorithms. Invokingstudycommand again will change your course of study.
More courses will be rolled out in GradTrak in the future.
Contributions to the Developer Guide
In this section, I will highlight some of my contributions to the developer guide.
Display Course Requirement feature
Current Implementation
The displayreq command allows the students to see all their course requirements and also check if the modules they have
taken fulfils them. This command is currently facilitated by 2 classes in Model, CourseRequirement and
RequirementStatus:
CourseRequirement Interface
As there are many different kinds of course requirements that can be found in NUS, it is difficult to iron down the common characteristic they all share. This can be seen in the examples found below:
For the requirement shown in Figure 9, students just have to complete at least one of CS3203 or CS3216 and CS3217 or CS3281 and CS3282. Whereas for the requirement in Figure 10, students have to fulfill all of the conditions stated above. Even though these two conditions might seem quite different, we are still able to draw some key observations about what they have in common:
-
Each requirement is composed of conjunction or disjunction of clauses. In turn, the clauses can be composed by conjunction and disjunction of other simpler clauses.
-
Clauses that cannot be further broken down into smaller clauses usually contain the following information:
-
a list of modules that can be used to satisfy the clause
-
how many of the modules should be completed to satisfy the clause.
-
These observations gives us some insight as to how we should design the interface. As such, the CourseRequirement interface follows a Composite design pattern. This is favoured as it allows
us to treat individual and composition of CourseRequirement objects uniformly through the use of polymorphism. The diagram below gives an overview of
how CourseRequirement is implemented.
CourseRequirement class diagramThis interface is realised by 2 subclasses - PrimitiveRequirement and CompositeRequirement.
The PrimitiveRequirement is the simplest building block for CourseRequirement. Each PrimitiveRequirement stores a
list of Condition objects. A Condition object stores a Java Pattern and an int, minToSatisfy. A Condition
is satisfied if there are at least minToSatisfy many distinct
ModuleInfoCode that matches Pattern in it. PrimitiveRequirement is satisfied only if all Condition objects in the list are
fulfilled.
For instance in Figure 9, a suitable Condition for completing CS3216 and CS3217 would be
a Pattern that accepts only CS3216 or CS3217, and a minToSatisfy of 2.
The CompositeRequirement can replicate the behaviour of more complex course requirements. Each CompositeRequirement
object contains two CourseRequirement objects. It also contains a LogicalConnector enumeration
that tells the CompositeRequirement how two different CourseRequirement are composed using logical operations. For instance, for
a list of ModuleInfoCode to satisfy a CompositeRequirement that has a AND LogicalConnector, the list must
satisfy the both CourseRequirement objects contained in CompositeRequirement.
There currently 3 methods that CourseRequirement provides information to the student:
-
isFulfilled()— a method that accepts a list ofModuleInfoCodeand returns abooleanto indicate whether the list ofModuleInfoCodecan satisfy the all theCourseRequirement-
In
PrimitiveRequirement, this is achieved by checking whether all theModuleInfoCodesatisfies all theConditionstored in it. -
In
CompositeRequirement, this is dependent on theLogicalConnectorit has. It would return the value of firstCourseRequirement#isFulfilledLogicalConnectorsecondCourseRequirement#isFulfilled.
-
-
percentageFulfilled()— a method that also accepts a list of ModuleInfoCode returns adoublevalue that represents the percentage of completion of theCourseRequirement-
In
PrimitiveRequirement, this is achieved by calculating the number of distinct modules that satisfy for eachCondition, inPrimitiveRequirementand it is divided by the sum ofminToSatisfy. -
This depends on the
LogicalConnectorinCompositeRequirement. If it is aORconnector, we return the maximum offirst#percentageFulfilledorsecond#percentageFulfilled. TheANDlogical connector returns the average of the degree of completion for both requirements.
-
-
getUnfulfilled()— a method that accepts a list ofModuleInfoCodeand returns a list of RegExes from where none of theModuleInfoCodematches. This method is used in the module recommendation feature.
RequirementStatus Class
The RequirementStatus is an association class that links a CourseRequirement with VersionedGradTrak in Model.
This can be seen in the class diagram below:
RequirementStatus class diagramIt also stores the result of the associated CourseRequirement object’s isFulfilled and percentageFulfilled
methods acting on the list of ModuleInfoCode.
Below is a sequence of execution when displayreq command is executed by the student:
-
Model#updateRequirementStatusListis called. This updates the pre-existingRequirementStatusListand fills it with newRequirementStatusobjects based on currentnonFailedCodeListfromGradTrak. -
UIcallsgetRequirementStatusListfromLogicand retrieves the updatedRequirementStatusListfromModel. This list is displayed in theResultPanel.
The sequence diagram below summarises the execution mentioned earlier:
displayreq executesDesign Considerations
Aspect: How Condition class checks if it is fulfilled.
-
Current choice: Checking
Conditionfulfilled by only usingModuleInfoCodeofModuleTaken-
Pros: Easy to implement since we are restricting scope to only checking whether strings match pattern in
Condition -
Cons: Possible that the
CourseRequirementclass is unable to replicate requirements that does not depend onModuleInfoCode
-
-
Alternative: Checking Requirement fulfilled by accessing any attribute of
ModuleTaken-
Pros: Increased flexibility and easier to replicate actual NUS requirements that does not depend on
ModuleInfoCode -
Cons: Increased complexity to implement
CourseRequirementclass properly.
-
We chose the current choice over the alternative due to time constraints in the project. Moreover, our current choice is sufficient to replicate most NUS requirements accurately.
Aspect: Choice of information stored in Condition class
-
Current choice:
Conditionclass stores aPatternto check whether a requirement is satisfied-
Pros: Compact representation of which
ModuleInfoCodefulfills the requirement -
Cons: Difficult to find the correct regular expression for some
Condition.
-
-
Alternative:
Conditionclass stores an exact list ofStringto check whether a condition is satisfied-
Pros: Easy and interpretive to use.
-
Cons: Might need to store a long list of
Stringif many modules can fulfil theConditioneg: General Education Modules
-
We chose our current choice as it takes up much fewer space to store. Moreover, storing a pattern
also improves performance time since each ModuleInfoCode is compared against one`Pattern` instead of an entire
list of String objects.
Possible Improvements
-
Allow students to create and export their own
CourseandCourseRequirementobjects. -
Allow
Conditionto check its fulfillment by accessing other attributes of aModuleTakenobject in the future.
PROJECT: Cuckoo Hash
This is an experimental assignment from CS5330 - Randomised Algorithm. The aim was to investigate various effects of different Cuckoo Hash schemes. More information on assignment here and more on the codes of the implementation here