About the Project
This Project Portfolio is intended to document and detail my personal contributions to my software engineering project for the module CS2103T Software Engineering. In this module, me and my team of four other software engineering coursemates were tasked with morphing a given codebase for a desktop app that primarily made use of typed input to receive instructions. We decided to morph the app into an all-in-one study aid application named StudyBuddyPro, targeted specifically at NUS Computer Science students who preferred visual learning. Our app supports the use of flashcards and notes, provides a timetrial and reminder feature for flashcards, and includes an automatic cheatsheet-generation tool.
The image below displays the current Graphical User Interface (GUI) of StudyBuddyPro:
My role in this project was to write the code for Notes, implement their basic functions, and implement the ability to add tags within the content of notes. Additionally, I was tasked with completing the test cases, user guide, and developer guide portions for the entire Notes feature, and any other relevant documentation. This Project Portfolio thus details how I implemented these changes.
Informative Callouts
The following symbols will be used throughout this document to indicate more important pieces of information in this Portfolio:
Information that, if not followed, will result in StudyBuddyPro not functioning correctly. |
Information that is crucial for you to understand the details of this Portfolio. |
Information that will enrich your understanding of this Portfolio. |
colored words
--- Refers either to a command word or a part of StudyBuddyPro’s architecture.
Summary of Contributions
As mentioned earlier, these are my contributions to my software engineering project:
-
Major Contribution 1: Implemented Notes, along with their basic features.
-
What: Notes are pieces of information that contain a title, some content, and some tags. They can be added, deleted, viewed, and filtered.
-
Why: Notes can be used by students to store information. They form one of the two main sources of information for cheatsheet creation in StudyBuddyPro, and are therefore essential to the studying process.
-
-
Major Contribution 2: Implemented the Add Tags Within Notes feature.
-
What: This feature allows the user to use a pre-defined syntax to tag specific portions of a note with tags (these tags are henceforth referred to as 'note fragment tags'). Note fragment tags are independent of the note’s original tags, and can be filtered just like normal notes can be.
-
Why: This feature can be used by students to add information to cheatsheets much more precisely. It can also be used to highlight specific important parts of a note. This would be very helpful for students to revise more efficiently.
-
-
Minor Contribution 1: Implemented the
view
andviewraw
commands for Notes.-
What: Both commands view a given note, but the
view
command also cleans up the syntax of the note to remove the leftover syntax from the addition of note fragment tags. -
Why: Users will not want the GUI of the app to be cluttered up by note fragment tag syntax. It will be more aesthetically pleasing to have the option to not view the syntax when viewing a note.
-
-
Code Contributed: This link contains the code that I wrote for this project: My code
-
Other Contributions:
-
Project management:
-
Enhancements to existing features:
-
Documentation:
-
Standardized formatting of User Guide to improve overall consistency. (#349)
-
-
Community assistance:
-
Tested bugs for another group’s project during a Practical Exam dry run.
-
-
Contributions to User Guide
In this project, I was tasked with writing all portions of the User Guide related to Notes (specifically Section 6 of the User Guide). The sections below hence document my contributions to the User Guide of StudyBuddyPro. In the following 3 pages, I will describe how you can add and view notes from StudyBuddyPro, in an easy-to-follow manner.
All the operations in this section assume that you are in the notes mode. To be sure
you are in the notes mode, please ensure that you have used the |
To create a note: add
Adds a note from user input with title TITLE
and content CONTENT
, that you can conveniently access later. The title of the note cannot be a duplicate
of an existing note title.
Format: add t/TITLE c/CONTENT [tag/TAG]...
Example usage:
add t/Pipelining Definition c/Pipelining is a process where a processor executes multiple processes simultaneously. tag/cs2100
Expected output:
New note added:
Title: Pipelining Definition
Content: Pipelining is a process where a processor executes multiple processes simultaneously.
Tags: [cs2100]
The added Note has no detected note fragment tags!
More advanced usage: This is where our Notes feature stands out from the others! Tagging of note fragments is also supported. The note fragment tagging is added at the same time as the note is created.
Note fragments can be visualised as a form of highlighting your notes. Its tags are added with content FRAGMENT_CONTENT
, at least one tag
FRAGMENT_TAG
, and any number of additional tags ADDITIONAL_FRAGMENT_TAG
:
Format (within CONTENT): /* C/FRAGMENT_CONTENT TAG/FRAGMENT_TAG [TAG/ADDITIONAL_FRAGMENT_TAG]... */
The format for note fragment content is 'C/', not 'c/', and the format for note fragment tags is 'TAG/', not 'tag/'. |
If the format is not followed correctly, the note fragment tag will simply not be added (but the note will still be added). StudyBuddyPro will assume that the user has typed the tags correctly. |
In the following example, two note fragment tags are added to the same note fragment:
Example usage:
add t/About Notes c/Notes can be /* C/highlighted TAG/highlight TAG/important */ if needed. tag/about
Expected output:
New note added:
Title: About Notes
Content: Notes can be /* C/highlighted TAG/highlight TAG/important */ if needed.
Tags: [about]
Note fragment tags detected:
Title: About Notes
Content: highlighted
Tags: [important][highlight]
This adds a note with content "Notes can be highlighted if needed.", and a note fragment tag with content "highlighted" and two tags "cs2100" and "important".
The spaces around the syntax elements of '/*', 'C/' etc are part of the syntax. For example, if a note fragment tag looks like this: '/* C/highlighted TAG/important */if needed', then the resultant Note will look like this: 'highlightedif needed'. |
Multiple note fragment tags are allowed. These do not interfere with the other tags of the Note.
Overlapping note fragment tags are not allowed. |
To view a note: view
Views the note of index NOTE_INDEX
. If the note contains any note fragment tags, those tags will be hidden.
To view the note with its note fragment tags, use the viewraw command instead (see Section 6.4).
|
Format: view (index)
Example usage:
view 3
Expected output:
Viewing note:
Title: About Notes
Content: Notes can be highlighted if needed.
Tags: [about]
Viewing a raw note: viewraw
Views the note of index NOTE_INDEX
. The note is shown exactly as written, including all note fragment tags.
Format: viewraw (index)
Example usage:
viewraw 3
Expected output:
Viewing raw note:
Title: About Notes
Content: Notes can be /* C/highlighted TAG/cs2100 TAG/important */ if needed.
Tags: [about]
Contributions to Developer Guide
In this project, I was tasked with writing all portions of the Developer Guide related to Notes (specifically Sections 3.4 and 4.7 of the Developer Guide). The sections below hence document my contributions to the Developer Guide of StudyBuddyPro. In the following 5 pages, I will detail out how I decided on and created my feature. I will also describe the architecture of my feature using various types of diagrams, so that you can more clearly understand how the feature works.
Implementation of Notes
Notes
contain a Title
and a Content
, with optional Tags
and NoteFragments
, as shown in the class diagram
below:
As is standard in this Developer Guide, red classes are part of the |
Implementation of the Add Tags Within Notes feature
In the following section, I will describe in general how I implemented the Add Tags Within Notes feature, which allows users to store specific sections of their notes with tags.
The Add Tags Within Notes feature was implemented in the following way:
-
Creation of a
NoteFragment
class that represents one tag within aNote
-
Have each
Note
contain any number ofNoteFragments
in a list -
Upon addition of a
Note
, parse itsContent
to check for any note fragment tags within it -
Create any required
NoteFragment
objects and add them to the list in their parentNote
-
Since
NoteFragments
are contained withinNotes
, when aNote
is deleted, itsNoteFragments
will be deleted as well.
The following class diagram shows a more specific view of the relationships between the Note
, NoteFragment
, and
NoteFeatureUtil
classes.
As shown in the diagram above, NoteFragments
contain:
-
A
Title
that is the same as their parentNote
-
A
Content
that is a substring of their parentNote
-
Any indicated
Tags
that are independent of their parentNote
Implementation of NoteFragment creation
In the following section, I will describe how I implemented the creation of NoteFragments
. While Notes
themselves are quite useful, I felt that implementing NoteFragments
would allow users to gain even more value out
of the automatic cheatsheet-generation feature in StudyBuddyPro.
The method of parsing Content
in NoteFeatureUtil#parseNoteFragmentsFromNote()
relies on the use of Prefixes
around each note fragment tag. Each note fragment tag is specified with a start and end marker (represented by the
Prefixes
'/*' and '*/'), and its Content
and Tags
are also represented with the Prefixes
'C/' and 'TAG/'.
Example usage:
add t/About Notes c/Notes can be /* C/highlighted TAG/highlight TAG/important */ if needed. tag/about
'C/' and 'TAG/' have to be used instead of the default 'c/' and 'tag/' because otherwise the Note would not be
parsed correctly (since only the most recent 'c/' tag is used for each command).
|
A Note
has been added with the Content
of 'Notes can be /* C/highlighted TAG/highlight TAG/important */ if
needed.', and a note fragment tag with Content
'highlighted' and two Tags
'cs2100' and 'important'. The Note
itself is instead tagged with the Tag
'about'.
You can refer to the earlier pages of this Portfolio to recall the specific syntax used in note fragment tags. |
The following sequence diagram elaborates upon the creation process of Notes
and NoteFragments
:
As can be seen from the zoomed-in diagram above, when an AddNoteCommand
is created:
-
A
Note
is created with the desiredTitle
,Content
, andTags
. -
The
Content
of theNote
is parsed for thePrefixes
'/*', '*/', 'C/', and 'TAG/', usingNoteFeatureUtil
. -
A
List<NoteFragment>
is returned to theNote
. -
A
CommandResult
is returned to describe the AddNoteCommand’s result.
All four Prefixes must be present for the note fragment tag to be considered valid. Otherwise, an exception is
thrown.
|
Implementation of ViewNoteCommand
In the following section, I will describe how I implemented ViewNoteCommand
. I chose to implement this command
because users might not want to see complicated syntax when they are viewing notes.
There are two Commands available if the user intends to view a particular Note
: ViewNoteCommand
and
ViewRawNoteCommand
. ViewNoteCommand
displays the Note
to the user while hiding any note fragment tag syntax
from the content of the Note
, while ViewRawNoteCommand
displays the Note
to the user exactly as it was inputted.
The main difference in the process of the two commands is shown in the activity diagram below:
As can be seen in the diagram above, the method Note#getContentCleanedFromTags()
is used to obtain a copy of the
Content
of the Note
, and reformat it by replacing its note fragment tags with blank spaces. This is further
elaborated on by the object diagram below:
As can be seen from the diagram above, the Note
object named 'note' makes use of the NoteFeatureUtil
object and
its own Content
object to return the cleaned content String to the ViewNoteCommand
object. The ViewNoteCommand
object then creates a separate Note
object named 'cleanedNote' to obtain the information to display.
This indicates that calling a ViewNoteCommand
does not affect the original Note
, as a separate Note
object is
created instead.
Design Considerations of the Add Tags Within Notes feature and ViewNoteCommand
In the following section, I will describe two of the decisions that I had to make while creating my feature, and will elaborate on the pros and cons of each choice.
Some of the architectural components mentioned in these alternatives (e.g. |
Aspect: Container location for NoteFragment
-
Alternative 1 (current choice): Each
Note
contains aList<NoteFragment>
:-
Pros: Much easier maintenance, since
NoteFragments
are automatically deleted with the deletion of their parentNote
. -
Cons: O(n2) search time for
filter
commands, as allNoteFragments
in eachNote
in theUniqueNoteList
must be searched through to filter them out.
-
-
Alternative 2: Separate
UniqueNoteFragmentList
fromUniqueNoteList
:-
Pros: O(n) search time for
filter
commands, as theUniqueNoteFragmentList
exists separately from theUniqueNoteList
. -
Cons: Difficult to maintain; deletion of a parent
Note
requires searching theUniqueNoteFragmentList
for any childNoteFragments
to delete as well.
-
Aspect: Implementation of ViewNoteCommand
-
Alternative 1 (current choice): Create a method
Note#getContentCleanedFromTags()
that also returns a Content:-
Pros: Allows
Note
to remain as the sole point of interaction between the otherNote
classes (specificallyContent
andTags
). -
Cons: Is more complicated as
Content
must be converted to String before manipulation.
-
-
Alternative 2: Create a method
Content#getContentCleanedFromTags()
that returns a cleaned copy of itself.-
Pros: Can manipulate the String of the
Content
directly without having to convert it to and fromContent
. -
Cons: Breaks the Single Responsibility Principle, as
Content
will now be dependent onTags
, even though it does not useTags
.
-