Introduction

As part of the CS2103 Software Engineering module at the National University of Singapore, I was part of a team of five tasked to develop an application from a given Java address book application, which will be called AB3 in the rest of the portfolio. We chose to morph it into NUStudy, an application for managing lecture notes, questions and revision tasks — all three things pertinent to the average university student, regardless of location. Like the original, it has a command line as its main method of interaction and a JavaFX GUI for display. It has around 5000 lines of code and looks like this:

Ui

This portfolio showcases my contributions to NUStudy: implementing the lecture notes by retooling the existing Person class, related documentation in the user and developer guides and management of the Git repository surrounding NUStudy. It also showcases my technical writing skills and my ability to explain complicated enhancements or modifications to the uninitiated person.

In this portfolio monospace indicates command-line input (commands, parameters, etc.) and italics mark class names. Pull requests and issues will be marked solely by their numbers and a # sign (e.g. #1); unless otherwise specified they refer to NUStudy.

Summary of contributions

This is a brief description of my contributions to NUStudy – to code, documentation and project management. These contributions show my ability to not only write good code, but also manage and synthesise team members' varying output into a coherent whole.

  • I was responsible for implementing lecture notes (starting from #34). These are simple items with a title, some content and optionally an image. For this I modified the existing Person class in the original address book application and its associated commands (AddCommand, EditCommand, etc.) — I did not have to make any new classes.

    • Lecture notes are the primary source of a student’s acquired knowledge in university, yet they come in many formats. Having a unified appearance helps the student understand the content of lecture notes better, by removing unnecessary markup and distracting styles.

    • While adding this feature I also refactored all other code throughout the application to use names relevant to lecture notes. This helped my teammates add their own features, setting an example for them to follow.

    • Image support was implemented starting from #67. Instead of a custom class, I used JavaFX’s scene.image.Image, which reduced the additional code I had to write on top of the Title and Content classes by avoiding an unnecessary wrapper.

  • As my fellow team members added their features to the code, one of the constructors of CommandResult grew to have four boolean variables representing command side effects. In #71 I replaced the boolean arguments of this constructor with a single integer argument acting as a bit field.

    • This serves two purposes: to avoid unnecessary use of the boolean literals and to allow easy extension to more side effects by increasing the range of the integer argument.

  • I enforced a style for the user and developer guides and wrote several of their key sections, such as the user guide’s introduction and the developer guide’s non-functional requirements. See #21 and #22 for examples.

  • In v1.4 I improved the graphical user interface in response to bugs filed by other people (#148).

  • I was the lead integrator for NUStudy:

    • Managed all four releases (v1.1 to v1.4) on GitHub

    • Set up Travis and Netlify for the project, enabling continuous integration and previews of documentation

    • Resolved merge conflicts for teammates' pull requests (see #44 for an example)

    • Attached milestones and labels to issues and pull requests where the original authors failed to specify them

    • Before v1.2, the only person who could merge pull requests

  • I contributed to forum discussions, both as a receiver (#88, #106) and source (#68, #100) of information.

  • I reviewed the following pull requests non-trivially, among others: #40, #49, #53, #70.

  • Whenever I could, I resolved issues assigned to teammates other than me, e.g. #123, #131, #141.

  • A detailed exposition of all code I contributed to NUStudy can be found here.

User guide contributions

Our application’s user guide had to be updated with the new features we added in code. The sections below are what I wrote for my features, demonstrating my ability to write clear, concise end-user documentation.


Lecture notes

Adding lecture notes: addnote

This is the basic command for getting your lecture notes into NUStudy. The i/ field, if provided, brings up a dialog where you can choose an image from your computer’s file system; such an image will be displayed at the bottom of the note.
Format: addnote t/TITLE c/CONTENT [i/]

Suppose you want to remember what the order-7 triangular tiling looks like and its Schläfli symbol. Type addnote t/Order-7 triangular tiling c/{3,7} i/ into the command line. The file selection dialog will pop up, and you can select the image from your file system. Once done, you will see the lecture note:

addnote

It is fine to back out of the image selection dialog; an image can always be added later using editnote. Your images are copied into the application’s data folder, so don’t worry about losing them – you can always take them along. Images resize according to the window, but if an image is small enough that it can fit at its natural resolution, it is left that way.

Editing lecture notes: editnote

If your lecture notes need updating, use this command, providing arguments t/, c/ and i/ (at least one) as you would do with addnote, but only those arguments you want to change. Providing i/ brings up the same image selection dialog like in addnote.

Images can explain a lot, but if you want to remove them, use i/none in your command, and the dialog will not appear. Otherwise, if you back off from choosing an image (e.g. by clicking the dialog’s close button), nothing will happen and your images will remain safe and sound.

Multiple notes can share the same image, and you can overwrite existing images currently in NUStudy with new ones sharing the same filename.

The index must be between 1 and the number of lecture notes inclusive. It is listed before the title of each lecture note:

index

Format: editnote INDEX [t/TITLE] [c/CONTENT] [i/[none]]

Viewing lecture notes: findnote

Of course, what use are virtual lecture notes if you can’t search through them? This command displays those notes whose titles contain any one of the words (space-separated, ignoring case) you provide as arguments.
Format: findnote WORD [WORD]…

Listing all lecture notes: listnote

This is like running findnote but with no arguments. It shows all your lecture notes in their unabashed glory.
Format: listnote

Deleting lecture notes: deletenote

When your semester ends, surely you want to free up space on your computer so you can accept new notes for the coming semester? This command deletes the lecture note with the index you provide.
Format: deletenote INDEX

Clearing all lecture notes: clearnote

Finally, if you ever find a better application than NUStudy for your lecture notes, you can clear them all. Your quiz questions and revision tasks will not be affected.
Format: clearnote

Lecture note grouping suggestions

NUStudy will intelligently suggest groupings of lecture notes based on their content.


In addition, I also harmonised the layout of the user guide and formatted other team members' contributions to said guide in a common manner.

Developer guide contributions

Like other projects in CS2103, there is the expectation that future developers could build on NUStudy. Thus we also updated the developer guide; below are my principal contributions to it, showcasing three aspects: my ability to write technical documentation, the complexity of what I contributed in code and my proficiency in using diagrams to explain my work.


Image support for lecture notes

Usually, we do not learn best from just text; we rely on images that our minds can process more easily. As such, implementing images in lecture notes is a very important feature for NUStudy.

Although some lecture notes have multiple images, it is always possible to combine them using basic image editing software like the GNU Image Manipulation Program (GIMP) and Paint, so the implementation is limited to at most one image per note. Having a common format for notes facilitates their retrieval through the findnote command and aids a human user in remembering what the notes say.

Implementation

Instead of a custom class to represent an image, JavaFX’s scene.image.Image is used instead. This is out of necessity, since an ImageView is needed to display an image in the GUI and it requires an Image object, not just a String path to the image. No significant coupling is introduced by this choice because Image objects can exist without a GUI to display them.

The static method selectImage() in AppUtil opens up a dialog allowing the user to choose the necessary image. This is possible because FileChooser#showOpenDialog(), which shows the dialog, can be fed an argument of null instead of having to rely on a Window object, which is the domain of the UI module.

The aforementioned dialog returns null if it is closed without choosing a file (i.e. clicking the close button). We interpret this as "no change" rather than "no image", i.e. addnote and editnote proceed as if i/ was not provided. If the "no image" interpretation was used, the user who decides to edit a lecture note’s image but then decides not to would be surprised to see the image disappear without warning. Therefore the value i/none has to be explicitly provided in editnote to remove the image; EditNoteDescriptor has the field isImageRemoved to track this.

We also defer image selection until after the title has been checked against existing lecture notes, which saves time that would otherwise be wasted in navigating to the desired image. This is accomplished using three things:

  • the finalizeImage() method of the Note class, calling selectImage()

  • the needsImage field of Note, which allows a one-time execution of finalizeImage()

  • the isImageReplaced field of EditNoteDescriptor

ImageSelectionSequenceDiagram
Figure 1. Sequence diagram for the execution of EditNoteCommandParser

The diagram above shows how EditNoteCommandParser creates an EditNoteCommand. It first creates an EditNoteDescriptor to hold details of what changes in the note, setting the new title (provided by the t/ argument) and content (c/) as necessary. If i/none is present, the EditNoteDescriptor is set to remove the image. If i/ is provided, it is set to replace the image. An EditNoteCommand containing the EditNoteDescriptor is finally returned for execution.

Images are only referenced, not embedded, in the JSON file holding application data. These references are Uniform Resource Identifiers (URIs) of system files, e.g. file:data/picture.png. Since NUStudy is meant to be portable, we cannot use absolute paths, since they would break when the images are moved or deleted. Instead we copy images into application data using finalizeImage(), which points references to these local copies.


Both the use of a JavaFX built-in object for images and the system-dependent implementation of graphical objects required me to make certain critical decisions regarding image support in lecture notes.


Design considerations: where to place the image?

  • Alternative 1 (current choice): We show the images associated to each and every lecture note in the first column, together with the title and content.

    • Pros: This is easier to implement, for the code interfacing with FXML does not have to be written in places other than those directly pertaining to notes. It also makes the note "card" (object representing the note) self-contained.

    • Cons: Scrolling through lecture notes, all with images, takes time, but this downside is alleviated by the findnote command.

  • Alternative 2: We place one full note in the second column and only show a preview (the title and first words of the content) in the first column.

    • Pros: This behaviour is closer to notepad applications on mobile devices which show a list of notes. It saves space in the list and gives more prominence to a selected note, turning it into a flash card.

    • Cons: The second column, normally housing revision tasks, requires extra code to handle the display of full notes. This may include a separate NotePreview class, or Note may have a variable toggling between preview and full modes.

Design considerations: when to copy images into the local folder

  • Alternative 1 (current choice): We copy images when the command is executed, i.e. in Command#execute().

    • Pros: This effects a better separation of concerns – image selection is not execution of the command, while copying can be a side effect of command execution. Individual command effects can be fine-tuned.

    • Cons: Each command that copies images needs to have its own code implementing the copy. To reduce code duplication, that common code can be written as a method of the Note class requiring a Path object representing the destination folder for the copy.

  • Alternative 2: We copy images when the image is selected, i.e. in AppUtil#selectImage().

    • Pros: Compared to alternative 1, this takes less time between image selection and writing into application data, minimising the chance of exceptions due to changes in the file system (permissions, existence of the file at the specified path, etc.) being raised.

    • Cons: selectImage() has two only loosely related responsibilities in this alternative, which is a worse separation of concerns. It is impossible to take into account user preferences at the point of image selection, since it requires a Model object which is not available to AppUtil#selectImage().


The remaining documentation, shown below, is my contribution to the developer guide concerning aspects not directly related to source code – use cases, non-functional requirements and a glossary.

Use case: Create lecture note (Jeremy)

MSS

  1. Student gives the command to add a lecture note – addnote t/TITLE c/CONTENT

  2. Application shows a lecture note with the given title and contents to the user

  3. Application also updates the lecture note list with the new note

Use case ends

Extensions

  • 1a. Student also gives i/ in the command

    • 1a1. Application brings up a file selection dialog

    • 1a2. Student selects the image they wish to include in the lecture note

    • 1a3. Application accepts the image

  • Use case resumes from step 2

  • 1a2a. The selected file is not an image (.png, .jpg, .gif)

    • 1a2a1. Application displays message about the supported file formats

    • 1a2a2. Student selects a file again

    • Repeat 1a2a1, 1a2a2 until a supported file format is selected

  • Use case resumes from step 1a3

Use case: Delete lecture note (Jeremy)

MSS

  1. Student gives the command to delete a lecture note – deletenote INDEX

  2. Application deletes the note from the note list

Use case ends

Extensions

  • 1a. Student gives an out-of-range or non-numeric index

    • 1a1. Application displays message showing in-range indices

    • 1a2. Student re-enters the command

    • Repeat 1a1 and 1a2 until a valid index is provided

  • Use case resumes from step 2

Appendix A: Non-functional requirements

  1. Images must be copied into the application data, residing in a dedicated folder, rather than merely linking to somewhere on the filesystem

  2. Export format of lecture notes and flash cards must be human-readable text

  3. Images must be referenced by pathnames with respect to the image folder

  4. Charts returned by statistics feature must be simple enough that it is universally understood

Appendix B: Glossary

Lecture note

An object stored in the application model that includes a title, text content and optionally an image. It is not quizzable.