Introduction to the project

My team of 4 NUS SoC students and I were tasked to enhance a command line addressbook application. We decided to convert it into a one-stop project management app called MyProject.

MyProject is meant to aid NUS students in managing multiple projects within a single desktop application that can fufill all their needs.

Aside from basic features such as setting of tasks and deadlines, MyProject also boasts several tools to aid users in better managing their projects. Notable features include:

  • Keep track of members' progress

  • Send out email reminders

  • Record meeting minutes

  • Track project budget

  • Generate meeting timings (My Contributions)

This is what our project look like:

Ui
Figure 1. Graphical User Interface for MyProject

This document serves to record down my contributions to the project in detail.

Summary of contributions

Enhancement: Implemented setTimetable and generate command. setTimetable records down a member’s schedule, while generate suggests timings to schedule meetings on.

  • What it does:

    • The setTimetable command is primarily used to support the generate command by recording members' schedule. The setTimetable command is made extremely convenient for NUS students due to our integration with NUSMods timetable sharing feature, allowing users to simply input a NUSMods timetable sharing URL, instead of having to enter all the timings manually.

    • The generate command suggest the most suitable timeslots to schedule project meetings on, based on the timetable of members added using the setTimetable command.

  • Justification

    • Team leaders often have trouble scheduling team meetings, having to run to every single members and ask for their availability at a certain timeslot. This process is often time consuming and inefficient. With this enhancement, team leaders can avoid this issue entirely by simply entering a database of team members' timetables into MyProject using the command setTimetable, and generate meeting timeslots using the command generate.

  • Highlights

    • I tried to make this enhancement to be very convenient to use, with only 2 commands required for this functionality to work. This led to the high variety of errors that the generate and setTimetable command can occur. As such, I had to provide a robust error catching mechanism to identify what the user did wrongly and provide suggestion on how to make the command work.

    • This enhancement was also challenging because the current Java data and time libraries do not fully address my needs for a weekly recurring type of timetable, thus I had to implement it myself, which proves to be more of a challenge than expected. However, this proved to be worth the time, as it forms the backbone of the entire enhancement. This allowed for my enhancement to be extremely extendable so that we can easily provide for more sources of input, such as input from .ics files.

  • Credits

    • Credits to the NUSMods team for provide such a comprehensive API to retrieve module information.

Code contributed: Click here to view a sample of my code.

Other contributions:

  • Enhancement to existing features

    • Update UI and README to better represent MyProject #181

  • Project Management:

    • Managed issue tracker

    • Release all software releases

    • Handled Travis integration on Github

  • Community:

    • Fix bugs introduced by other group members #17

    • Reviewed PR made by teammates #13

  • Tools:

    • Integrated Coveralls to the project to keep track of code coverage

Contributions to the User Guide

We had to provide a user guide as an instruction for how to use our software. The user guide consist of mainly different commands and the various arguments they take.

Below is the section of user guide that I contributed for my enhancement which describes the commands required for my enhancements to work.

Set a timetable: setTimetable

Need to keep track of your team members' schedule? Use this command to record down their timetable easily!

Timetable set can be used to generate available meeting timeslots using the command generate

Format:

setTimetable INDEX [n/NUSMODS_SHARE_URL] [f/FILEPATH_TO_TIMETABLE]

  • Assigns timetable to the person at the specified INDEX.

  • The index refers to the index number shown in the displayed person list using the command list.

  • The index must be a positive integer 1, 2, 3, …​

Example:

  • setTimetable 3 f//home/john/Desktop/aliceTimetable.txt
    Set Alice’s timetable to Alice, who has index 3 in the list of persons.

File should be formatted as a newline separated list of time ranges, e.g:
MONDAY 1000 MONDAY 1200
MONDAY 1400 MONDAY 1600
TUESDAY 1100 TUESDAY 1500
  • setTimetable 2 n/https://nusmods.com/timetable/sem-1/share?CS2100=LAB:05,TUT:02,LEC:1&CS2101=&CS2103T=LEC:G13&CS2105=TUT:03,LEC:1&CS3241=TUT:05,LEC:1&CS3243=TUT:01,LEC:1&GEQ1000=TUT:D27
    Set timetable to the person with index 2 on the list of persons, by retrieving timetable data from NUSMods.

Below is a step-by-step instruction to guide you through the process of setting a timetable to Alex, through the use of NUSMods:

  • Step 1: Type list and enter to view the list of persons. Identify the index of the person you wish to set the timetable to.

set timetable step 1
Figure 2. List of person in the application
  • Step 2: Type setTimetable, followed by the index of the person you wish to set the timetable to, and the URL of the share link.

set timetable step 2
Figure 3. User enters timetable of team member
  • Step 3: Press enter, and you would see the following message. You can even scroll down to view a simple visualization of the timetable set!

set timetable step 3a
Figure 4. setTimetable command success
set timetable step 3b
Figure 5. Visualization of timetable set
Even if you accidentally entered a wrong URL, MyProject would prompt you helpfully!
set timetable step 3 error
Figure 6. Error message when entered URL is invalid

Generate meeting timing: generate [Checkout]

Need to decide on a meeting timing, but having trouble finding a time where all members are free? This command can help suggest meeting timings!

  • Prerequisite:

    • Members have been assigned to the project using addFromContacts or addMember

    • Timetables have been assigned to the members with the command setTimetable

generate would not give an error if some members do not have timetable assigned to them. Ensure that you have done setTimetable for each of the members in the project before using generate.

Format: generate d/DURATION [r/TIMERANGE]

Example:

  • generate d/2 r/MONDAY 0900 MONDAY 1800
    Generates all possible meeting timeslots that lasts at least 2 hours, within the time frame of Monday 9am to Monday 6pm.

Below is a step-by-step instruction to guide you through generating a meeting timeslot that lasts for at least 1 hours, between Monday 1000 to Monday 1800:

  • Step 1: To generate a meeting timing for a project, you first need to checkout that project.

generate step 1
Figure 7. Timeslot will be generated for the checked out project
  • Step 2: Enter the command with your desired duration of the meeting, and the time range to generate within

generate step 2
Figure 8. Enter parameters for generate command
  • Step 3: Press enter, and you will see the following result:

generate step 3
Figure 9. Suggested timeslots shown on the GUI
If MyProject is unable to find a timeslot where all members are free, it would try to find another timeslot where most members are free
generate alt
Figure 10. Result shown when not all members are available. Members available would be listed.

Contributions to the Developer Guide

The developer guide is used by future developers for reference when they continue developing on MyProject.

The section below is the portion of the developer guide that I contributed to, which are directly related to my enhancement.

Timetable input

Description of Feature

This feature is used to input timetable data, which would then be used in the generate command to find a suitable meeting timeslot.

There are two ways to input member’s timetable:

  1. Member send a formatted text file to the team leader, which would then be parsed by the system. The file would be a list of newline separated time ranges

  2. Member send their NUSMods timetable URL to the team leader, and the system would parse the URL and fetch timetable data using NUSMods API

User command would be in the format: setTimetable INDEX m/member [n/NUSMODS_URL] [f/FILEPATH]

The main logic is implemented within the TimetableInput class, which is invoked by the SetTimetableCommand class.

Details

Important functions in TimetableInput:

  • TimetableInput#getTimetableFromNUSMods(Url url) — Parse URL and fetch timetable data using NUSMods API

  • TimetableInput#getTimetableFromFile(String filepath) — Parse file to obtain timetable data

Below is an overview of the classes related to time+table input:

SetTimetableClassDiagram
Figure 11. Class diagram for timetable input feature

setTimetableCommand accepts either a filepath or a URL, which is then supplied to TimetableInput to fetch the timetable data.

Afterwards, the timetable is passed into TimetableVisualization to provide a visual representation of the set timetable. This visualization is then passed back as a CommandResult to be displayed to the user.

The following sequence diagram illustrates what happens when the user issues the command setTimetable to add their timetable from a shared NUSMods timetable.

SetTimetableSequenceDiagram
Figure 12. Timeline of entire process from user executing their command to getting the result back.

Design Considerations

Aspect: How to input timetable
  • Alternative 1 (current choice): Input timetable by importing timetable from an already existing platform.

    • Pros: More practical and convenient for users to input, as opposed to manually typing in all the timetable for every single members.

    • Cons: Feature unreliable as it requires maintainance if the web API changes.

  • Alternative 2: Input all time ranges manually by user.

    • Pros: Very reliable due to lack of usage of online APIs.

    • Cons: Very impractical. Most users would not want to enter timetable data of all their members one by one, and would probably skip this feature.

We realized that it is very impractical to expect users to input timetable manually all by themselves. No matter how unreliable the web API is, the feature would at least be useful to users. If users have to manually input all the data, we cannot realistically expect this feature to be useful at all.

Generate meeting timeslot

Description of Feature

The timeslot generator is used to suggest meeting timings by making use of team members' timetable.

This feature makes heavy use of the class TimeRange, which represents a period of time in a week, e.g. MONDAY 1000 — MONDAY 1200.

The main logic of this feature is contained within the TimeSlotGenerator class:

Details

TimeSlotGenerator(members, desiredMeetingDuration, restrictedTimeRange)

  • members: List<Timetable> of members of the checked-out Project

  • desiredMeetingDuration: How long the meeting would last in hour, expressed as a positive integer

  • restrictedTimeRange: Sets the limit of generated TimeRange, e.g. restrict meeting to working hours, from MONDAY 0900 - MONDAY 1800

Only the two following methods are exposed:

  • TimeSlotGenerator#generate() — Generate timeslot suitable for all Timetable supplied. Returns a list of TimeRange, or an empty list of TimeRange if no such timeslot is available.

  • TimeSlotGenerator#generateWithMostMembers() — Generate timeslot where most members of the currently checked out project are available. Returns a list of TimeRange.

This feature depends on the timetable stored internally as an attribute of each members:

GenerateSlotClassDiagram
Figure 13. Class diagram of the TimeSlotGenerator

Typical usage of TimeSlotGenerator would be look like this:

List<TimeRange> availableTimeSlots = new TimeSlotGenerator(members, desiredMeetingDuration, restrictedTimeRange).generate()

The following sequence diagram shows the entire process of generating timeslot after the command generate d/2 is given:

GenerateSlotSequenceDiagram
Figure 14. Timeline of process from user entering the command to the results being displayed to the user.

As shown in the sequence diagram above, the command execution would go through the following stages:

  1. Fetch the data of members in the current project and pass them to the TimeSlotGenerator.

  2. TimeSlotGenerator will extract their timetable and generate all possible TimeRange.

  3. Display result for the user to view all the possible timeslots that a meeting can be held.

If generate() returns an empty List<TimeRange>, the program should automatically call generateWithMostMembers() and return it as result, informing the user that there is no timeslot where all members are available.

The following activity diagram summarizes the general flow of the command generate:

GenerateSlotActivityDiagram
Figure 15. generate command tries to provide best possible meeting timeslot

Algorithm Used

TimeSlotGenerator#generate()
  1. Combine all the given Timetable into a single List<TimeRange> combined

  2. combined is then processed further by merging overlapping TimeRange into a single TimeRange. E.g. TimeRange(MONDAY, 1000, MONDAY, 1200) and TimeRange(MONDAY, 1200, MONDAY,1400) are merged together to form a single TimeRange(MONDAY, 1000, MONDAY, 1400). List<TimeRange> merged is then passed on to the next stage.

  3. merged is then inverted, and returns List<TimeRange> inverted containing all timeslots where all the members are free.

  4. inverted is then processed to ensure that all TimeRange falls within restrictedTimeRange specified by the user, truncating all TimeRange that extends beyond the specified restrictedTimeRange, returning List<TimeRange> truncated.

  5. The algorithm then filters inverted by rejecting all TimeRange that last shorter than desiredMeetingDuration specified by the user. This List<TimeRange> accepted is then passed back to the caller of this method, and the algorithm terminates.

TimeSlotGenerator#generateWithMostMembers()
  1. Iterates over all possible combinations of timetables in descending order of number of timetable.

  2. For each possible combination, call TimeSlotGenerator#generate().

  3. If TimeSlotGenerator#generate() returns an empty list, repeat step 2 again.

  4. Algorithm terminates, returning the combination of List<Timetable> used and available timings List<TimeRange> wrapped in a class TimeSlotWithMember.

Design Considerations

Aspect: How to generate timeslot with most number of available members
  • Alternative 1 (current choice): Iterate over all possible combinations of timetables, sorted in descending order of number of timetables, and call TimeSlotGenerator#generate() on each of these combinations.

    • Pros: Easy to implement.

    • Cons: May have performance issues in terms of speed. This implementation takes O(2n) time for n members.

  • Alternative 2: Use a more sophisticated algorithm to shorten generation duration

    • Pros: Will be much more efficient

    • Cons: Harder to implement, and more specialize towards only doing a single task. Tough to maintain and adapt for other usage.

We went with options 1 as there is no real difference in speed if the number of members is restricted to below 15 members, which many projects do not normally exceed. It is much easier to understand and maintain by other developers as well.