1. Overview

My team, comprising of 5 software engineering students, was tasked with enhancing a basic command line interface (CLI) desktop address book application for our Software Engineering project.

With modern life comes a fast-paced, hectic lifestyle. It is increasingly easy to be overwhelmed by the insurmountable number of responsibilities and tasks we have to fulfill. Most task-manager applications involve countless clicking and navigation, which defeats their purpose. To rectify this, my team decided to design a simple, no frills CLI student assistant from the address book to cater to students who prefer CLI.

We named our application ELISA, an Exceptionally Loud and Intelligent Student Assistant. ELISA enables users to add and track their tasks and events while receiving reminders for them. With a sassy and humorous personality and her user-interface interaction (in the form of a chat bot), she is simpler, yet more engaging to use than other regular task managers. There are also other features to aid the productivity of students and to spice up their life.

2. Application introduction

This is how our application looks like:

task panel
Figure 1. User interface annotated

ELISA’s various components serve the following functions:

Component Function

ELISA icon

Icon of the application which changes with the different mode of ELISA.

Result display

The "chat box" with ELISA which contains all past user input and ELISA’s response.

Command box

The user can type their commands here to interact with ELISA.

View panel

The current view of the application. It can show the task, event, reminder or calendar panel.

3. Summary of contributions

In this section, I will be briefly going through my contributions to this team project. For the full extent of my contributions to the project, please visit here.

3.1. Functional contributions

  • Priority mode (Major Feature):

What does it do?

This feature allows the user to enter a priority mode where they are able to prioritize tasks with a higher priority first and focus on that task to complete it.

Why make it?

This features helps the user narrow their focus down to completing one task at a time and prevents them from being overwhelmed by a long list of tasks.

Why is it special?

There are multiple modes to cater to different user needs. Users can choose from a focus mode, a timed mode, a normal mode or a combination of multiple modes. The different modes will be explained in greater detail in the user guide.

At the same time, users are able to update their task list in realtime (add, delete, edit) so that they can always be sure that the task that they are currently doing is the most important one.

Difficulties?

The difficulty of this feature comes from the fact that it has to be integrated with all the other commands within the application. That means that the algorithm needs to be written in a way such that it is constantly updating itself to give the user the most important task despite the changes in the tasks.

For example, when a new task of a higher priority (than the current task) is added, the algorithm should be able to make that the task that is to be completed first. This requires a lot of integration with all the other code so that ELISA can behave differently depending on whether she is in priority mode.

  • Sorting (Minor Feature):

The sorting feature allows users to sort their items so that they are able to better arrange their items in a way that is most useful to them. Each list has its own sorting algorithm while users can also choose to sort the items based on their priority or description. Refer to here for more information on this feature.

  • Find (Minor Feature):

The find feature allows users to find an item based on the description of the item. This will aid users in getting the item that they need at the fastest possible time. Refer to here for more information on this feature.

  • Other implementations:

Helped my teammates with the following features and implementation:

  1. Implementation (PR #138) and fixes on the calendar panel so that it is able to display the events and update the events when there are changes to the events (PR #148, PR #181 and PR #244).

  2. Helped with the implementation of the undo for marking a task as completed (PR #153).

3.2. Other contributions:

  • Project management:

Review and made notable suggestions on the following PR:

  1. PR #69 - gave idea of storing the priority in the item class that was ultimately adopted

  2. PR #130 - gave idea of getting the command word to display to the user was ultimately adopted

  3. PR #132 - gave suggestion on how to improve the code for readability and to follow coding practice.

  4. PR #134 - gave idea of moving method to the UndoableCommand abstract class was ultimately adopted in PR #137

  5. PR #141 - gave suggestion of using Long instead of BigInteger

  6. PR #158 - gave suggestion on how to improve the feed back message to the users for undo command, which was ultimately adopted

  7. PR #252 - gave suggestion on fixing some issue with the code and optimizing it

  • Refactoring:

Refactored the model (PR #68) and storage (PR #79) class so that it will work with the project.

  • Documentation:

Updated the developer guide to include the use cases (PR #44),user stories (PR #47) and manual testing (PR #271).

4. Contributions to the User Guide

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

4.1. Entering priority mode: priority

Overwhelmed by the number of tasks to complete? Priority mode will help you narrow your focus down to the most pressing task to complete.

500
Figure 2. ELISA before priority mode with a long list of tasks

By simply typing priority into the command box, you will be given one single task of the highest priority among your task list. This task is chosen by ELISA base on priority and the order in which the task was added to the list.

500
Figure 3. ELISA in priority mode

Notice that the ELISA icon turns red to signify that you are in priority mode and your task list has shrunk from 5 tasks down to the 1 most important task.

When you are done with your current task, just tell ELISA you are done by simply typing done 1 and ELISA will generate the next task for you.

500
Figure 4. ELISA after completing the first task

To go back to the normal task view, simply type priority again. Or even better, complete all your tasks and you will be automatically brought out of priority mode.

500
Figure 5. ELISA after all tasks are completed

Feeling lazy? You can also opt to turn off priority mode at a specific time by typing priority dd/mm/yyyy hhmm and ELISA will turn it off at that specific time for you.

For the easily distracted, there is an extreme focus mode available. Simply tell ELISA that you want to enter the extreme focus mode by attaching a -f flag to the back of the command. In the extreme focus mode, commands such as show, sort, find, game, event and reminder are banned.

Format: priority [DATETIME] [-f]

Examples:

  • priority - activates or deactivates the priority mode

  • priority 30/10/2019 1200 - activates the priority mode and ask ELISA to turn it off on 30/10/2019 at noon

  • priority 2.hour.later -f - activates the focus mode and ask ELISA to turn it off 2 hours later

  • Note that this command can only be called in the task panel and when you have incomplete tasks to be completed.

  • Note that if priority mode is currently on, any variation of priority will turn it off.

  • Note that all command such as edit, undo and redo still works in priority mode. However, if a done or delete command takes you out of priority mode and then you undo it, it will only undo the command but will not take you back into priority mode.

5. Contributions to the Developer Guide

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

5.1. Model component

500
Figure 6. Structure of the Model Component

The ItemModel,

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

  • contains the ItemStorage that stores all the data for ELISA.

  • exposes four observable lists that can be viewed by the Ui and will cause an update in the Ui when it is updated.

5.1.1. Design Consideration

The original implementation was to have one single observable list and modifying it whenever the view changes. We decided against it as we believe that this will result in O(n) time complexity for switching the different views as we need to iterate through all the items to find the relevant items.

Using the four visualization list, we only need to change the pointer when we want to change the view of the viewing panel making it an O(1) time complexity solution. However, this makes it more complicated to maintain the different lists.

5.2. Priority Mode

5.2.1. Implementation

The priority mode is used to aid the user in focusing on the most pressing task that they have especially when they have many tasks in their list. As priority mode is only for clearing of tasks, the priority mode can only be activated at the task pane of the application.

The priority mode is mainly controlled in the ItemModelManager and the following are the methods it uses within the ItemModelManager:

  • ItemModelManager#togglePriorityMode() - Toggle the priority mode depending on whether it is on or off.

  • ItemModelManager#toggleOnPriorityMode() - Helper function to toggle on the priority mode.

  • ItemModelManager#toggleOffPriorityMode() - Helper function to toggle off the priority mode.

There are two variants to the priority mode, a normal priority mode and a focus mode. The focus mode is more restrictive than the normal priority mode, preventing the user from doing any operations that are not relevant to the task list, such as adding a new event. This is currently implemented by having a separate Parser when ELISA is in focus mode. (Refer to Design Consideration for more details)

There are two ways to trigger priority mode, a normal priority mode that is controlled fully by the user and a scheduled priority mode that is triggered by the user but is scheduled to turn off after a specific amount of time. In addition to the above three methods, the scheduled priority mode also uses the following method:

  • ItemModelManager#startTimer(LocalDateTime) - Starts a timer to turn off the priority mode.

5.2.2. Example run of priority mode

In this section, we will show a run of the priority mode and a overview of the mechanism at each step. In particular, we will be showing how the ScheduledPriorityCommand works as it has a more complicated implementation than the normal PriorityCommand.

  1. The user opens his Task panel and types in priority 30.min.later.

  2. The incomplete tasks are added to a PriorityQueue where they are ranked by their priority.

  3. Once all the items are added into the PriorityQueue, ELISA will peek the first task from the queue and present it to the user.

  4. The user can type done 1 when he is done with the current task to retrieve the next task. This carries on until there is no more undone task left to do in the PriorityQueue. This is shown in the activity diagram below.

300
Figure 7. Activity diagram for priority mode
  1. ELISA will automatically disable the priority mode after 30 minutes and show all the task that the user have in his task list currently.

5.2.3. Internal working of the command

The figure below shows the sequence diagram on what happens from a simple execution of the priority 30.min.later command. We will go through the internal mechanism of the execution of the ScheduledPriorityCommand.

PriorityMode
Figure 8. Sequence diagram for priority mode
  1. When the user types in the command, the LogicManager takes in the command as a string and pass it to the ELISAParser

  2. The ELISAParser parses the string and determine whether the command is that of a normal PriorityCommand or a ScheduledPriorityCommand. In this case, a new ScheduledPriorityCommand is created and is passed back to the LogicManager.

The following steps (except step 4) are also applicable to PriorityCommand.
  1. Within the LogicManager, the ScheduledPriorityCommand#execute() method is called and the command is executed.

  2. The ScheduledPriorityCommand calls the ItemModel#scheduleOffPriorityMethod() which creates a new Timer object and a new TimerTask object. The TimerTask object will be scheduled to fire off at a specific time, which in this case is 30 minutes later (as defined by the user).

  3. The SchedulePriorityCommand then calls ItemModel#togglePriorityMode() which calls the private method ItemModel#toggleOnPriorityMode() (since the current state of the priority mode is false).

  4. This creates a new TaskList which will have the task with the highest priority added to it. This TaskList will be displayed to the user.

  5. A CommandResult is passed to the ScheduledPriorityCommand and then back to the LogicManager to be passed into the Ui, informing the user that the priority mode is activate.

A normal PriorityCommand will end at this point and will only be deactivated by the user’s input of priority again.
300
Figure 9. Sequence diagram for the scheduled turning off of priority mode
  1. As the Timer within the ItemModelManager is still running on a separate thread, it will trigger the TimerTask#run() when the user defined time is reached.

  2. The TimerTask will call ItemModelManager#toggleOffPriorityMode() which will cancel the Timer and destroy the Timer. This is to ensure proper cleanup of the thread.

  3. All the items are added back into the TaskList and shown to the user. The priority mode is deactivated.

5.2.4. Design Consideration

Aspect: How to restrict commands for focus mode

  • Alternative 1: Storing a boolean within the ItemModelManager to check if the application is in focus mode or normal mode. Commands that are not allowed to be called in focus mode will check against this boolean to determine if the command is allowed.

Pros Cons

This implementation will contain the changes within the class of the Command itself and will ensure that they do not interfere with each other. This will make it easier to maintain the code.

This implementation is not scalable as each new Command that is added will need to be checked to see if they are allowed in focus mode. There is also the additional overhead of checking the state of the ItemModelManager at every call of Command#execute().

  • Alternative 2 (Current implementation): Create a new FocusElisaParser that extends from the current ElisaParser but prevent the parsing of commands that are not allowed in focus mode.

Pros Cons

This implementation stops the creation of the Command at the Parser level which will reduce the computational cost to the application.

There might be difficulty in maintaining the Parser#parse() method of the two Parser.

Both methods are not scalable in the long run, but at this moment, alternative 2 is favoured as it prevents the command from even being parsed or created, which saves the computing time. At the same time, it is easier to maintain as one only needs to edit the Parser#parse() method instead of having an if-else loop in all the command that are banned.

Aspect: How to turn off the priority mode after a fixed time

  • Alternative 1: Storing the timer within the ScheduledPriorityCommand.

Pros Cons

Adheres to the SLAP principle with each class having it’s own implementation of the Command#execute(ItemModel). It is easier to maintain the code and prevents overloading the ItemModelManager.

There is no way to end the schedule priority mode prematurely as the timer is kept within the command and so cannot be referenced after the execution of the command.

  • Alternative 2 (Current implementation): Storing the timer within the ItemModelManager.

Pros Cons

The timer can be referenced from the ItemModelManager and so it can be cancelled prematurely if the user chooses to do so.

This implementation will clutter the ItemModelManager further and make it harder for maintaining the code.

Alternative 2 was chosen as we believe that the ability to cancel a scheduled priority mode prematurely is more important than the maintainability of the code at the moment.

5.2.5. Possible extension

At the moment, the user is not able to keep track of the amount of time that he has before the schedule priority mode is over. This can be improved by including a countdown timer in the Ui when the user toggles on the scheduled priority mode.