PROJECT: ELISA

Introduction

My team of 5 were tasked with morphing or enhancing a basic command line interace (CLI) desktop address book application for our Software Engineering Project.

We were all computing students who were experiencing high amounts of stress from juggling the never-ending list of responsibilities we had. We then realised that this was not a problem that was unique to ourselves, thus we resolved to develop an application to help reduce the stress of individuals like us. We decided to morph the project into a student assistant we called ELISA. Our Extremely Intelligent n' Loud Student Assistant. We decided that ELISA could help us through 5 ways.

  1. She could help keep track of our tasks & events

  2. She could help us focus on one task at a time when we feel overwhelmed.

  3. She could remind us so that we don’t have to constantly scan through the lists to ensure that we remember everything we need to.

  4. She could entertain us.

This is how our user interface looks like:

blimyjUI

My role was to implement the reminder and snooze functionality as well as to design the underlying commons classes used by my teammates.

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.

  • Major enhancement: added the ability to set and snooze reminders

    • What it does: allows the user to remind himself of details of tasks or events when needed.

    • Justification: This feature improves the product significantly because the user now no longer needs to constantly scan through lists in order to remember information at the right time. Instead ELISA will now remind him when it’s time.

    • Highlights: This enhancement had to deal with multiple threads and had to handle the occurrence of reminders correctly. Due to the undo / redo feature, it required an in-depth analysis of thread-safety and time-sensitive behaviour analysis. The implementation was challenging as it required modifications to other components such as the ItemModelManager in order to ensure the correct handling of reminders when edited, undone or redone.

  • Minor enhancement: add commons classes

    • What it does: Contains the details required for tasks, events & reminders.

    • Justification: It allowed for cross-reference of information between the lists so that details of the tasks, events & reminders could be accessed regardless of the type of list being viewed without cyclic dependencies.

    • Highlights: This enhancement had to support immutability in order ensure thread-safety as well as to make the code easier to maintain.

    • Credits:

  • Other contributions:

    • Project management:

      • Managed releases v1.1 - v1.4 (6 releases, excluding v1.3.4) on GitHub

      • Managed team meetings & agendas. (Week 4-10)

      • Managed bug allocation for PE.

      • Managed Github team repo. (Setting up of branch protection & tools mentioned below)

    • Documentation:

      • Updated the developer guide by giving the implementation of the undo function as well as filling in use cases and user stories

    • Reviewed the following pull requests:

      • PR #82:

        • Suggested abstraction of arePrefixesPresent method to adhere to DRY principle.

        • Suggested usage of Optional to prevent potential error.

      • PR #116: Suggested changes in function naming in order to maintain code consistency which were eventually implemented.

      • PR #266: Spotted potential conflict with reminder due to repeated addition from autoReschedule event.

    • Tools:

      • Integrated AppVeyor & Coveralls to the team repo [#281]

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.

Reminder Feature

So focused on your work that you forget the other tasks in your life? Don’t worry! You can ask ELISA to remind you to do what you need to do, when you need to do it!

Adding a reminder: reminder

Simply add your reminder with this command: reminder John’s Birthday -r 11/11/2019 1440
and ELISA will carry it out!

BeforeReminderCommand

Once it’s time for you to be reminded, ELISA will remind you! Best of all, ELISA will play a chime so you won’t need to have ELISA open in order to be reminded!

AfterReminderCommand

More specifically, the reminder command format is: reminder DESCRIPTION -r REMINDER [-t TAG]

Here are some other ways you could use this command!:

  • reminder Finish UG -r 11/10/2019 1400

  • reminder Get John’s Birthday gift -r 2019-09-19T14:00 -t friend

  • reminder Study for 2103T Exam -r 3.day.later

    1. It is currently not possible to set a reminder for events with an autoreschedule flag. We intend to include this in v2.0 .

    2. It is not possible to set a reminder in the past.

FailReminderCommand

Snoozing a reminder: snooze

If you’re in the groove of working but still want to be reminded again of a reminder that just occurred, you can use the snooze command!

snooze will snooze the most recent reminder for a duration of time (5 minutes by default)

BeforeSnoozeCommand

And ELISA will remind you again once it’s time!

AfterSnoozeCommand

More specifically the format of this command is: 'snooze [INDEX] [-s SNOOZE_DURATION]'

  1. This snoozes a reminder.

  2. The index refers to the it’s index in the reminder list.

  3. If an index is not provided, the most recently occurred reminder will be snoozed.

  4. If a snooze duration is not specified, the reminder will be snoozed at the default duration of 5 min.

Here are some examples you can try out! * snooze 1 * snooze 3 -s 10.min.later * snooze -s 10/10/2020 1400

  1. It is possible to snooze the same reminder multiple times if you wish.

  2. It is not possible to snooze (without specifying index) if no reminder has occurred yet.
    However, if you use the snooze command incorrectly, ELISA will first attempt to correct your usage of the snooze command.

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.

Commons represents a collection of classes used by multiple other components. The following class plays an important role at the architecture level:

  • Item : Used by classes to represent a task, event, reminder or any combination of the three.

  • Task : Used by classes to store, access and modify details regarding tasks.

  • Events : Used by classes to store, access and modify details regarding events.

  • Reminders : Used by classes to store, access and modify details regarding reminders.

  • LogsCenter : Used by many classes to write log messages to the App’s log file.

ItemClassDiagram
Figure 1. Class Diagram of the Item
  • An Item can contain an task, event or reminder. However it must contain at least one of the three.

  • The ItemBuilder class ensures the validation of the above rule when build() is called..

  • An Item is immutable in order to support thread safety.

  • An Item is created via the ItemBuilder class.

  • Setter methods of Item create a new Item through ItemBuilder to ensure immutability.

Add Reminder feature

Step 1. The user enters the command "reminder John’s Birthday -r 3.day.later".
Step 2. The LogicManager creates an ELISAParser to parse the user input.
Step 3. ELISAParser creates a AddReminderCommandParser which parses the input and returns an ReminderCommand.
Step 4. LogicManager will execute the ReminderCommand. AddCommand will then invoke ItemModel#add(Item), which adds the Item that contains the reminder to the RemindersList and the futureRemindersList.
Step 5. Each time an Item is added to the futureRemindersList, the Items in futureRemindersList is sorted according to the occurrenceDateTime of its Reminder in order of recency.
Step 6. AddCommand will also trigger a change in view by calling ItemModel#setVisualList(taskList)
Step 7. Upon the successful execution of AddCommand, a CommandResult is returned to the LogicManager, which will then be returned to the Ui to render the appropriate view.

When the application is launched, the LogicManager also creates a separate thread using the ScheduledThreadPoolExecutor that constantly runs checkTask every 5 seconds.
CheckTask is a runnable that monitors the ItemModelManager to see if there are any reminders in futureRemindersList that have an occurrenceDateTime after LocalDateTime#now().
If there is, it transfers those reminders to activeRemindersList which is an ObservableList.

Meanwhile, the MainWindow binds a listener activeRemindersList in order to observe if any Items with Reminders have been added to it.
If so, it will add ReminderDialogBox with the appropriate details for the added Items to the resultDisplay.

Snooze Reminder feature

We can see how snooze is performed through the activity diagram below.

SnoozeActivityDiagram
Figure 2. Activity Diagram to snooze a reminder

From the image above, we can see that there 2 guard conditions.
The first checks whether there is a reminder to snooze (either via an index or recently occurred reminder). If there isn’t, an exception is thrown.
The second checks if the newReminderOccurrenceIsValid (i.e. reminder does not occur in the past). Otherwise, it throws an exception.
If the duration of the reminder is not specified, then the default duration for the snooze is 5 minutes.