This page serves as my CS2103T project portfolio page on project Typee. The following software were used in the development of Typee application:
Overview
We are a group of 5 NUS Computer Science students involved in enhancing a basic command line interface (CLI) desktop application that manages addresses for our Software Engineering project. We chose to morph it into an appointment management application called Typee.
Typee is a CLI application that allows secretaries and receptionists to better schedule and manage appointments. Receptionists and secretaries possess one of the fastest typing speeds and would get increased productivity using the CLI-based Typee. The CLI application boosts productivity by having a comprehensive appointment management system with interactive parsing, calendar view, pdf report generation, as well as a typing game.
The sections below will cover the following:
-
Summary of contributions
-
Contributions to User Guide and Developer Guide
Summary of Contributions
This section will give you a brief overview of my contributions to the project. This section will be split into Major Enhancement, Major Enhancement, Other Contributions and Code contributed sub-sections. |
|
Major enhancement: added Interactive Parsing
-
What it does: - Interactive parsing allows the users to interact with the application to enter commands. This feature makes it possible for users to enter arguments to commands sequentially, instead of entering the entire command in one shot.
-
Justification: - Interactive parsing is a crucial feature that allows new and amateur users to get accustomed to the application. For example, the
Add
command has 7 parameters that the user must know to invoke. Interactive parsing makes Typee prompt the users for the correct input, step by step, to ensure that they don’t have to remember the command format. This feature is also versatile because experienced users can still enter the full/partial command in one shot, if they remember the format of the command or parts of it. -
Highlights: - This feature required me to replace the entire
Parser
package that was in present inAddressBook 3
. I was pushed to the boundaries of my knowledge and had to adhere to good design patterns to re-implement the package. -
Depth - Interactive Parsing is a very deep feature. Each command’s parser is a fully implemented finite state machine with a state for each parameter of the command. Moreover, the interactive parser’s design conforms to the state pattern documented by the Gang of Four. This necessitated skillful use of abstract classes, interfaces and polymorphism.
-
Completeness - Users can:
-
enter the arguments of a command step-by-step
-
enter the entire command in one shot
-
mix both worlds and enter a partially completed command with some, but not all arguments
-
switch tabs in between commands
-
-
Effort - The entire
Parser
package required extendingArgumentMultimap
, along with the creation of several state machines, each with one or more states. This feature necessitated a few thousand lines of code to be written. Moreover, care was taken to develop theParser
such that future developers can easily add parsing for newCommands
.
Minor enhancement: added add
command
-
What it does: - Adds an appointment, meeting or an interview at the specified time-slot and venue.
-
Justification: - Secretaries and receptionists primarily manage engagements. The first step in managing engagements is to be able to add them. This feature is crucial in managing engagements effectively and efficiently.
-
Highlights -
-
This enhancement required implementing a new
Engagement
package to functionally replace thePerson
package from AB3. -
An engagement that clashes with another existing engagement will not be addable.
-
Due to the nature of the class
AttendeeList
, Java’s Stream API was utilized in several methods.
-
-
Depth - A new package,
engagement
had to be created for this feature.Engagement
has 7 fields, which necessitated the creation of 7 classes to encapsulate the information. Along with the creation of the classes, engagement conflict checking was implemented. -
Completeness - In order to complete this feature, an entire overhaul of the
Storage
package, including the Json format was necessary. This was done along with refactoring of several other components ofModel
. Last but not least, theUi
had to be tweaked to accommodate the display of engagements in place of addresses. -
Effort - Implementation of this feature demanded refactoring of four components, namely
Model
,Storage
,Ui
andLogic
. Carrying out the aforementioned changes was an elaborate, demanding and structured process.
Other Contributions
-
Project Management
-
Managing Issue Tracker
-
The following issues link displays the issue trackers I managed.
-
-
Managing milestones
-
The following milestone link displays the milestones I managed.
-
-
Community
-
PR Reviews:
-
The following links Typee PR MoneyGoWhere PR display the pull requests I have reviewed.
-
Code contributed
-
The following reposense link displays my code contribution.
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. |
Interactive Parsing
About
Typically, engagement managing software require users to enter the entire command in one shot.
For example, a user that wishes to add a meeting must type out the following: -
add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
This can prove to be rather tedious and cumbersome as users must remember every detail of a command.
Typee overcomes this by allowing users to interact with its interface and build commands sequentially. Users just need to type the relevant command word to get prompted about subsequent inputs.
With interactive parsing, the aforementioned 'Add' command reduces to the following sequence of inputs: -
add
t/meeting
s/16/11/2019/1500
e/16/11/2019/1600
l/Meeting Room 2
d/Team Meeting
a/John | Smith
p/High
add
Experienced users that have a grasp of the structure and format of various commands can also benefit from this feature. Interactive parsing allows multiple arguments to be input simultaneously, as long as the entered arguments adhere to a set of rules detailed in a later subsection.
The same 'Add' command can be constructed this way by a fairly experienced user: -
add t/meeting
s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2
d/Team Meeting
a/John | Smith p/High
add
.Finally, a highly experienced user can create an 'Add' command in the conventional manner, i.e. by typing out
the entire command at once. This is identical to the format introduced in the beginning of this section: -
add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
Supported Commands
All commands are parsed and built interactively. Each command, however, adheres to its own structure. Individual commands' structures and idiosyncrasies are detailed in the sections belonging to the respective commands.
In general, commands are of two types - static and dynamic.
At any point of time, the user can enter // current
to view the current input constraints and
input // clear
to stop parsing the current command. These are examples of dynamic commands.
Static commands are executed one at a time, whereas dynamic commands can be built at any point of time, even while parsing an ongoing static command.
Examples:
'Add' and 'Delete' are static commands. The following input sequence is invalid: -
add t/meeting
delete
'Help' and 'Exit' are dynamic commands. Therefore, the following input sequence is valid: -
add t/meeting
help
s/11/01/2019/1500
exit
Calling another dynamic command in the midst of building a Tab command will erase the details of the command preceding
'Tab'. This happens if the command preceding Tab isn’t fully built.For example: add t/meeting tab // current b/calendar will erase the information of the add command.
|
Valid Input Sequences
Valid input sequences can be one of three types.
-
One argument per input -
add
t/meeting
…p/high
-
Entire command in an input -
add t/meeting s/11/01/2019/1600 … p/High
-
More than one argument, but not the entire command in an input -
add t/meeting
s/11/01/2019/1600 e/11/01/2019/1700
…
After the last argument is specified, the required command is built and executed, carrying out the operation intended by the user.
The order of arguments entered is important. Consider the 'Add' command. The ideal ordering is as follows: -
add t/ s/ e/ l/ d/ a/ p/
When users resort to any of the three aforementioned forms of supplying arguments, they are required to conform to the specified ordering.
When the arguments aren’t in order, then the input is parsed as far as possible, in the expected order of the arguments.
For example, add t/meeting l/Meeting Room 2
is parsed till the argument for t/
. The parameter location is deemed
invalid and the user is prompted to enter a start date-time.
This happens because the parser expects an argument for s/
, but there is no such argument.
As a consequence, all arguments that are supposed to be entered after s/
(like l/
) are not parsed.
add t/meeting l/Meeting Room 2
.Similarly, add t/meeting s/15/01/2019/1500 d/desc p/low
is parsed till s/
and a prompt is raised to enter a valid end date-time, leaving d/
and p/
untouched.
add t/meeting s/15/01/2019/1500 d/desc p/low
.
There lies a quirk with respect to the ordering of inputs if the parser has sufficient arguments. Consider the case when the user inputs add t/meeting e/15/11/2019/1500 s/15/11/2019/1400 . This input is deemed valid even
though e/ and s/ are flipped. This is because after 't/', the parser expects to find an s/ , which is in-turn contained in the input.
|
Thus, to summarize, the parser continues parsing in the order of the expected arguments, as long as the corresponding prefixes are found in the input.
Erroneous Inputs
Erroneous inputs occur in three mutually exclusive categories.
-
Inputs with invalid arguments
-
Inputs with multiple arguments for the same parameter.
-
Inputs with valid arguments, but irrelevant additional arguments.
An example of the first case is as follows: add t/teeming
. "Teeming" is an invalid engagement type. Typee flags this inaccuracy
and prompts the user to enter an acceptable engagement type instead. Since Typee has already begun building an 'Add' command,
the subsequent input must begin with t/…
Attempting to replace the argument for a parameter or supply different arguments to the same parameter will result in Typee rejecting the user input.
For example, the input add t/meeting t/interview
will be rejected.
The following sequence will also be rejected since it attempts to overwrite an argument.
add
t/meeting
s/15/11/2019/1500
t/interview
Last but not least, Typee will reject cases wherein the user supplies excessive and irrelevant arguments.
add t/meeting s/16/11/2019/1600 e/16/11/2019/1700 l/COM-1 d/Meeting a/Damith p/High o/High
will be rejected because o/
is not a parameter for the 'Add' 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. |
Interactive Parsing
Overview
Interactive parsing allows users to build a command sequentially, as opposed to doing it entirely in one shot. A user that wishes to
add an interview can simply type add t/interview
to receive prompts on what to enter next.
This feature was conceived to make the application easy to use for amateur users.
Design & Implementation
Important Classes:
-
InteractiveParser
- The interface exposed toLogicManager
. The parser implements this interface. -
Parser
- A concrete implementation ofInteractiveParser
that enables interactive parsing. -
State
- An abstract class that represents the individual states the application can be in while parsing and building aCommand
. -
EndState
- An abstract class that extends fromState
. Represents the finalState
of a parsed command, from which aCommand
object can be built.
The interface InteractiveParser
is the connecting interface between the LogicManager
and the main Parser
. This interface is
designed by contract (DbC - proposed by Bertrand Meyer). The interface exposes four methods to the LogicManager
, namely:
-
parseInput()
- Parses the entered input. -
fetchResult()
- Returns the response to be showed to the user in aCommandResult
object. -
hasParsedCommand()
- Returns true if theParser
has finished parsing aCommand
fully. -
makeCommand()
- Makes and returns theCommand
the user intends to execute.
To achieve interaction, the Parser
keeps track of the State
of the current Command
being built. State
is an abstract class that represents
the individual states the application can be at in the midst of building a Command
. EndState
is an abstract class that extends from State
,
from which Command
objects can be built. As and when valid inputs are entered, the Parser
updates
the current State
to the subsequent States
of the corresponding Command
.
The Parser
starts at an idle, inactive State
Upon entering add t/meeting
, the State
being tracked is changed twice - first
to the State
corresponding to the type of the Engagement
and then to the State
responsible for the start date-time.
Such State
changes happen sequentially until all the arguments necessary for the Command
have been supplied. When all necessary arguments are present,
the State
being tracked transitions into an EndState
. Once the tracked State
transitions into an EndState
, the Parser
builds the Command
which is executed by the LogicManager
.
The structure of the interactive parser is detailed in the UML diagram below.
State
.
The above diagram only shows the component of the package State that handles the PdfCommand . The other packages have been
omitted for brevity.
|
Parsing of user entered inputs can be viewed as parsing a small, finite context-free language. The command built by a sequence of inputs
is uniquely determined by the sequence of inputs entered by the user and happens to be deterministic.
This observation allows the Parser
to be modeled by a finite state machine. A finite state machine is an
abstract computational model which consists of a machine comprising several states. At a particular point in time, only one state
of the state machine is active. The machine transitions from one state to another state if certain conditions are met.
In the context of Typee’s Parser
, the parser of each individual Command
is a distinct finite state machine. The condition to be
satisfied to transition to another state is the validation of user-entered inputs.
The incorporation of state machines into the Parser
is done by implementing a slightly modified version of the state pattern
documented by the Gang of Four (GoF).
Upon initiating the parsing (building) of a Command
, the state machine that corresponds to the required Command
is instantiated and set
to its initial state. This state becomes the State
tracked by the Parser
Subsequent inputs are tokenized by the ArgumentTokenizer
class,
processed by the InputProcessor
class and forwarded to the current State
. If the input is deemed valid, the Parser
invokes the transition()
method of the current State
to proceed to the next State
. This process is repeated until an EndState
is reached. Throughout this process, the
user receives feedback from the Parser
in the form of an encapsulated CommandResult
object.
Below is a sequence diagram illustrating the processes that occur when the user enters add t/meeting s/15/11/2019/1500 e/15/11/2019/1600
.
Parser
parses the entered input and returns the result to the GUI in the form of a CommandResult
object.
The sequence diagram incorrectly extends the life-line of the three destroyed State classes. This is due to a limitation of PlantUML.
|
The high-level working of the Parser
can be summarized by the activity diagram shown below.
"parameter present" refers to the parameter required by a particular state. |
Design Considerations
Aspect : Abstract model
-
Alternative 1 (current design) : Finite state machine
-
Pros:
-
Highly flexible - Entire command, one argument at a time and multiple arguments at a time - all are supported.
-
Easily extensible - Adding a new command will require almost no changes in any of the existing classes.
-
Supports optional arguments with the help of the
OptionalState
interface.
-
-
Cons:
-
Tedious to implement a state machine for each individual command.
-
-
-
Alternative 2 : Use a list based implementation to keep track of arguments entered.
-
Pros:
-
Easy to implement and keep track of arguments
-
-
Cons:
-
Very hard to implement optional states.
-
Cannot execute commands like
Help
at any point in time without hard-coding it in theParser
.
-
-
Use case: (UC01) Add appointment
MSS
-
User requests to add an appointment.
-
System adds the corresponding appointment to the existing appointment list.
-
System displays the updated appointment list and notifies the user.
Use case ends
Extensions
-
1a. User supplies the necessary information.
Use case ends
-
1b. User supplies invalid information.
-
1b1. System notifies user about the invalid information.
Use case ends
-
-
1c. Appointment clashes with an existing appointment.
-
1c1. System notifies user about the conflict.
Use case ends
-