1. Introduction

This project portfolio highlights my various contributions to the BrainTrain project, including code, documentation and administrative matters.

1.1. Overview of project requirements

BrainTrain was developed as part of the CS2103T Software Engineering module at the National University of Singapore. My team of 5 were given seven weeks to develop our application, built off of an existing address book application.

We were expected to apply industry-standard practices and tools such as Github and Continuous Integration. Beyond the application, we were also required to document our work in a User Guide and Developer Guide.

1.2. Overview of BrainTrain

BrainTrain is a memorisation tool made for students and other learners, especially in content-heavy subjects, such as language vocabulary, science terminology and others.

BrainTrain is a flashcard application that implements a Spaced Repetition System (SRS) to test the user over time. This allows you to remember various things in a short amount of time, yet also assist in memorization long-term as you continuously use the application.

2. Summary of contributions

My role was to design and manage the storage of Lesson data in BrainTrain. The following sections will highlight some of the choices I made and the reasons behind them, and various other contributions to the administration and documentation of the project.

2.1. Major enhancement

Added the ability to save and load Lesson data to Comma-Separated Value (CSV) files.

  • What it does: Allows the user to save and load flashcard lesson data to CSV files.

  • Justification: CSV files can be opened in an external editor, such as Excel. Given that a lesson may have up to hundreds of cards, managing the lesson through row by row editing would be tedious for a user. An external spreadsheet editor would be more suited to editing large amounts of data.

  • Credits: The OpenCSV library, which handles actual file I/O.

  • Relevant pull requests: #28, #35, #78, #121, #179


2.2. Minor enhancement

Added the reload command.

  • What it does: Allows the user to manually reload lessons from their hard disk.

  • Justification: The user would be able to modify existing lessons or download new lessons without having to close and open the application.

  • Relevant pull requests: #121


2.3. Other contributions:

  • Project management:

    • Led the team, setting deadlines for milestones and other tasks and contacting mentors as needed

    • Set up team’s Github repository

    • Set up branch protection, issue labels, milestones on the repository

    • Set up AppVeyor, Codacy, Coveralls, Travis on the repository

  • Documentation:

    • Updated User Guide and Developer guide: #78, #99 , #121

  • Community:

    • PRs reviewed (with non-trivial review comments): #32, #129, #180

    • Contributed to forum discussions (examples: 1, 2)

    • Reported bugs and suggestions for other teams in the class (examples: 1, 2, 3)

  • Tools:

    • Integrated a third party library (opencsv) to the project (#21, #28)

    • Set up a team Discord channel with the Github Bot for notifications

3. 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.


Reloading all lessons: reload

Reloads all lessons from the lessons folder. The default lessons folder is /lessons/, found next to braintrain.jar.

Format: reload

This command only works in lesson view. If you are currently editing a lesson in card view, you have to use the quit command to return to lesson view before you can use this command.

Steps:

  1. You have a newly downloaded .csv lesson file, new_lesson.csv, with no lessons currently loaded.

    reload 0 csv
    Figure 1. A new lesson file.
    reload 1 empty
    Figure 2. No lessons are currently loaded.
  2. You drag the new file into the /lessons/ folder.

    reload 2 drag
    Figure 3. Dragging the file.
  3. You enter reload into the app, and the new lesson appears.

    reload 3 reload
    Figure 4. Reloading lessons.
  4. You verify again with listLessons.

    reload 4 list
    Figure 5. New lesson has been loaded.

Lessons are automatically reloaded when you open the application.

If the lesson does not appear, please check Troubleshooting.


Troubleshooting

Q: Why are my card values shown as ??????
A: If your lesson contains non-English characters such as:

  • Characters with accents: à

  • Non-English words : こんにちは السلام عليكم 你好

This can be fixed by opening the lesson file in your preferred spreadsheet application (e.g. Excel), and then saving it as CSV UTF-8 (Comma delimited) (*.csv). UTF encoding allows a computer to show non-English characters.

The default encoding setting is unable to process special characters. As a result, you will need to save it as a UTF-8 encoded file.

Note that externally created lesson files have to be saved with UTF-8 encoding before using them in BrainTrain.
If the files are saved without UTF-8 encoding, any non-English data may be saved as ?????, and the data will be lost.


Q: Why are my lessons not loading?
A: Please verify if the location of BrainTrain is suitable. Depending on your computer’s permissions and security settings, places such as the Desktop may not be usable, and your operating system may prevent BrainTrain from loading the lesson files.

If BrainTrain still does not load lessons despite trying other locations, please contact Team BrainTrain at our issue tracker or email us at eugenef@u.nus.edu, and attach any generated braintrain.log files.



4. 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.


4.1. Lesson storage feature

4.1.1. Current implementation

The lesson CSV storage feature implements the following functions:

  • Parsing lesson data into a list of string arrays, which is a format OpenCSV accepts for saving to CSV.

  • Parsing a list of string arrays back into lesson data, as retrieved from OpenCSV.

Actual file I/O is handled in the CsvUtil class, which uses the OpenCSV library to read/write .csv files.


4.1.2. Csv lesson format

CsvLessonStorageSequenceDiagram
Figure 6. High-level sequence diagram for the reload command, an example of lesson loading

Lessons are parsed by CsvLessonListStorage, being converted between Lesson and List<String[]> formats. The List<String[]> format is the primary format handled by CsvUtil for reading and writing to .csv files.

For lessons, there are three main sections when saved to a .csv file.

Name

A lesson’s name in BrainTrain is equivalent to its file name.
A lesson named "French" would be saved as "French.csv", and vice-versa.

Header

The header is represented in the file as the first two lines. Each line represents a specific set of data, as outlined below.

The first line represents the type of the corresponding column. Each column can have three types:

  1. Tested
    This marks the column as a core value. By default, the first two instances of Tested in the file will be tested in quiz mode. All remaining Tested values are treated as Not Tested.

  2. Not Tested
    This marks the column as a core value. However, unlike Tested, they will not be tested in quiz mode. You can use the set command to change this.

  3. Hint
    This marks the column as a hint value. Hint values will appear when the user enters the \hint command in quiz mode. Values here are optional and can be left empty.

Core values require every value in that column to be non-empty. This guarantees that the user will be tested on something, should they change which fields are tested.

This is a code snippet from the parsing of the header data.

for (int i = 0; i < headerArray.length; i++) {
    if (headerArray[i].isEmpty()) {
        headerArray[i] = " ";
    }
}
int coreCount = 0;
int index = 0;
while (index < headerArray.length) {
    String headerChar = headerArray[index].toLowerCase().substring(0, 1);
    if (headerChar.equals(HEADER_CORE_QA)) {
        if (questionIndex == -1) {
            questionIndex = index;
        } else if (answerIndex == -1) {
            answerIndex = index;
        }
        coreCount++;
    } else if (headerChar.equals(HEADER_CORE_NOT_QA)) {
        coreCount++;
    } else if (!headerChar.equals(HEADER_OPTIONAL)) {
        return returnValues;
    }
    index++;
}

As seen at the beginning of the while loop, header values are actually treated as single case-insensitive characters. This means an experienced user may simply enter those letters as a shortcut.

The second line represents the name of each column as shown to the user. Any names left blank are automatically replaced with Unnamed.
Any discrepancies in the number of types and the number of names will result in the lesson not being loaded.

Card data

All remaining data is treated as card data. Any invalid data found in memory or from the file is skipped over.

Summary
ReloadActivityDiagram
Figure 7. Activity diagram for the reload command, highlighting failure conditions

As shown in the above diagram, data that is read in from a file goes through various checks before it is loaded into the application. Any invalid data is skipped over, with an entry in the logs explaining the cause of failure.


4.1.3. Design considerations

Aspect: choice of file type
  • Alternative 1 (current choice): Save as .csv

    • Pros: User is able to modify lesson data in a more advanced external spreadsheet tool like Excel

    • Cons: Lack of data verification within the file, JSON is already implemented in original code

  • Alternative 2: Save as JSON

    • Pros: All values can be verified through the file

    • Cons: Difficult for user to edit manually

Alternative 1 was chosen as ease of use is a high priority for the project. Most computer users are familiar with the Microsoft Office suite of applications, such as Word and Excel. As Excel allows .csv files to be shown in a spreadsheet, it was intended that users use Excel alongside BrainTrain for easy lesson management.

Aspect: handling of invalid data
  • Alternative 1 (current choice): Skip over specific lesson/card

    • Pros: User data is not automatically overwritten

    • Cons: User has to manually fix any issues with their data

  • Alternative 2: Automatically fix data

    • Pros: Ease of use for user

    • Cons: Automatic fix may not be as desired by user

Alternative 1 was chosen as creators are expected to have some skill in data editing. Normal users would ideally only download lessons from a creator, and would not be familiar enough with the lesson data to fix any issues.