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
, andrequirement 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.
-
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):
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.
Here is how our application looks like (on a typical usage):
The following is the same screenshot of our application, but with the various components of our application highlighted:
As per the screenshot above (in figure 4):
-
Course is indicated in blue,
-
Degree Requirements is indicated in red, and
-
Modules is indicated in yellow
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 allModules
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:
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
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 thecomputeCredits(…)
method inCourseInfo
(whenever there is a possible change). This newly recomputedCredits
object would be subsequently updated in theCourseInfo
-
creditsRequired
is recomputed by summing all thecreditsRequired
of the individualRequirements
in theUniqueRequirementList
-
creditsFulfilled
is recomputed in the same way ascreditsFulfilled
-
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 theUniqueRequirementList
,` by whichcreditsRequired
andcreditsFulfilled
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 aModule
is attributed a grade and marked done. Resultantly, allRequirements
in theUniqueRequirementList
, consisting of thatModule
would have to be updated. Also, but most importantly, thecreditsFulfilled
attribute of thoseRequirements
would have to be updated, causing an eventual change in the total coursecreditsFulfilled
ofCredits
(inCourseInfo
). -
requirement un/assign
whereModule(s)
are assigned to that particular requirement, where someModules
might have already been marked as done and given a grade, hence falling back to the first scenario, wherecreditsFulfilled
of a course would have to be updated. -
requirement edit
where thecreditsRequired
attribute of that requirement might be updated, resulting in the need to update the overall coursecreditsRequired
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:
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:
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
):
-
CourseInfo
first iterates throughreqList
to determine if aModule
belongs to anyRequirement
-
If it does,
CourseInfo
again interfaces withModule
to extract itsGrade
. -
Finally,
CourseInfo
interacts withGrade
to determine if theGrade
is a non-SU grade. -
If the
Grade
is non-SU, theModule
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:
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:
Hence as per the diagram, we observe that modules are assigned to a Requirement
on the following two conditions:
-
All
Modules
to assign are existent in thecoursebook
(more specifically, theUniqueModuleList
) -
Modules
have not already been previously assigned to thatRequirement