PROJECT: FlashCard Pro

Overview

FlashCard Pro is a flashcard software created primarily with students in mind. FlashCard Pro takes after traditional flashcard apps in which users are given decks of cards that they can test themselves on or simply use as reference while studying.

Taking after reputable flashcard applications like Anki, FlashCard Pro provides a Command Line Interface (CLI) driven application where users can control the app via typing various commands.

Summary of contributions

  • Major enhancement: created a test function that users can use to test themselves using flashcards.

    • Allows the user to create tests with or without a time limit.

    • Supports the testing of all 4 types of cards, namely Front-Back Cards, MultipleChoice Cards, Javascript Cards and Java Cards

    • Allow users to test the cards in any order where they can skip to later questions and come back to skipped ones later on.

    • Allows users to review cards at the end of the test and even repeat them to get the correct answer (though it will not contribute to their score).

    • Results will be shown to the user at the end of the test.

  • Justification: This feature improves the product significantly by adding to its functionality because it makes FlashCard Pro more than just a database for FlashCards by having some interactivity with the user. Users will be able to do self-learning with this added functionality.

  • Highlights:

    • This enhancement provides the user with greater functionality to improve his flashcard learning experience. Instead of having a database to access cards, the user is now able to test him/herself.

    • The user is also able to obtain a full-feedback loop with regards to his learning. This begins with testing him/herself with questions, followed by getting a feedback score and lastly being able to review the mistakes made and re-attempt cards for further practice.

    • In addition, this feature is challenging because it requires in-depth analysis and design of the overall application architecture. It involved some complex design decisions such as making ExamRunner a singleton class as well as overall understanding in FXML, Regex and Logic code to tie the implementations of GUI and CLI together.

    • Significant changes were made from the initial design when we changed our program structure to suit a MVC design pattern. This required thorough understanding of good software architecture as well as the Consumer functional interface.

  • Code contributed: [Functional code][Test code]

  • Other contributions:

    • Testing:

      • Alerted team about bugs found in issue tracker: #326

      • Did product testing to ensure that the test mechanism was bug-free, along with other features and GUI, and various system integration tests.

      • Spent a great deal of time trying to fix our CI environment because our project suddenly failed Travis

    • Enhancements to existing features:

      • Wrote additional tests (Please refer to [test code] link above.)

    • Documentation:

    • Community:

      • Contributed to forum discussions (examples: #167)

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.

Start test with flashcards : test

StartTestCommand

Starts a test with a deck of flashcards, with the choice of a timed or un-timed test mode, with the duration specified by the user.

Format: test deck/DECK_NAME duration/DURATION_IN_SECONDS

Examples:

  • test deck/science_deck duration/0

Starts a untimed test with the deck of cards, science_deck

  • test deck/science_deck duration/100

Starts a timed test of 100 seconds with the deck of cards, science_deck

Do note that only the results of the first attempt of each question will be counted in each test. Repeat attempts are allowed for a better learning experience, but will not contribute towards score.

Note that test creates the test deck by taking a few questions from the entire deck! So don’t expect the entire deck to be inside test mode :)

Get next card: next

Gets the next card in the test deck.

If there are no more cards, will trigger a popup with test results.

Get previous card: prev

Gets the previous card in the test deck.

Quit test: exit

ExitCommand

Exits test mode.

Triggers a popup with the results of the test.

Popup will also automatically be triggered upon reaching the end of the deck.

However, upon reaching the end of the deck, the user will be able to review and reattempt questions (though it will not count towards the user’s score)

Do note that premature ending of a test will still count towards your User Statistics.

Front-Back Cards: front, back, correct, wrong

FrontBack
  • Users should look at the question on the front of the card and think of their answer.

  • Once they have their answer, they can type back to view the answer on the back on the card.

  • Once on the card back, one can type correct or wrong to count their results, which will automatically take them to the next question.

  • They can type front when they are on the card back to relook at the question.

Multiple Choice Cards: <INDEX_OF_CORRECT_ANSWER>, front

MCQCard
  • Upon loading the card, users will be presented with the question and several choices.

  • Users will be able to key in their choice into the command bar, with the top most option as 1 and increasing downwards. Do note only numbers are accepted.

  • Keying in the answer will automatically flip the card and evaluate the answer. Users can then use front to relook at the question or next to go to the next question.

Java/Javascript Cards: code

JsJavaCard
  • Upon loading the card, users will be presented with a coding question.

  • They can then type code to launch the appropriate Java/Javascript coding playground to code their programs.

  • Upon running their programs, if they pass all test cases, their results will automatically be counted.

  • Users can then type next to go to the next question.

Command Summary

  • help help [command/COMMAND_NAME]
    e.g. help e.g. help command/view

  • import : import filepath/FILE_NAME

  • export : export deck/DECK_NAME FILE_NAME

  • view : view [deck/DECK_NAME]
    e.g. view deck/science_deck

  • create : create deck/DECK_NAME

  • add - only applicable for Front-Back Cards and Multiple Choice Cards

  • add FrontBack: add deck/DECK_NAME front/CARD_FRONT back/CARD_BACK [priority/HIGH_OR_LOW]

  • add MCQ: add deck/DECK_NAME front/CARD_FRONT back/INDEX_OF_CORRECT_OPTION choice/CHOICE_A choice/CHOICE_B [priority/HIGH_OR_LOW]

  • edit - only applicable for Front-Back Cards and Multiple Choice Cards

  • edit deck/DECK_NAME index/CARD_INDEX [front/NEW_FRONT_TEXT] [back/NEW_BACK_TEXT] [choiceIndex/CHOICE_INDEX] [choice/CHOICE_TEXT]

  • e.g. edit deck/science_deck action/edit index/1 front/what is a cell back/a cell is a building block

  • undo : undo

  • redo : redo

  • test : test deck/DECK_NAME duration/DURATION_IN_SECONDS
    e.g. test deck/science_deck duration/0
    e.g. test deck/science_deck duration/100

  • While in TEST_MODE:

    • next card: next

    • previous card: prev

    • exit test mode: exit

  • TEST_MODE: Front Back Cards:

    • see back of card: back

    • correct answer: correct

    • wrong answer: wrong

    • see question: front

  • TEST_MODE: Multiple Choice Cards:

    • indicate choice: <INDEX_OF_CORRECT_ANSWER> which must be a positive integer between 1 and the total number of choices

    • see question: front

  • TEST_MODE: Java/Javascript Cards:

    • open coding playground: code

  • stats : stats [deck/DECK_NAME]
    e.g. stats deck/science_deck

  • quit : quit

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.

Test

Implementation

The timed/un-timed test is a exam mechanism whereby users can enter a test mode that allows users to test themselves using the various flashcards. Users will then be notified of their results at the end of the test and will also have the chance to review their answers and reattempt questions.

The overall test architecture is depicted in the class diagram below.

TestClassDiagram

Tests are driven by the main ExamRunner class which ensures that only a single Exam object exists at any point in time.

Exam objects are where the bulk of the test logic resides. Exam objects are used to control what card the user is currently attempting via the getCurrentCard() method, used to control the AnchorPanes that show up on the GUI and also to keep track of score through the Result object within.

Exam objects have a composition relationship with Result objects, whereby a Result object cannot exist without an Exam object.

The sequence diagram of the three classes is as follows:

TestSequenceDiagram

When a user first chooses to start the test, he will call on the createExam() within ExamRunner, which will create an Exam object with the duration specified by the user.

Creating an Exam object automatically creates a Result object in the constructor. The Exam object is then able to interact with it via the getResult() method.

Responses and Controllers will then be able to get the current instance of Exam via the getCurrentExam() method in ExamRunner

Given below is an example usage scenario and how the timed/untimed mechanism behaves at each step. The activity diagrams for Timed and Untimed Tests are also as follows:

UntimedTestActivityDiagram
TimedTestActivityDiagram

Step 1. User keys in the command test deck/DECK_NAME duration/DURATION_IN_SECONDS (Eg. test deck/german duration/0)

Step 2. If DURATION_IN_SECONDS is 0, untimed test will be initiated. Else, a timed test will be initiated.

Step 3. A question will be loaded and user answers the question.

Step 4. Answer will be evaluated and if it is correct, score will be updated.

Step 5. For untimed test, repeat steps 3 and 4 until the end of deck is reached. For timed test, repeat steps 3 and 4 until either end of deck is reached or time runs out.

Step 6. If end of deck is reached, a popup will be triggered with the user’s final score.

Step 7. Upon closing that popup, users will be able to review their mistakes and reattempt all questions (but it will not contribute to their score).

Step 8. When the user is done reviewing, he can type exit or click Exit Session to exit test mode and go back to the main Deck Display screen. Users can also use this command prematurely to exit test mode mid-test.

Managing the CLI and GUI

CLI is largely driven by the Responses class which can be found above. However, the test mechanism differs slightly as it relies on a greater amount of States in order to control which commands can be used at what time.

For example, a correct command cannot be used on a MCQCard.

Commands are checked if they belong to a certain ResponseGroup for a State. Only commands that are registered within that state’s ResponseGroup will be executed.

GUI is also controlled by States but does not go through the ResponseGroup class. Instead, it relies on EventHandlers triggered by button clicks. Ideally, one should make GUI go through Responses as well to streamline both the GUI and CLI together.

This design choice is reflected on further below.

Design Considerations

Aspect: Controlling the number of Exam instances.
  • Alternative 1: Just create Exam whenever a user calls for a new test.

    • Pros: Lesser code to write

    • Cons:

      • Limited control on number of instances of an exam object

      • Potentially may lead to bugs if not well managed

      • Hard to simulate a test truly "ending" if an object can persist

  • Alternative 2: (Current Choice) Use a singleton static class that ensures only one instance of Exam exists at each point in time.

    • Pros:

      • Extensive control over the Exam object by ensuring that only one instance exists

      • Exam can be "terminated" to ensure once a test ends, users are unable to re-access it.

    • Cons:

      • More complex design architecture that requires higher understanding of MVC pattern as well as Consumer Functional Interface

Aspect: Management of StandardExam Object
  • Alternative 1: StandardExam class exists standalone

    • Pros:

      • Lesser code to write

      • Lesser complexity in terms of polymorphism

    • Cons:

      • Not open for extension.

  • Alternative 2: (Current Choice) Use an Exam interface despite only one class inheriting from it

    • Pros:

      • Allows the project to be open for extension. Developers may potentially develop other kinds of Exam modes (eg. speed round whereby there’s a limited time per card)

    • Cons:

      • Relatively redundant at the current version (v1.4)

Aspect: Streamlining of GUI and CLI
  • Alternative 1: Have both GUI and CLI managed by the Response class

    • Pros:

      • More streamlined

      • Lesser chance of performance glitches since both interfaces rely on the same logic.

    • Cons:

      • Limited customization if different behaviours want to be implemented in the GUI and CLI (though unlikely).

  • Alternative 2: (Current Choice) Individual logics for both GUI and CLI:

    • Pros:

      • Greater customization.

    • Cons:

      • Slightly more "spaghetti code"

      • Limited expansion as having many different types of cards will result in many different ResponseGroups

  • While FlashCard Pro went with the "inferior" design choice for v1.4, there is definitely room for expansion by using an external state controller like Redux (see below).

Future Extensions

Relationship between GUI and CLI
  • Currently GUI and CLI are not implemented ideally because CLI is dependent on the Responses class while GUI relies on button handlers.

  • Ideally, GUI and CLI should both rely on the Responses class which will streamline the back-end logic.

  • However, due to time constraints and the late discovery of the bug, v1.4 was made with the GUI and CLI not streamlined.

  • Future enhancements could either streamline the GUI and CLI both rely on Responses class or port over to an external state manager like Redux for better performance.

Exam Interface
  • The Exam interface exists such that the project remains open for extension with various different test modes.

  • One example would be a speed round (whereby specific time limits are set for each card).