Overview
BBProductive is built upon a brown field project titled AddressBook. It was done for the purpose of a software-engineering module, CS2103T with a team of 5 other students. We decided to implement a task manager and a productivity application combined in one. Apart from the standard create, read, update and destroy capabilities of a task manager, BBProductive includes a “Pomodoro” timer [25 minutes work, 5 minute rest] to help users perform manageable work cycles. BBProductive also has a virtual pet that grows and changes in appearance depending on how much work the user has done. The pet serves to complement the pomodoro features by providing an incentive for users to work.
Summary of contributions
-
Major Enhancement: Auto complete feature.
-
What it does: When typing, users can press tab to autocomplete command words or add prefixes specific to the command. It also removes invalid indexes for done/delete commands.
-
Justification: As we are targeting fast typists, auto completing and allowing users to write faster would definitely be a big plus to our users.
-
Highlights: I’ve decided to provide some additional visual feedback to users depending on the outcome of the auto complete. Given that it’s a separate mechanism from the commands itself, I decided to add additional text coloring to the command input field and result display to differentiate auto complete success/warning/error from command error feedback.
-
-
Major Enhancement: Sort by multiple fields feature
-
What it does: Sorts the tasklist by multiple fields {name, priority, done, reminder}
-
Justification: Most task managers have a sorting function so that users are able to see what’s more important to them at the front.
-
Highlights: We’ve provided multiple fields to sort by so that users can have a more specific ordering. On the same thread, we’ve decided to provide reverse sorting orders as well.
-
-
Major Enhancement: Enhanced find command
-
What it does: Rather than the original exact fit matching, we’ve decided to expand it to be more flexible. Now Tasks names whose start matches the search term or that has some typos will be recognized by the find command. Also we’ve added searching by tags.
-
Justification:Typing often leads to typos, so we’ve decided to enhance the finding command so that users will be able to find tasks they want to look for with some error boundary. We’ve also allowed the find command to show tasks that have names who’s start matches the keywords.
-
i.e.
find tuto
⇒ a task with nametutorial 1 CS2106
will be shown
-
-
Highlights: We used a popular Dynamic programming approach that implements the Levenshtein distance algorithm to achieve a faster run time for scalability purposes.
-
Code contributed for this: #300
-
-
Minor Enhancement: Worked on migrating Address Book features to Task list features
-
Changed fields like address, phone number to description and priority Added Done field
-
Code contributed for this: #85
-
-
Minor Enhancement: added for done and delete commands for mulitple indexes
-
Allow users to mark several tasks as done or to delete several tasks in one command
-
Code contributed for this: #73
-
-
Minor Enhancement: Added Json classes and baseline models for Pomodoro and Pet features for other members to expand on
-
Helped other members create baseline models for their features and linked it to JsonAdapted classes for storage purposes. Also modified JsonAdaptedTask to fit the new Task model.
-
Code contributed for this: #85
-
-
Minor Enhancement: Worked on the css styling and java FXML for the revamped BBProductive look
-
Made new grid layout of tasks displayed, added margins. Added priority display.
-
Code contributed for this: #145
-
Other Contributions:
-
Dev Ops
-
Set up team github repo
-
Set up Travis CI to perform Continuous Integration on our project
-
Set up auto binding of project website
-
Set up auto formatting with pre-commit git hook with googleJavaFormat
-
-
Contributions to team:
-
Project management:
-
Managed releases
v1.3
on GitHub
-
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. |
TaskList (Branson)
Task Fields
Use add
and edit INDEX
attached with any combination of the following task field prefixes to perform them. These prefixes can be in any order.
Constraints for fields are italicized in the Notes column. |
Field | Format | Notes |
---|---|---|
Name |
|
|
Description |
|
|
Priority |
|
|
Reminder |
|
|
Recurring tag |
|
|
Tag |
|
|
Done |
No prefix available |
|
Add Command
Command: add n/This is a new task p/3 des/We have alot of work to do today! t/This t/Is t/Fun
Alright, time to start your productivity journey! Let’s add our very first task by using the command stated above.
When adding tasks, you only need the n/ prefix as only the name field is compulsory.
.Add success
|
Edit Command
Command: edit INDEX n/Look edited the task des/BB Productive is the best app I’ve ever used t/NewTag
Made a mistake when adding your task? don’t worry you can always edit your tasks! But first, a few things to take note of:
|
Done Command
Command: done INDEX INDEX…
After some hard work, you have finally finished a task! Let us now mark it as done by using the done command. You can also mark multiple tasks as done by using space to separate the indexes.
Sort Command
Command: sort FIELD FIELD…
Oh boy, after a couple of hours, you have filled your day with so many activities! You can choose to change the current ordering of your task list to something more suitable by sorting it by one or more of these task fields:
All fields with r- prepended refers to a reverse of the original. |
-
priority → Shows task of highest priority first.
-
r-priority → Shows task of lowest priority first.
-
done → Shows undone tasks first.
-
r-done → Shows done tasks first.
-
date → Shows tasks with reminders closer to today first then tasks without reminders.
-
r-date → Shows tasks with no reminders first then tasks with reminders further from today.
-
name → Shows tasks in alphanumeric order.
-
r-name → Shows tasks in reverse alphanumeric order.
Sort order is removed after any find command is applied. |
Find Command
Command: find PHRASE t/TAG…
Even after sorting, you still have so many tasks in your tasklist. You can perform a search for tasks by name or tag to find the tasks most important to you.
-
You can choose to search by both name and tag, just name or just tag.
-
For phrase searching, it is tolerant to typographical errors and will show tasks that differ from the
PHRASE
by a little. -
However, tag names provided must be an exact match (ignoring casing of letters).
Filtered selection is unapplied when the |
Tag Command
Command : tag
Wondering what types of tasks you have? You can view all existing tags in BB Productive by entering the Tag command!
Delete Command
Command: delete INDEX INDEX…
Tasklist getting overcrowded? Use the delete command to delete one or more tasks To clean up your tasklist!
Clear Command
Command: clear
It’s been a productive month and you want to start on a clean slate. You may delete all tasks from your list by issuing a clear command.
AutoComplete (Branson)
As much as you enjoy typing, we’ve added some extra grease to help you type even faster. You can trigger our intelligent autocomplete function by pressing tab
on the keyboard.
You can expect:
-
Auto completion of command words:
del → delete
-
Addition of prefixes for common values:
20/10/20@10:30 → r/20/10/20@10:30
-
Auto completion of sort fields
sort pri
→sort priority
-
Removal of indexes that are invalid [not a positive integer or out of the tasklist’s size]
-
If we can’t find a valid command, you will observe feedback like below:
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. |
Sort
The sort order is not maintained after the application closes |
Implementation
API : SortCommand.java
The sort command takes in a list of fields and generates FieldComparators as seen in the diagram and then uses Comparator.thenComparing to aggregate the comparators. The first field provided will be of the highest sort order. The Model
will then set the aggregated comparator on the TaskList
.
We use a new SortedList
from JavaFx within TaskList
because FilteredList
does not allow for sorting. As such we have the FilteredList
reference the SortedList
and the SortedList
refernce the UniqueTaskList
. By warpping the lists around another, this allows the SortedList
and FilteredList
to read changes to the UniqueTaskList
and perform the appropriate filtering and sorting.
Due to the requirements mentioned, this is how we generate our FilteredList
. We set FilteredList
to reference the SortedList
and then the SortedList
to reference the UniqueTaskList
.
Updating UI
Meanwhile to update the UI on the newest sorting order, the latest sortOrder is set on the TaskList
. The LogicManager
is then able to access the sort order from the TaskList
throgh the Model
and provide the MainWindow
with the sort order. The MainWindow
then sets it on the TaskListPanel
.
AutoComplete
Auto complete is triggered when users press tab while focussed on the command line.
Implementation
API : CommandCompletor.java
When a user presses tab on the command line, a key event handler in the CommandBox
calls the suggestCommand function of MainWindow
with the user input. The MainWindow
then passes the user input through the LogicManager
to the CommandCompletor.
The input is pass through the LogicManager
so that we can get TaskList details from the LogicManager
and transfer it to the CommandCompletor (e.g. taskList length). The CommandCompletor then parses the input and returns one of three things which lead to different changes to the UI:
-
CompletorResult
-
Will cause
CommandBox
to setSuccess onCommandTextField
-
-
CompletorDeletionResult
[inherits fromCompletorResult
]-
Contains deleted input which will be shown as feedback
-
Will cause
MainWindow
to call setWarning onResultDisplay
-
-
CompletorException
-
Will cause
CommandBox
to setFailure onCommandTextField
-
Auto Complete Overview
Auto completion of a word happens when either:
|
The above diagram provides a big picture overview of decisions CommandCompletor
goes through when processing user input.
-
It attempts to complete the command word as in the callout above
-
if command word is unrecognized,
CommandCompletor
throws aCompletorException
which leads to Unknown Command UI -
else it performs argument checks and auto completes as necessary
-
Argument checks overview
-
If the input is an add/edit/pom command then
CommandCompletor
will attempt to add prefixes.-
add/edit command → add priority and reminder prefixes
-
Edit auto complete will only add prefixes after the second word to avoid adding a prefix to the compulsory INDEX field of edit commands
-
-
pom command → add timer prefix
-
-
If input is a delete/done command
-
remove any invalid indices that are greater than the length of the displayed task list or that are not a positive integer
-
-
If input is a sort command
-
Auto completion of fields is performed based on the criteria
-
If the field is not recongized, then it is removed
-
Auto Complete output:
As seen from the activity diagram above:
-
Known Command UI is displayed when:
-
Any kind of completion has happened or nothing has changed for the input
-
CompletorResult
is returned
-
-
Any input is deleted (invalid index or sort field)
-
CompletorDeletionResult
is returned
-
-
-
Unknown Command UI is displayed when:
-
Command word provided is not recognized
-
CompletorException
is raised
-
-
Known Command UI
-
CommandTextField
is set to green -
CommandTextField
text is replaced by the suggested command -
Feedback is also provided on what changes have been made
-
If input has been removed,
ResultDisplay
is set to orange
-
Unknown Command UI
-
CommandTextField
is set to red -
CommandTextField
text is unchanged -
Feedback is provided that command word is not recognized
Prefix Completion
Here we take a closer look at how prefix completion is implemented. We iterate through every word of the user’s input and then check if the word is a valid task field. If it is, we append the prefix and update the hasPrefix boolean to true so that we don’t append duplicate prefixes. The input is then updated and we continue iterating.
Index Completion
Similar to before, we iterate through the arguments and we remove indexes that are either out of the displayed TaskList
size or that is not a positive integer. We then append it to a removed list so that we can inform the user what input has been removed.
Sort field Completion
Sort field completion is done by iterating through all arguments word by word and performing the auto complete checks against all possible sort fields. The auto complete checks were the same as the above criteria.
Enhanced Find
We’ve built upon the existing find function in AB-3 to filter tasks based on phrases (with some degree of typing errors) and based on task tags.
The filtered list is not maintained after the application closes |
Implementation
API : FindCommand.java
-
After setting the predicate on the model and
FilteredList
, theFilteredList
will apply the Test method of the predicate.-
The test method calculates a score for every task and only displays tasks with score < 2.
-
-
A comparator is then retrived from the Predicate by comparing Tasks based on their score and is used to sort the filtered list to show the more relevant searches first
-
Lower scores means a more relevant task to the search term.
-
Tasks with lower scores will preceed those with higher scores based on the comparator.
-
Any existing comparator set by previous sort commands is replaced by the find command’s relevance comparator. |
Predicate
Scoring decision
The score is first initialized to 2 and is later replaced by name score if the name score is lower than 2. We then subtract tag score from it to get the final score.
Name scoring
Please refer to the above’s name score group
-
The name score of a task is the minimum score of all chunks of a task.
-
A chunk is a String subsequence of the task name that has the same number of words as the search term.
-
-
We iterate through all chunks of the task name and calculate a score for each chunk.
-
Here is how we set the score for each chunk:
-
edit distance between one of the chunks and the search term < 2, chunk score is set to 1.
-
search term matches the start of one of the chunks, chunk score is set to 1.
-
one of the chunks is the same as the search term, chunk score is set to 0.
-
else chunk score is 2.
-
-
We then get the minimum of these chunk scores.
Tag scoring
For every tag in the search term that appears in a Task, we increment the tag score by 1.
Final score
final score = name score - tag score. Search results are displayed in ascending order of final score.
Design considerations
-
The idea is to first ensure that tasks that are too different are not shown while allowing some degree of typo error on the user’s end when searching for a task.
-
This is supported by the use of edit distance and a small threshold.
-
-
Next we also wanted the user to be able to find a task name without searching the full name.
-
We show tasks who have a chunk who’s start matches the search term.
-
-
We also wanted to allow users to search by tags.
-
Thus tag score is introduced.
-
-
While the score helps to determine which tasks to show, it serves another job in providing the search relevance so that while accommodating for some degree of error from user input, they are still seeing what’s more relevant first.
-
Users can also narrow their search by performing find with more tags or a more complete task name so that only that task has a chunk that matches.
-
-
We chose to not use edit distance for search terms of string length less than 3 as this would bring about alot of false positives given that that the edit distance between words of length < 3 will easily be 1.
Glossary
Term | Detail |
---|---|
Mainstream OS |
Windows, Linux, Unix, OS-X |
A time management method developed by Francesco Cirillo. Traditionally, cycles of 25 minutes of work and 5 minutes of rest. |
|
A snippet of text specified by the user that can be tracked (done/time spent). |
|
A cute little companion whom the player can care for and accessorise with more tasks being done. |
|
CLI |
Command Line Interface - a typing interface which is used to interact with the application |
Command |
Executes user input in the application |
CommandBox |
UI component that takes in user input |
ResultDisplay |
UI component that displays the feedback to the user |
FXML |
XML-based user interface markup language for defining user interface of a JaxaFX application |
TaskListCard |
UI component that displays information on an item |
TaskListPanel |
UI component that displays list of items |
JavaFX |
Software platform for creating and delivering desktop applications and rich Internet applications |
JSON |
An open-standard file format that uses human-readable text to transmit data objects consisting of attribute–value pairs and array data types |
Logic |
Handles user input for the application and returns the application’s output |
MainWindow |
Provides the basic application layout containing a pet and CLI sidebar and a task list interface with pomodoro timer |
Model |
Represents and exposes data in the task list, pet, pomodoro and statistics |
Parser |
Converts user input into a Command object |
ReadOnlyTaskList |
Provides an unmodifiable view of a task list |
Storage |
Manages data of the pet, pomodoro, tasklist and statistics in local storage |
Edit distance |
Integer calculated with the levenshtein distance that represents the number of changes to get from one string to another |