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:
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 thegenerate
command by recording members' schedule. ThesetTimetable
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 thesetTimetable
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 commandgenerate
.
-
-
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
andsetTimetable
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:
-
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]
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.
-
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.
-
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!
setTimetable
command successEven if you accidentally entered a wrong URL, MyProject would prompt you helpfully! |
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
oraddMember
-
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.
-
Step 2: Enter the command with your desired duration of the meeting, and the time range to generate within
generate
command-
Step 3: Press enter, and you will see the following result:
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 |
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:
-
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
-
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:
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.
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-outProject
-
desiredMeetingDuration
: How long the meeting would last in hour, expressed as a positive integer -
restrictedTimeRange
: Sets the limit of generatedTimeRange
, 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 allTimetable
supplied. Returns a list ofTimeRange
, or an empty list ofTimeRange
if no such timeslot is available. -
TimeSlotGenerator#generateWithMostMembers()
— Generate timeslot where most members of the currently checked out project are available. Returns a list ofTimeRange
.
This feature depends on the timetable stored internally as an attribute of each members:
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:
As shown in the sequence diagram above, the command execution would go through the following stages:
-
Fetch the data of members in the current project and pass them to the
TimeSlotGenerator
. -
TimeSlotGenerator
will extract their timetable and generate all possibleTimeRange
. -
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
:
generate
command tries to provide best possible meeting timeslotAlgorithm Used
TimeSlotGenerator#generate()
-
Combine all the given
Timetable
into a singleList<TimeRange> combined
-
combined
is then processed further by merging overlappingTimeRange
into a singleTimeRange
. E.g.TimeRange(MONDAY, 1000, MONDAY, 1200)
andTimeRange(MONDAY, 1200, MONDAY,1400)
are merged together to form a singleTimeRange(MONDAY, 1000, MONDAY, 1400)
.List<TimeRange> merged
is then passed on to the next stage. -
merged
is then inverted, and returnsList<TimeRange> inverted
containing all timeslots where all the members are free. -
inverted
is then processed to ensure that allTimeRange
falls withinrestrictedTimeRange
specified by the user, truncating allTimeRange
that extends beyond the specifiedrestrictedTimeRange
, returningList<TimeRange> truncated
. -
The algorithm then filters
inverted
by rejecting allTimeRange
that last shorter thandesiredMeetingDuration
specified by the user. ThisList<TimeRange> accepted
is then passed back to the caller of this method, and the algorithm terminates.
TimeSlotGenerator#generateWithMostMembers()
-
Iterates over all possible combinations of timetables in descending order of number of timetable.
-
For each possible combination, call
TimeSlotGenerator#generate()
. -
If
TimeSlotGenerator#generate()
returns an empty list, repeat step 2 again. -
Algorithm terminates, returning the combination of List<Timetable> used and available timings
List<TimeRange>
wrapped in a classTimeSlotWithMember
.
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.