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. Invokingstudy
command 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 ofModuleInfoCode
and returns aboolean
to indicate whether the list ofModuleInfoCode
can satisfy the all theCourseRequirement
-
In
PrimitiveRequirement
, this is achieved by checking whether all theModuleInfoCode
satisfies all theCondition
stored in it. -
In
CompositeRequirement
, this is dependent on theLogicalConnector
it has. It would return the value of firstCourseRequirement#isFulfilled
LogicalConnector
secondCourseRequirement#isFulfilled
.
-
-
percentageFulfilled()
— a method that also accepts a list of ModuleInfoCode returns adouble
value that represents the percentage of completion of theCourseRequirement
-
In
PrimitiveRequirement
, this is achieved by calculating the number of distinct modules that satisfy for eachCondition
, inPrimitiveRequirement
and it is divided by the sum ofminToSatisfy
. -
This depends on the
LogicalConnector
inCompositeRequirement
. If it is aOR
connector, we return the maximum offirst#percentageFulfilled
orsecond#percentageFulfilled
. TheAND
logical connector returns the average of the degree of completion for both requirements.
-
-
getUnfulfilled()
— a method that accepts a list ofModuleInfoCode
and returns a list of RegExes from where none of theModuleInfoCode
matches. 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#updateRequirementStatusList
is called. This updates the pre-existingRequirementStatusList
and fills it with newRequirementStatus
objects based on currentnonFailedCodeList
fromGradTrak
. -
UI
callsgetRequirementStatusList
fromLogic
and retrieves the updatedRequirementStatusList
fromModel
. 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
Condition
fulfilled by only usingModuleInfoCode
ofModuleTaken
-
Pros: Easy to implement since we are restricting scope to only checking whether strings match pattern in
Condition
-
Cons: Possible that the
CourseRequirement
class 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
CourseRequirement
class 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:
Condition
class stores aPattern
to check whether a requirement is satisfied-
Pros: Compact representation of which
ModuleInfoCode
fulfills the requirement -
Cons: Difficult to find the correct regular expression for some
Condition.
-
-
Alternative:
Condition
class stores an exact list ofString
to check whether a condition is satisfied-
Pros: Easy and interpretive to use.
-
Cons: Might need to store a long list of
String
if many modules can fulfil theCondition
eg: 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
Course
andCourseRequirement
objects. -
Allow
Condition
to check its fulfillment by accessing other attributes of aModuleTaken
object 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