PROJECT: ModuleBook

Overview

As part of the project requirement of CS2103T offered by NUS, my team of 4 software engineering students and I were tasked with enhancing a basic command line interface desktop addressbook application for our Software Engineering project. We decided to morph the addressbook into a module management application called ModuleBook designed specifically for NUS students.

ModuleBookUILayout
Figure 1. Graphical user interface of ModuleBook

ModuleBook is a desktop module manager application designed with the needs of NUS students in mind. It is designed to streamline the process of managing time and resources related to the modules offered by NUS. The user interacts with ModuleBook using command line interface, which also comes with graphic user interface created with JavaFX. ModuleBook is written in Java.

As of the current build (v1.4), ModuleBook offers the following features:

  1. Detailed archive of all modules offered by NUS (adapted from NUSMods API).

  2. Track modules of interest.

  3. Search for specific modules using search filters.

  4. Add personalised deadlines to tracked modules.

  5. Add links to tracked modules.

My role was to adapt and migrate the base code of addressbook to the requirements of ModuleBook, as well as to design and enhance the operations related to tracking a module. This includes the add, delete, list and find command. The following sections illustrate these enhancements in more detail, as well as the relevant documentation I have added to the user and developer guides in relation to these enhancements.

Summary of contributions

This section documents my contribution to this team project in the from of code, documentation as well as supporting the team.

  • Major enhancement: Added the ability to find specific modules using filtered search.

    • What it does: Allows the user to search for modules by filtering any combination of the following categories:

      1. module

      2. title

      3. description

      4. prerequisite modules

      5. precluded modules

      6. semesters the modules are offered

    • Justification: This feature should be very useful for freshmen students, or students who are unfamiliar with the large selection of modules offered by NUS. These students would be able to able to find a module of their interest without requiring in depth knowledge of specific details related to these modules.

    • Highlights: The search is is able to detect and ignore minor spelling mistakes when searching within the title or description. Searching is also extremely fast, with most search cases taking less than a second. These would definitely improve the user friendliness of the search feature.

    • Credits: Module information is directly adapted from the API provided by NUSMods. The adaptation and storage of module information is done by Ge Shuming, one of the students involved in this project. Without these information, this feature would not be possible.

  • Minor enhancement: Improved the base add and delete module commands to be more in line with the program specifics.

  • Code contributed: [Link to RepoSense] [Test code]

  • Other contributions:

    • Project management:

      • Took part in the release of v1.1 - v1.4 (4 releases) on GitHub

    • Enhancements to existing features:

      • Overhauled the base addressbook code to meet the requirements of Modulebook features. (Pull request #16)

    • Documentations:

      • Updated UML diagrams for Developer Guide (Pull request #58,)(Pull request #175)

    • Community:

      • PRs reviewed (with non-trivial review comments): (Pull request #40)

Contributions to the User Guide

The following is an excerpt from our ModuleBook User Guide, showing additions that I have made for the add, delete and find commands. They showcase my ability to write a comprehensive documentation with the end-users in mind.

Finding an archived module: find

Method 1: Using command lines

Find archived modules with the the given prefix and keyword.
Format: find PREFIX\ KEYWORD …​

It is possible to use any number or combination of filters. Prefixes not present will not be considered in the search.
  • Prefixes: (case sensitive)

    • all\ : List all the modules. Overrides all other prefixes.

      • Example: find mod\ cs all\, all\ will override mod\ and list all the modules.

    • mod\ : Find all modules with module code that contains at least one of the given keyword(s).

      • Example: find mod\ cs ma st will list all modules with module code containing cs or ma or st.

    • title\ : Find all modules with title that contains all of the given keyword(s).

      • Example: find title\ software engineering will list all modules with titles containing "software" and "engineering".

    • desc\ : Find all modules with description that contains all of the given keywords(s).

      • Example: find desc\ software engineering will list all modules with description containing "software" and "engineering".

    • prereq\ : Find all modules with prerequisites that match at least one of the given keyword(s).

      • Example: find prereq\ cs2030 cs2040 will list all modules with prerequisite of cs2030 or cs2040.

    • preclu\ : Find all modules with preclusion that match at least one of the given keyword(s).

      • Example: find preclu\ cs2030 cs2040 will list all modules with preclusion of cs2030 or cs2040.

    • sem\ : Find all modules offered in a particular sem 1 - 4. (Sem 3 and 4 are special terms 1 and 2).

      • Example: find sem\ 1 3 will list all modules offered in semester 1 or special term 1.

  • The prefixes can be used together in any order to filter modules that passes all the search requirements.

    • Example: find mod\ cs2 cs3 desc\ software engineering sem\ 1 will show all modules with module code containing cs2 or cs3 with description containing "software" and "engineering" offered in semester 1.

  • The keywords are case insensitive. e.g cs2103t will match CS2103T.

  • Keywords used in title\ and desc\ are tolerant of minor spelling mistakes.

    • Example: find desc\ enginering will display results similar to find desc\ engineering.

  • Search is performed using string matching, commonly used keywords will therefore produce many search results.

  • Invalid prefixes and keywords before a valid prefix will be ignored.

    • Eg: find INVALID\ invalidKeyword mod\ cs the INVALID\ invalidKeyword will be ignored, mod\ cs will be searched.

Keywords are searched using "OR" relation (apart from title\ and desc\ which uses an "AND" relation.) while predicates are seached using "AND" relations. For example, find mod\ cs ma title\ linear algebra will produce results of all modules with (module code containing cs OR ma) AND (title containing linear AND algebra)

Method 2: Using GUI

Alternatively, you can simply click on the search button on the top left hand corner (shortcut key: F2) and select search. Input your keywords in the fields provided within the popup.

SearchGui
Figure 2. Searching using GUI
Modules are imported from NUSMods database.

Adding a module: add

Adds a module to be tracked.
Format: add MODULE_CODE

  • The add is case insensitive. e.g cs2103t will match CS2103T.

  • Only module code is searched for module to be added.

  • Only full words will be matched e.g. cs2103 will not match cs2103t.

Modules are imported from NUSMods database.

Examples:

  • add cs2103t

Deleting a module: delete

Untracks a module.
Format: delete MODULE_CODE

  • The delete is case insensitive. e.g cs2103t will match CS2103T.

  • Only module code is searched for module to be added.

  • Only full words will be matched e.g. cs2103 will not match cs2103t.

Examples:

  • delete cs2103t

Contributions to the Developer Guide

This section contains an excerpt for the filtered find feature in the ModuleBook Developer Guide. This should highlight my ability to write a detailed technical documentation and simplify complicated technical knowledge.

Search filtering feature

Implementation

The search filtering feature Uses different categories of predicates to narrow down the search space of the archived module list. The user is able to able to combine different categories of search to find modules that passes all the user defined filters. This can be achieved through the use of Predicate which can be chained with additional predicates and applied to a FilteredList. This requires additional predicate classes that searches their individual fields for the keywords.:

  • ModuleCodeContainsKeywordsPredicate — Tests that a module module code matches any of the keywords given.

  • TitleContainsKeywordsPredicate — Tests that a module title contains all of the keywords given.

  • DescriptionContainsKeywordsPredicate — Tests that a module description contains all of the keywords given.

  • PrerequisiteContainsKeywordsPredicate — Tests that a module prerequisites matches any of the keywords given.

  • PreclusionContainsKeywordsPredicate — Tests that a module preclusions matches any of the keywords given.

  • SemesterContainsKeywordsPredicate — Tests that a module semester matches any of the keywords given.

FindCommandClassDiagram
Figure 3. Class diagram for search.

As shown in the figure above, predicate classes are created in the FindCommandParser, the list of predicates is used to construct a find command. Note that only DescriptionContainsKeywordsPredicate and TitleContainsKeywordsPredicate depends on LevenshteinDistanceChecker, the rest of the predicates do not depend on it.

SearchActivityDiagram
Figure 4. Activity diagram for search predicates.

The figure above shows how each predicate checks for the keyword. Do note that DescriptionContainsKeywordsPredicate and TitleContainsKeywordsPredicate requires their specified field to contain all of the keywords, while the rest of the predicates returns true as long as their field contains at least one of the keyword.

The user is able to use any combination of filters and the order of input should not matter. Examples of valid find commands:

  • find mod\ cs2 : Should display a list of modules with module code containing "cs2"

  • find mod\ cs2 prereq\ cs2040 : Should display a list of modules with module code containing "cs" and with prerequisite of "cs2040"

The following sequence diagram shows how the find operation wold work:

FindSequenceDiagram
Figure 5. Sequence diagram for search filtering.
The lifeline for FindCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.

As represented in the figure above, when a FindCommandParser is constructed by ModuleBookParser#parseCommand, the FindCommandParser would construct a list of Predicate<module> based on the parsed arguments, which is used to construct a FindCommand.

During the execution of FindCommand#execute(), each predicate is chained and applied to the FilteredList.

Finally, a FilteredList of Modules that passes all of the filters will be displayed.

Design Considerations

Aspect: Requirements.
  • Module field requirements: Information from the archivedModules.json would have to be abstracted out as individual fields in the ArchivedModule object.

    • pros: Added fields can be used for future developments.

    • cons: Can potentially slow down Module construction and operations due to increased size for each Module object.

  • Search with spelling mistake tolerance: Due to the potential of spelling mistakes within fields such as the module and module discription which does not rely on module codes, searching these fields can accept mistakes with a degree of 2 Levenshtein Distance from any of the original intended word.

    • pros: Much more robust searching potential.

    • cons: Will slow down the search.

Aspect: Incremental development.
  • Adding new search filters: Developing and integrating new filters.

    • pros: Filters can be developed independently and incrementally, filters can be integrated based on priority.

    • pros: Can be further adapted to search fields from Deadline and Links.