Nathanael Seen Zhong Qi - Project Portfolio

PROJECT: iGrad


Ui

Overview

iGrad is a desktop module management and graduation tracking application. The user interacts with it using a CLI, and it has a GUI created with JavaFX, FXML and CSS.

Summary of contributions

  • Code contributed: [All commits] [Project Code Dashboard]

  • Major enhancement: Added course management feature.

    • What it does: Allows the user to create/edit/delete a course, through which various modules, and requirements (degree requirements) are 'housed'. Also allows users to track overall degree progress information, such as overal MCs completed for the course, and current CAP.

    • Justification: Without a course, it does not make sense to have modules and degree requirements (by which those modules are mapped under), as standalone features. In fact, this feature could be said to be the most important feature.

    • Credits: The original AB3 codebase which provided the necessary 'backing'

  • Major enhancement: Integrate course management, requirement management, and module management feature together, by implementing the module done, requirement assign, and requirement unassign, commands.

    • What it does:

      • module done: allows the user to record down the grade she has obtained for a particular module she has completed

      • requirement assign: allows the user to assign certain modules under a requirement

      • requirement unassign: opposite of requirement assign

    • Justification: Again this feature is particularly important, in helping one track her graduation requirements and overall degree progress.

    • Highlights: This three commands function helps to 'glue' the three components of the app altogether.

      • For instance, in the module done command, when a module is marked as 'done', the module manager is involved to update that module. Also, requirement manager helps to update all requirements which contains this module. Finally, the course manager helps to update information such as the total overal MCs fulfilled, and CAP.

    • Credits: Here, I would like to credit the rest of my teamates for implementing the module management and requirement management feature, without which this feature would not have been able to make sense.

  • Minor enhancement: remodularise some UI logic (avatar, Progress Side Panel, etc), Wayne, has initially written.

  • Contribution to Team Based Tasks:

    • In-charge of merging any PRs request, this involves critically reviewing the code, and fixing it if necessary.

      • Things I checked/helped my teamates fix when merging PRs were; violating checkstyle, obvious logic bug errors, design/implementation considerations and concerns, remodularising of code.

      • Also, helped resolve merge conflicts; #320, #307, and #295.

    • Set-up Reposense, and Nelify for my team, for tracking code contributions and easy reviewing of UG/DG docs.

    • Managed the issue tracker for the first-half of this project.

    • Designed the initial application UI prototype for the first draft UG submission.

  • Review/Mentoring Contributions:

    • Assisted Teri, in her initial difficulties understanding and adapting to such a large code-base, by creating stubs for her implementation. She feedbacked that she liked my way of mentoring and found it to be really helpful.

    • Provided PR code reviews to my team members on code aspects I felt could be be improved, as I was merging their PRs (#313, #295, #281, #276, #269, #188, #193, #177, #89, #80, and many more!)

Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability in written communication, in the form of documentation, with possibly non-technical end-users.

Features

Section by: Nathanael Seen

This segment highlights three key features iGrad offers to NUS students, namely; a Course Planner, an MCs Tracker, and a CAP Tracker.

If you would like a more in-depth overview of the actual components of our application, please refer to the next section; Components, for more details.

Course Planner

iGrad was built with every NUS student in mind. Our flexible course planner allows you to plan a course of your own dreams, be it those of you doing a single degree programme, a double degree programme, and even a concurrent degree programme.

With our course planner, you would be able to enter your current course details such as your modules and the various degree requirements by which those modules are mapped.

(For instance, the Computer Science course has the various modules, highlighted in blue, and degree requirements, boxed in red):

graduation degree requirements
Figure 1. Computer science degree requirements

MCs Tracker

We are sick of counting our MCs at the beginning of every semester; be it counting the total course MCs left before you can graduate, or tracking the number of MCs left for those invidual degree requirements (boxed in green, in Figure 1).

With our MCs feature, you would be able to easily keep track of how close you are to graduation, as all this information is automatically updated and recomputed, each time you have completed a certain module.

CAP Tracker

No more googling for CAP calculators. iGrad’s CAP tracker helps you keeps track of your current CAP at every step of your journey in your course. In addition, it even offers predictive features so you know how well you have to do in order to achieve your dream CAP.

Everything Integrated into One Application

But the best part is that these features are all integrated into our application; iGrad. And with all these important pieces of information in one place, you would never go amiss keeping track of all your graduation requirements.

Components

This segment details the various components of iGrad. As shown in Figure 2 below, these components follow a hierachical structure, exactly like how an NUS course is structured.

hierachical structure
Figure 2. Hierachical overview of iGrad components

Here is how our application looks like (on a typical usage):

app screenshot ui
Figure 3. iGrad application screenshot

The following is the same screenshot of our application, but with the various components of our application highlighted:

app screenshot ui components highlighted
Figure 4. iGrad components screenshot

As per the screenshot above (in figure 4):

You may refer to Figure 2, if you would like a quick recap on the hierarchical structuring of these components.

Course

A course is simply a group of degree requirements.

It contains important information such as your current CAP, total number of MCs you have completed thus far, and semesters left before you can graduate.

In short, it helps you keep track of your overall degree progress.

Degree Requirements

Under a course are the various degree requirements, such as the ones shown in Figure 2 above; Computer Science Foundation, Mathematics and Sciences, and Unrestricted Electives.

Each requirement comprises of the modules you need to complete in order to fulfill that particular requirement.

Additionally, each requirement consists of important information such as the number of MCs you have already fulfilled.

Modules

Finally, modules are the basic building block of all the other components.

These could be modules you have taken, modules you are currently taking and modules that you plan to take.

Each module allows recording of other optional information, such as indicating the grade you have obtained for those modules.

Contributions to the Developer Guide

Sections contributed to DG

Course Feature

Section by: Nathanael Seen

As per the Model diagram above, there is only one CourseBook in the system.

A CourseBook represents all information related to helping a user track her graduation requirements, including the following:

  • One UniqueModuleList, consisting of all Modules in the system, which may or may not be mapped to any (degree) Requirement(s)

  • One UniqueRequirementList, consisting of all (degree) Requirements

  • One CourseInfo, representing important information related to a degree course, which would be detailed more in this section

Implementation

Section by: Nathanael Seen

In the implementation of the course feature which 'houses' the various Requirements and the Modules mapped under those requirements, a CourseInfo class is necessary in order to represent overall course information, such as the name of the course, the current cap of the student (or user), the total credits (MCs) fulfilled/required, and semesters left before she could graduate.

These important information are encapsulated in the CourseInfo class which should only have one Name, one Cap, one Credits and one Semesters object(s), at any one time:

CourseInfoClassDiagram
Figure 5. Structure of CourseInfo Class

Also, as per the diagram above, we note that these fields (in a CourseInfo) are optional, because a user might not even have a course set in the first place. This occurs when the application is started out in a 'blank' state, with no initial or sample data.

Now, to describe more of this CourseInfo class, its fields, the following two sub-sections would detail the Credits and Semesters classes and their design.

Thereafter, the next two sub-sections would attempt to explain the mechanics of the two crucial static methods computeCredits(…​) and computeCap(…​), which is used throughout the application.

Finally, the last two sections would be dedicated to elaborating how the various course commands; course edit and course achieve works.

Credits

Section by: Nathanael Seen

CourseCreditsClassDiagram
Figure 6. Course Credits Class Diagram

The Credits class maintains 2 integers; creditsRequired and creditsFulfilled, for storing both the total number of course credits (MCs) required for graduation, and also the number credits the user has fulfilled thus far, respectively.

Also, it some public validation methods (isValidCreditsFulfilled() and isValidCreditsFulfilled()) which is used in the constructor for constructing a 'valid' Credits object.

The following constraints defines a 'valid' Credits object:

  • creditsRequired > 0

  • creditsFulfilled >= 0

Note that creditsFulfilled can be more than or equals to creditsRequired, as it is possible that a student 'over-fulfills' the graduation requirements in her course.

The following are some noteworthy details on the Credits class/object:

  • Credits is recomputed through the computeCredits(…​) method in CourseInfo (whenever there is a possible change). This newly recomputed Credits object would be subsequently updated in the CourseInfo

  • creditsRequired is recomputed by summing all the creditsRequired of the individual Requirements in the UniqueRequirementList

  • creditsFulfilled is recomputed in the same way as creditsFulfilled

  • In the CourseInfo class, Credits is first initialized (to some non-empty value) only when the following conditions have been met:

    • The user has already set a course, through the course set command.

    • There is at least one Requirement in the UniqueRequirementList,` by which creditsRequired and creditsFulfilled could be re/computed.

Compute Credits

In this section, we describe how computeCredits(requirement: Requirement[]) works to recompute the latest Credits.

As previously mentioned, this method is invoked everytime there is a possible change in the total course Credits.

This might be caused through the following commands:

  • module done where a Module is attributed a grade and marked done. Resultantly, all Requirements in the UniqueRequirementList, consisting of that Module would have to be updated. Also, but most importantly, the creditsFulfilled attribute of those Requirements would have to be updated, causing an eventual change in the total course creditsFulfilled of Credits (in CourseInfo).

  • requirement un/assign where Module(s) are assigned to that particular requirement, where some Modules might have already been marked as done and given a grade, hence falling back to the first scenario, where creditsFulfilled of a course would have to be updated.

  • requirement edit where the creditsRequired attribute of that requirement might be updated, resulting in the need to update the overall course creditsRequired as well

  • And many others such as; requirement add, requirement delete, module edit, module delete

Now, we have specified the possible scenarios where computeCredits(…​) might have to be invoked to update Credits of CourseInfo, however we have not described how it actually works.

As from our previous discussion, we note that creditsFulfilled and creditsRequired is computed through summing up the creditsFulfilled and creditsRequired for the individual Requirements.

More formally, the interactions between the various classes, for the computation to be performed are as such:

ComputeCreditsSequenceDiagram
Figure 7. Sequence Diagram for computing updated credits
Compute Cap

Similar to Compute Credits, Cap has to be updated frequently, each time module information in coursebook changes, and the computeCap(…​) method facilitates the recomputation of the updated Cap.

The diagram below describes the interactions between the various classes, as the computation is performed:

ComputeCapSequenceDiagram
Figure 8. Sequence Diagram for computing updated cap

We note that from above, CourseInfo does most of the interfacing with other classes, and the rest of the classes don’t interact with each another.

In summary, the following steps are performed as computeCap(…​) is invoked:

(For each Module in the moduleList):

  1. CourseInfo first iterates through reqList to determine if a Module belongs to any Requirement

  2. If it does, CourseInfo again interfaces with Module to extract its Grade.

  3. Finally, CourseInfo interacts with Grade to determine if the Grade is a non-SU grade.

  4. If the Grade is non-SU, the Module is factored into Cap computation.


Module Done

Section by: Nathanael Seen

Overview

This feature enables students to mark a module which they have completed with a certain grade. Once a module is marked 'done', it would be counted to graduation requirements.

Implementation

Trivial as it might seem, there are actually quite a number of coursebook data which needs to be updated when a module is marked 'done'.

This includes the Module itself, the various Requirements in the UniqueRequirementList, and the CourseInfo.

The following diagram illustrates this:

ModuleDoneActivityDiagram
Figure 9. Module Done Sequence Diagram

As from the above, there are two possible scenarios; either a Module belongs to at least one Requirement or that it does not belong to any Requirement.

In the latter case, calls to methods which update CourseInfo would be immediately invoked, bypassing the updating of the Requirement(s).


Requirement Assign

Section by: Nathanael Seen

Overview

This feature allows Module(s) to be assigned or mapped under a Requirement.

Implementation

We note that as like the module done command, a few pieces of information in the coursebook would have to be updated.

The command-parsing-execute mechanism is largely similar to requirement add the above, however, we would like to focus more on the activities (such as validations, etc) that happens at the Model side.

The following diagram details this:

RequirementAssignActivityDiagram
Figure 10. Activity Diagram when assigning modules under a requirement.

Hence as per the diagram, we observe that modules are assigned to a Requirement on the following two conditions:

  1. All Modules to assign are existent in the coursebook (more specifically, the UniqueModuleList)

  2. Modules have not already been previously assigned to that Requirement