Overview
The purpose of this portfolio is to document my role and contributions to project 3VIA. 3VIA is a desktop flash card application designed for self-driven learners to reinforce their knowledge. The main form of interaction with the application is via the keyboard. 3 notable features are learning, testing and reviewing. This is a team-based project. My main task was to implement a mass import feature. Additionally, my assigned role was to review the code quality written by each member which is done by reviewing each member’s pull request on Github.
Summary of contributions
-
Major enhancement: added the ability to import multiple cards.
-
What it does: allows the user to add multiple cards into 3VIA at one go.
-
Justification: This feature incentivizes non-existing users to use 3VIA more as the users can import their existing digital notes quickly.
-
Highlight: This enhancement allows grouping of multiple pairs of questions and answers under a set of topics. Thereby reducing the need to repeatedly tag each question and answer pair with the same set of topics.
-
-
Code contributed: [Functional code]
-
Other contributions:
-
Project management:
-
Conceptualized future releases.
-
Assigned roles and responsibilities to team members.
-
-
Enhancements to existing features:
-
Ported list and select functions from original AddressBook to 3VIA.
-
-
Documentation:
-
Updated storage class diagram for 3VIA.
-
-
Community:
-
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. |
Cram More Knowledge!: import
Quickly import multiple flash cards from existing notes or documents into 3VIA.
Format: import FILEPATH
Example:
The file path refers to either the absolute file path or the relative file path of the import file. |
Creating your import file:
Open your existing notes or create a new one. You may use any text editing programs such as Microsoft Word, Google Docs, etc. Below are 2 rules regarding the import file type and format that must be adhered too.
-
Import file type:
-
The file must be in UTF-8 format.
-
The file must be a plain text file (i.e. file.txt).
-
-
Import file format:
Keys | Purpose |
---|---|
SPACE + t + / |
A space and "t/" prefix separates each topic |
TAB |
A tab space separates a question and an answer |
⏎ |
A new line separates each card |
Duplicate questions in the import text file will result in an import failure. Duplicated answers with different questions are allowed. |
Importing your file:
Now that your file is ready, head over to 3VIA and lets begin the import.
-
Enter the
import
command followed by the absolute/ relative file path of the import file you previously created in the command box as seen below.
-
Hit enter/ return to confirm. 3VIA will now display a list of cards that has been imported.
You can edit or delete any of the recently imported cards and/or even undo the import if you are not satisfied
with the cards imported.
|
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. |
Mass Import Feature
Current implementation
The import mechanism allows the user to add multiple cards quickly into 3VIA. This is done by parsing an external file in a specified format and file type but with minimal syntax.
The import mechanism is facilitated mainly by ImportFile
and TriviaBundle
.
Additionally, the import mechanism implements the following operations:
-
ImportFile#parseFileToCard()
— Parses a plain text file into a unique list of cards. -
TriviaBundle#haveAnyCard()
— Checks if the cards to add contain any duplicated cards already inTriviaBundle
. -
TriviaBundle#addMultipleCards()
— Adds multiple cards into theTriviaBundle
at once.
The 2 TriviaBundle
operations are exposed in the Model interface as
Model#haveAnyCard()
and Model#addMultipleCards()
respectively.
The following activity diagram summarizes what happens when a user executes the import command.
Given below is an example usage scenario and how the import mechanism behaves.
Step 1. The user enters the import command to import a file from an absolute or relative file path.
An ImportCommand
object is initialised.
Step 2. When the ImportCommand
executes, the desired import file is first verified to be valid by calling ImportFile#isFileValid()
.
The following checks are done:
-
#isValidFile()
— the import file’s path points to a file and the file is non-empty. -
#isValidFileType()
the import file is of a supported file type (i.e. plain/text file format). -
#isValidFileFormat()
the import file is readable and the text in the import file is in the specified format.
Step 3. Once verified, the import file is parsed to form a unique list of cards that is stored in UniqueCardList
.
An empty UniqueCardList is also considered as an import failure as no cards were parsed from the given text file.
A CommandException will be thrown, and the user is informed that no cards (question and answer pair) were found in the text file.
|
Step 4. TriviaBundle#haveAnyCard()
checks every card in the UniqueCardList
against the existing list of cards in TriviaBundle
for duplicates.
If duplicates are found, the import fails and a DuplicateCardException
is raised.
Step 5. The UniqueCardList
is then added into TriviaBundle
via TriviaBundle#addMultipleCards()
.
The number of cards and the cards imported are displayed to the user for verification.
The sequence diagram below describes the import of multiple cards.
Each card is added repeatedly by invoking TriviaBundle#add()
until all cards in the UniqueCardList
are added.
Design Considerations
Aspect: Pre-import preview
-
Alternative 1: (current implementation) Single step to import cards from a text file.
-
Pros:
-
A single command can be executed quickly for an import.
-
Post import edits can be done using existing commands such as
edit
,delete
, etc.
-
-
Con:
-
A single formatting error in the text file will result in an import failure.
-
-
-
Alternative 2: 'Stages' the import file by first previewing the imported cards to the user. Edits to the import file can be done directly to the text file within the application during this phase. The actual import is then done upon confirmation.
-
Implementation details:
-
Given below is a class diagram describing the structure for the alternative import implementation.
-
The
Format
class verifies the formatting of theImportFile
, marks and displays the errors of the text file within the application for editing.The
FileParser
is dependent onFormat
to determine whether each line in the text file is a topic or a question and an answer pair. TheFileParser
parses theImportFile
into aUniqueCardList
to be added.The
ObservableFile
interface allows the UI component to update the preview of the cards each time the file is edited without a direct dependency to it.
-
-
Pro:
-
Allows the user to identify errors in formatting and correct them directly in the application.
-
-
Con:
-
An additional step (command) is required to successfully import the cards into the application.
-
-
Aspect: How import executes
-
Alternative 1 (current choice): Store all cards to be added in
TriviaBundle
before writing to file on the hard disk.-
Pro: Less IO intensive as only one write to file is needed.
-
Con: May have heap memory issue if large amount of cards are stored temporarily.
-
-
Alternative 2: Writes a card to a xml file after each card is added.
-
Pro: Easy to implement.
-
Con: May have performance issue when large amount of cards are added.
-
Aspect: How the import file is parsed
-
Alternative 1 (current choice): Tokenize strings according to defined characters between question and answer, and between cards.
-
Pro: Allows the user to undo/ redo an import as the execution of the import only executes
VersionedTriviaBundle#commit()
once. -
Con: May have memory performance issue as multiple cards are stored temporarily in the
TriviaBundle
.
-
-
Alternative 2 (current choice): Tokenize strings based on the
AddCommand
input format.-
Pro: Easy to implement as it allows reuse of the
AddCommand
functions. -
Con: Unable to undo/ redo import of cards as the execution of the import command executes
VersionedTriviaBundle#commit()
multiple times. A successful undo/ redo of the import of all cards would require multiple executions of the undo/ redo command.
-
[Proposed] Delete Multiple Coming in v2.0
Current Implementation
The delete mechanism is facilitated by TriviaBundleParser
, DeleteCommandParser
, ParserUtil
, DeleteCommand
and Index
.
Currently, DeleteCommandParser
invokes ParserUtil#parseIndex()
which parses a oneBasedIndex
input into an Index
.
The DeleteCommand
executes the deletion of a card using the zeroBasedIndex
as specified in Index
.
Proposed Enhancement
To delete a range of cards from 1 to 5, delete 1-5
will be executed.
The proposed deletion of multiple cards will utilise the following operations:
-
ParserUtil#parseIndex()
— takes in a one based index. -
ParserUtil#parseMultipleIndex()
— takes in a range of one based indexes in a specified format.
Both of the above methods will return a set of Index
.
Given below is an example implementation of how delete 1-5
will behave at each step.
Step 1. DeleteCommandParser
will determine if the given input deletes a single card or multiple cards.
This can be done by determining if the input contains a -
.
Step 2. In this example, ParserUtil#parseMultipleIndex()
will execute and return a set of Index
.
Step 3. The set of Index
is used to initialise DeleteCommand
.
Step 4. When DeleteCommand#execute()
is invoked. A zero based index is obtained from each Index
in the set.
Each zero based index is then used to delete the cards, similar to the current implementation of delete
.
Design Consideration
Aspect: Separate or single delete command
-
Alternative 1 (current choice): Single delete command.
-
Pro: Reduces the number of commands for the user to remember.
-
Con: Users may be unaware of this functionality being available as the name of the command does not describe deleting multiple cards.
-
-
Alternative 2: Separate delete command for deleting multiple cards.
-
Pro: The command will describe the action of deleting multiple cards clearly (i.e.
deleteMultiple 1-5
). -
Con: There will be more commands for the user to remember.
-