PROJECT: NUS Module Planner


Overview

The NUS Module Planner (NUSModPlnr) is for Computer Science (CS) students at the National University of Singapore (NUS) to manage their enrollments in NUS modules over their school life. With NUSModPlnr, module planning has never been easier!

The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 250+ kLoC.

Summary of contributions

  • Major feature: Importing of all modules that NUS has to offering, made available using the NUSMods.

    • What it does: Allows the user to view the list of all the modules offered by NUS, including details such as Faculty, Workload, Description, Module Credits and in which semesters it is offered.

    • Justification: This feature improves the product significantly because a user can view actual accurate data of the modules currently being offered by NUS, with the latest data available.

    • Highlights: This feature forms the basis of most of the logic for this application, and is used by various other models such as GraduationRequirements, Programmes, and Timetable. The implementation was a significant amount of effort in order to build the foundations for other models and logic controllers to make use of. Having real life data helps make the application more helpful for the user, as compared to using a dummy system or one that requires users to input module details by themselves.

    • Credits: NUSMods for providing the data and API.

  • Major feature: Handled the storage and JSON serialisation mechanism for all models to maintain a consistent state throughout multiple runs of the application.

    • What it does: Allows the user to use the application offline, and have its state saved and restored upon every launch of the app. It can also allow for moving of the data across devices by moving the relevant JSON files along with the executable.

    • Justification: This feature improves the product usability significantly because a user can come back to the app across multiple stretches of time and will still be able to pick up where they left off - a very practical scenario of a Student who wants to update his records after every semester.

    • Highlights: This enhancement greatly affects the overall usability of the application and existing commands and changes to models will require modification in order to ensure that the data is stored and loaded correctly. The implementation required an in-depth analysis of how different models come together. The implementation was challenging as well, as it required content changes from the additions of models.

    • Credits: The original JSON Storage code used in Address Book Level 3.

  • Major feature: Co-Developed GraduationRequirements and DegreeProgramme with @DANamic modelled after actual graduation requirements of NUS Computer Science and Information Systems undergraduate students to support complex fulfilment logic.

    • What it does: Allows the users to determine if he/she has fulfilled individual graduation requirements based on his/her enrolled modules.

    • Justification: This feature improves the product usability significantly by allowing users to view the modules that he/she is required to take in order to fulfil certain graduation requirements.

    • Highlights: This feature is the core feature of the entire application, and is the very purpose of what the application aims to achieve - to allow students to better plan their modules better across semesters.

  • Major feature: Co-Developed Specialisations with @DANamic, which is modelled after actual specialisations of NUS Computer Science and Information Systems undergraduate students to support further complex fulfilment logic between Primary and Elective modules.

    • What it does: Allows the users to determine if he/she has fulfilled specialisations based on his/her enrolled modules.

    • Justification: This feature improves the product usability significantly by allowing users to view the modules he/she is required to take in order to fulfil certain specialisations.

    • Highlights: This feature is another core feature of the entire application, complementing GraduationRequirements in order to model a Student’s constraints as accurately as possible.

  • Major feature: Co-Developed the foundational code for Planner and associated classes for all other advanced features to be built upon.

    • What it does: Allows other developers to work with a baseline formed around the framework provided by AddressBook-Level3.

    • Justification: This initial refactoring of AddressBook to Planner is important and needs to be done synchronously and before other portions of code can be developed as this forms the basis of which other features rely on.

    • Highlights: This feature blocks the entire application development and needed to be completed fast, as it would have impeded the progress of my team members. As this was a lot to do at once, I have had the help of @DANamic and @gruntultra in order to push this foundational code out.

    • Credits: The original code from AddressBook-Level3, @DANamic, @gruntultra

  • Minor enhancement: Created helper classes to facilitate easier testing of models such as TypicalStudent and StudentBuilder.

  • Code contributed: Please see the RepoSense Report here!

  • Other contributions:

    • Project contributions:

      • Contributed to releases v1.0 - v1.4 (5 releases) on GitHub

    • Enhancements to existing features:

      • Refactoring of AddressBook-Level3 to accommodate application use case

      • Wrote additional tests for existing features to increase coverage from 88% to 92% (#1, #2)

    • Documentation:

      • Generated diagrams to enhance readability of Developer Guide

      • Contributed to Features and Module Management sections of User Guide

    • Community:

      • PRs reviewed: #81, #85, #86, #87, #96, #97, #101, #105, #107, #108, #109, #110, #179, #185, #186, #188, #189, #194, #197, #198, #199, #203

      • Reported bugs and suggestions for other teams in the class: #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11, #12, #13, #14, #15, #16

      • Worked with @DANamic and @gruntultra to perform initial codebase refactoring to allow for the easier building of features into the application #1, #2, #3, #4

      • Implemented the first JSON Serializable and Adapted classes for models to be easily saved and loaded to and from JSON files, which was further used by other team members for their models, alongside ModuleDataImporterUtil to load a list of Modules from NUSMods API (#1, #2, #3)

      • Written Test Cases for tests broken by refactoring (#1)

      • Fixed CheckStyle issues caused by refactoring (#1, #2, #3, #4)

      • Worked with @DANamic to develop Graduation Requirements (#1)

      • Fixed bugs discovered by PE Dry Run (#1, #2, #3, #4)

Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

Features

(Benjamin wrote the preamble of "Features" below.)

These are the key features that are part of the NUSModPlnr!

Before you dive into the commands themselves, do familiarise yourself with how the User Guide has been formatted in terms of the commands to key in!

Command Format

  • Words in UPPER_CASE are the parameters to be supplied by you (e.g. in student add n/NAME major/MAJOR, NAME is a parameter which can be used as student add n/John Doe major/CS).

  • Items in square brackets are optional (e.g module grade CS2103T [grade/GRADE] can be used as module grade CS2103T grade/A+ or as module grade CS2103T).

  • Items surrounded by < and > can be used any positive number of times (at least once, e.g. <MODULE_CODE> can be used as CS2040 (1 time), CS2040 CS2030 CS2103T (3 times), etc).

  • Parameters can be in any order (e.g. if the command specifies n/NAME major/MAJOR, major/MAJOR n/NAME is also acceptable).

Common Parameters

These are parameters that are commonly used in commands available in NUSModPlnr.

  • MODULE_CODE - a code for a module in NUS

  • INDEX - a index number of an item listed

    • Must be a positive integer

  • LESSON_NUMBER - a number for the class number for a module

  • NAME - a name of a entity

    • Must be alphanumeric, spaces are allowed

  • SEM - an academic semester

    • Must be one of the following: 1, 2, st1, st2

  • YEAR - a year of study (e.g. Year 1, 2, 3, 4, 5, 6)

    • Must be a non-negative integer from 1 to 6

  • GRADE a letter grade for a module

    • Must be one of the following: A+, A, A-, B+, B, B-, C+, C, D+, D, F, CS, CU, W, EXE

Let’s begin!

Module Management

(Benjamin wrote this section on "Module Management" below.)

The following commands below are part of the application’s Module Management, which allow you manage the modules of your academic plan.

Do note that you can click on the modules to see the module description. When managing your modules, you will be able to see the Module View Screen (Figure 8. below).

ModuleList
Figure 1. Home Screen View
All the following commands require a timetable to be selected (using the timetable active command).

Adding modules: module add

You can use this command to add a number of modules to your timetable for the selected semester (see the timetable active command) and student (see the student active command).

Format: module add <MODULE_CODE>

Example:

  • module add CS2040

  • module add CS2040 CS2103T CS2101

Removing modules: module remove

You can use this command to remove a number of modules from your timetable for the selected semester (see the timetable active command) and student (see the student active command).

Format: module remove <MODULE_CODE>

Example:

  • module remove CS2040

  • module remove CS2040 CS2103T CS2101

Viewing added modules: module list

You can use this command to display a list of modules of your timetable for the selected semester (see the timetable active command) and student (see the student active command).

Format: module list

Example:

  • module list

Adding exempted modules: exempt add

You can use this command to add a number of exempted modules for the selected student (see the student active command).

Format: exempt add <MODULE_CODE>

Example:

  • exempt add CS2040

  • exempt add CS2040 CS2103T CS2101

Removing exempted modules: exempt remove

You can use this command to remove a number of exempted modules from the selected student (see the student active command).

Format: exempt remove <MODULE_CODE>

Example:

  • exempt remove CS2040

  • exempt remove CS2040 CS2103T CS2101

Viewing exempted modules: exempt list

You can use this command to display a list of modules that you have declared as exempted.

Format: exempt list

Example:

  • exempt list

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

Model Component

Planner Model

ModelClassDiagram
Figure 2. Structure of the Model Component

API : Planner.java

The Planner,

  • stores a UserPref object that represents the user’s preferences.

  • stores the Planner data such as the list of Student, Module

  • store an index for the currently active Student

  • store an index for the currently active Semester

  • exposes an unmodifiable ObservableList<Student> that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change.

  • exposes an unmodifiable ObservableList<Module> that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change.

  • does not depend on any of the other three components.

Student Model

ModelStudent
Figure 3. Student Class Diagram

API : Student.java

The Student,

  • stores a Name object that represents the Student’s Name

  • stores a Major object that represents the Student’s Major

  • stores a Enrollment object that represents the Student’s Name

  • stores a TimeTableMap object that represents the Student’s TimeTables

  • stores a GenericSpecialisation object that represents the Student’s Specialisation

  • stores a List<Lesson> object that represents the Student’s currently selected Lessons

Module Model

ModelModule
Figure 4. Module Class Diagram

API : Module.java

The Module,

  • stores a ModuleCode object that represents the Module’s Module Code. This is used as the key identifier between modules.

  • stores a List<SemesterData> object that represents the Semester-specific data of the Module, such as Exam Dates, Exam Duration and Timetable.

  • stores other String objects that represents the various other attributes of the Module such as:

    • acadYear representing Academic Year

    • preclusion representing Precluded Modules

    • description representing Module Description

    • title representing Module Title

    • department representing Module department

    • faculty representing Module faculty

    • workload representing Module workload

    • prerequisite representing Module prerequisites

    • moduleCredit representing Module Credits

    • prereqTree representing Module prerequisite tree

The ModuleDataImporterUtil,

  • is a helper class used to load Modules from a JSON file downloaded from NUSMods API

  • handles the conversion of Modules from JSON format to Module objects using JsonSerializableModule and JsonAdaptedModule

  • loads SemesterData into each Module

Graduation Models

ModelPackageGraduation
Figure 5. Graduation Package Class Diagram

The Graduation package,

  • contains a list of GraduationRequirement classes that represents the Modules which are required to be taken by Student in order to Graduate.

  • contains an AggregationType class

Graduation Requirement Model

The GraduationRequirement interface,

  • provides the interface of all implementations of GraduationRequirement

  • provides a helper function getStatusIcon to display a tick or cross depending on whether the GraduationRequirement is fulfilled or not.

Single Graduation Requirement Model

The SingleGraduationRequirement class,

  • is an implementation of the interface GraduationRequirement

  • acts as a basic GraduationRequirement containing only a single Module

  • determines if the SingleGraduationRequirement is fulfilled by checking if the Student has enrolled in the specified Module

Compound Graduation Requirement Model

The CompoundGraduationRequirement class,

  • is an implementation of the interface GraduationRequirement

  • contains a list of GraduationRequirement objects

  • contains an AggregationType enum to represent how to calculate fulfillment of the CompoundGraduationRequirement object

  • acts as a aggregator of GraduationRequirement representing requirements where a Student needs to complete a group of modules in certain ways such as:

    • any module can be completed or

    • all modules must be completed or

    • completed modules must be within a specified list

    • add up to a certain amount of Module Credits

  • determines if the CompoundGraduationRequirement is fulfilled by checking if the Student has fulfilled the internal list of GraduationRequirement stored in the CompoundGraduationRequirement, with checks based on the AggregationType specified.

Specialisation Graduation Requirement Model

The SpecialisationGraduationRequirement class,

  • is an implementation of the interface GraduationRequirement

  • contains a list of GraduationRequirement objects to represent a Specialisation’s primary modules

  • contains a list of GraduationRequirement objects to represent a Specialisation’s elective modules

  • handles the calculation of fulfillment for the SpecialisationGraduationRequirement object based on Major and primary and elective modules

Storage Component

StorageDiagram
Figure 6. Structure of the Storage Component

API : Storage.java

The Storage component,

  • can save UserPref objects in json format and read it back.

  • can save the Planner data in json format and read it back.

  • consists of various JSON implementations of Models

  • handles the saving and loading of Models to provide stateful behaviour in the application

Additional details on how certain Models were stored in JSON format is available at JSON Handling & Module Data Management.

JSON Handling & Module Data Management

As mentioned in several sections (of [Implementation]) above, NUS Module Planner has the capability to pull live data for entities, such as, Major and Module, via JSON.

JSON stands for JavaScript Object Notation and is a lightweight format for storing and transporting data. We choose this syntax as it is "self-describing" and thus, human-readable and easy to understand, while keeping our application size low.

Jackson is a standard JSON library for Java that contains a suite of data-processing tools, including JSON parsers and generators. Jackson is used for the JSON-related operations mentioned below.

The original schema of the JSON file came from NUSMods via version 2 of their API available here. The endpoints we used are:

  • /{acadYear}/moduleInfo.json

  • /{acadYear}/modules/{moduleCode}.json

The Academic Year (acadYear) used is: 2019/2020.

From the JSON responses of the above API endpoints, we created several classes to help convert the JSON representation of the object into a working Java Object that the application can use, as well as the other direction which is used to stored the current state of the Planner in a JSON file.

Such classes include:

  • JsonSerializableLesson

  • JsonSerializableModule

  • JsonSerializablePlanner

  • JsonSerializableSemesterData

The ModuleDataImporterUtil is used to parse the raw JSON files containing Module information and convert them into JsonSerializableModule objects which contain various attributes such as a list of JsonSerializableSemesterData.

sequenceDiagramModuleDataImporterUtil
Figure 7. Sequence Diagram for a run operation in ModuleDataImporterUtil

The LessonDataImporter is used to parse the raw JSON files containing Module-specific Lesson information and convert them into JsonSerializableModule objects which contain various attributes such as a list of JsonSerializableLesson.

sequenceDiagramLessonDataImporterUtil
Figure 8. Sequence Diagram for a run operation in LessonDataImporter

The following classes are used to convert objects of various classes (such as Module, Lesson, Student) into Jackson-friendly versions.

  • JsonAdaptedEnrollment

  • JsonAdaptedGrade

  • JsonAdaptedLesson

  • JsonAdaptedModule

  • JsonAdaptedModuleCode

  • JsonAdaptedSemesterData

  • JsonAdaptedSemesterYear

  • JsonAdaptedStudent

  • JsonAdaptedStudentSemester

  • JsonAdaptedTimeTable

  • JsonAdaptedTimeTableMap

  • JsonAdaptedTimeTablePair

When saving the Planner, JsonSerializablePlanner is used to store all the various attributes of the Planner in a JSON-compatible format, such as list of Student objects, currently active Student index, and currently active SemesterYear.

Proposed Future Enhancements

NUS Module Planner has a lot more potential to grow!

Below are some of the other great features we think can be implemented in v2.0 onward:

  • Module Viewer with Search - Other than just searching for modules, search for their content instead, such as modules that deal with Heat Transfer or Geology.

  • Timetable Planner with Friends - Instead of just viewing timetables of different students (i.e. friends) separately, be able to overlay them in one "Timetable View", for easier group planning.

  • Requirements Double-Upper - Instead of just one Major, handle double Major programme students, or even those with Minors.

  • Module Popularity Prediction - Get and analyse historic data from NUSMods about module uptake, so that students do not have to plan for modules that would be overly subscribed.

  • Support for Overseas Exchange and University Town College Programmes - Be able to plan for special modules only offered in these programmes, if a student is enrolled in them.

  • Live Module Data - Get the latest Module Data available from NUS Mods and plan your Semester before it starts.

  • Module Data History - View historical data on Module enrollments and decide if when you want to take a certain Module.

Appendix A: Product Scope

Target User Profile

  • targets prospective, incoming and current Undergraduate NUS Students

  • needs to plan/track academic progression via enrolling and passed modules

  • prefer desktop apps over other types

  • can type fast

  • prefers typing over mouse input

  • is reasonably comfortable using CLI apps

Value Proposition

  • aggregates all information regarding modules and graduation requirements in a single app

  • manages academic progress and module planning faster than a typical mouse/GUI driven app