About the project

I worked in a team of 5 for a software engineering project to morph a basic command line interface addressbook into a flashcard management application called Know-It-All. Know-It-All is designed to help medical students store, organise and share their learning material, integrated with a test session feature and scoring system to allow for a more efficient rote learning process.

My role was to design and implement the test session feature. The following sections illustrate this major feature in more detail.

Note the following icons and formatting used in this document:

This symbol indicates important information related to this section.

test: A grey highlight (called a mark-up) indicates that this is a command to be executed or a component, class or object in the architecture of the application.

Information in a box like this represents additional useful information related to this section.

Summary of contributions

This section shows a summary of my coding, documentation, and other helpful contributions to the team project.

Major feature: I implemented the functionalities of a test session.

  • What it does: This allows users to begin and end a test session. While inside a test session, flashcard questions will be displayed, and student can input an answer or choose to reveal the answer before moving on to the next flashcard.

  • Justification: This feature is the main highlight of Know-It-All, as students use flashcards to test how much content they have memorised. Equipped with the user-friendly answer command that is missing in existing flashcard applications, Know-It-All provides a more engaging and interactive testing experience for the user.

  • Highlights: This feature modifies the existing UI to facilitate the addition of a new test session screen. It also has a heavy dependency on folder methods. Hence, this feature required an in-depth analysis of design alternatives, considering design patterns and principles as well as the user-friendliness of the commands. More details can be found under design considerations sections of Contributions to the Developer Guide. Implementation and writing tests were also tedious as many checks of the current state of the test session needs to be done to permit only certain commands and ban others.

Code contributed: [Collated code]

Other contributions:

  • Enhancements to features:

    • Wrote additional tests for new features to increase coverage from 79% to 81% (Pull requests #74)

    • Refactored existing status bar to display the current state of the user (whether user is in a test session, in a report display, in a folder or in home directory) instead of the previous last saved location and time. Corresponding tests are written as well. (Pull requests #162)

    • Updated UI colour scheme to enhance aesthetics and clarity of Know-It-All (Pull requests #162, #166, #174)

  • Documentation:

    • User guide: I updated the QuickStart section, added new features, remove previous addressbook features and modify existing commands (Pull requests #60, #59, #80, #106, #127)

    • Developer guide: I updated relevant sections related to addressbook to our Know-It-All flashcard context like Product scope and Non-Functional Requirements, some of its class diagrams and sequence diagrams, and added implementation for test session (Pull requests #80, #106)

    • About Us page: I collated and updated profiles for all members of the team. (Pull requests #6, #127)

  • Community:

    • PRs reviewed with non-trivial review comments: #65 (suggested another method of implementation), #46 (explained why Travis CI was failing)

    • Conducted manual testing, reported bugs and offered suggestions for our team: #119, #123, #124, #125, #134

    • Conducted manual testing and reported bugs for other teams in class: #170, #158, #165, #145

Contributions to the User Guide

We had to update the original addressbook User Guide with instructions for Know-It-All enhancements that we had added. The following is an excerpt from our updated Know-It-All User Guide, showing a few of the notable additions that I have made for the test session feature.

Command Format

  • Words in UPPER_CASE are the parameters to be supplied by you e.g. in addfolder FOLDER_NAME, FOLDER_NAME is a parameter which can be something like Human Anatomy.

  • Items in square brackets are optional e.g HINTS in add q/QUESTION a/ANSWER [h/HINTS].

Test Operations

After memorising the content of the flashcards, it is helpful to test how much information have been internalised and retained in a timed setting. The following commands show just how this can be done with the Test Session functionality of Know-It-All.

At the end of a successful test session, scores are final and you will not be able to perform an undo to restore the previous states before the test session.

Test flashcards in a folder : test

You will enter a test session, where the display area enters a fullscreen and you will be presented flashcard questions and hints (if any) one by one. You should see a screen like the figure below.

startTestSessionPage
Figure 1. A successful test command will display a test session page


Format: test

This command is only considered valid when inside the folder to be tested and is not already inside a test session.
This command is invalid if the current folder is empty as there will be no flashcards to test.
  • Hints will be presented along with the questions.

  • When presented with a question in a test session, you can either input an attempt or enter the command to reveal the answer.

  • For MCQ cards, the ordering of options will be randomized each time the flashcard is tested.

  • Internally, flashcards in a folder are queued to be displayed one by one in the order of lowest existing score to highest existing score.

  • The next flashcard will only be presented when the next command is carried out.

Examples:

  • test

Hint toggle on / off feature Coming in v2.0

If you are familiar with the content and feeling confident, simply toggle off hints during the test session. You can do it by specifying ‘-nohint’ at the end of the test command. Hint will not be displayed along with the question when the card is presented.

Format: test [-nohint]

Timer feature Coming in v2.0

If you are preparing for an exam that will require you to recall information quickly within the limited time given, this timer feature is just right for you! You will be given only 20 seconds to answer each question. If the 20 seconds is up before the question is answered, this attempt will be marked as wrong.

Format: test [-timer]

Keying in answer to a flashcard: ans

To reinforce learning and provide a more engaging experience with Know-It-All, you can input an answer for the currently displayed flashcard question. Know-It-All compares your attempt with the correct answer for that flashcard and tells you if you are right or wrong.

If the answer has been submitted successfully and it is correct, you will see the following page.

CorrectAnswerPage
Figure 2. Correct Answer page


If the answer has been submitted successfully and it is wrong, you will see the following page.

WrongAnswerPage
Figure 3. Wrong Answer page


Format: ans ANSWER

This command is only considered valid if a card question is currently being displayed in an active test session.
  • Answer matching is case insensitive.

  • Answering a flashcard will increase the total number of attempts. If your answer is correct, this action will also increase the number of correct attempts.

  • To answer MCQ cards, enter the number of the option that you think is correct, rather than the option itself.
    E.g. ans 1 rather than ans myanswer

Examples:

  • ans Mitochondrion
    in response to the card question: What is the powerhouse of the cell?

  • ans 2
    in response to the card displayed below, choosing option 2 will give the right answer as the correct answer is 'Pigs'.

AnsweringMcqCard
Figure 4. Answering an MCQ card

Contributions to the Developer Guide

Besides updating the original addressbook User Guide, Developer Guide has to be updated to Know-It-All context and features as well. To keep this section concise, I have included an excerpt from my contributions to the updated Know-It-All Developer Guide about the UI Component and the implementation details and design considerations for the test session feature.

UI component

UiClassDiagram
Figure 5. Structure of the UI Component

API : Ui.java

UI consists of a MainWindow made up of many parts as seen above e.g.CommandBox, ResultDisplay, CardMainScreen, StatusBarFooter, BrowserPanel etc. All these parts, including the MainWindow, inherit from the abstract UiPart class.

Test Session feature

Overall Current Implementation

This big feature mainly involves UI, Logic and Model components.

There are 3 main variables in ModelManager introduced to keep track of the current state of the user in a test session.

  • currentTestedCardFolder

    • The current card folder that the user is running a test session on (stored as an ObservableList of cards) .

    • Set to null if user is not inside a test session

  • currentTestedCard

    • The current card the user is seeing in the test session, obtained from currentTestedCardFolder using currentTestedCardIndex.

    • Set to null if user is not inside a test session

    • Related methods:

      • ModelManager#setCurrentTestedCard(Card card) - set currentTestedCard to the card specified.

      • ModelManager#getCurrentTestedCard() - returns the currentTestedCard.

  • cardAlreadyAnswered

    • A boolean variable to indicate if the user has already executed a valid answer command for the current card.

    • Related methods:

      • ModelManager#setCardAsAnswered() - set cardAlreadyAnswered to true.

      • ModelManager#setCardAsNotAnswered() - set cardAlreadyAnswered to false.

      • ModelManager#isCardAlreadyAnswered() - returns true if the current card has already been answered and false otherwise.

Overall Design Considerations

Aspect: Usage of an extra card variable to keep track of the current card in test session
  • Alternative 1 (current choice): Introduce another variable, currentTestedCard, to store the card to display in the test session.

    • Pros: More reader friendly. Save time from accessing the list to get card at that index.

    • Cons: Extra space used.

  • Alternative 2: No introduction of currentTestedCard as using the currentTestedCardIndex suffices. Every time a card is needed, can simply reference it using currentTestedCardFolder#getIndex(currentTestedCardIndex).

    • Pros: No need to store an extra variable so this method uses less space.

    • Cons: Not so reader friendly. Need to keep accessing the list using the index which can potentially lead to possible violation of the Law of Demeter where an object should only interact with objects that are closely related to it.

Evaluation: We went with Alternative 1 since not a large amount of memory is taken up with just 1 extra card stored. As there will be several references to the currentTestedCard, it will be better to store them somewhere. Abiding by the Law of Demeter, currentTestedCard object will not be interacting with currentTestedCardFolder, limiting its knowledge of that object which is encouraged according to the Principle of Least Knowledge.

Test / End Command

Current Implementation
Model

The main logic for test and end command is carried out in ModelManager with the following methods:

  • ModelManager#startTestSession() - begins a test session on the current card folder user is in and implicitly sorts the cards in it.

  • ModelManager#endTestSession() - ends the current test session.

UI

To update the change in the UI to reflect that the user is a test session (app goes to full screen with question of the current card presented), the following methods are introduced.

  • MainWindow#handleStartTestSession(Card card) - creates a new TestSession page with the card specified and bring the page forward in front of the current CardMainScreen page.

  • MainWindow#handleEndTestSession() - deletes the current TestSession page and the CardMainScreen page at the back is now presented to the user.

Example Usage of test command

To illustrate how the UI, Model and Logic components interact, below is a walkthrough of a typical usage scenario of the test command. Component interactions for a test command is a sequence diagram that summarises Model and Logic interactions, namely steps 1 to 7.

Step 1. User is inside a folder and wants to begin a test session on the current folder by executing the command test.

Step 2. As with every command, the command parser reads the input and generates the relevant Command object, in this case a TestCommand. The object is returned to the LogicManager.

Step 3. The LogicManager executes the TestCommand, storing the result and then transferring control to the Model component, with Model#getState() to check that user is inside a folder and is not already in a test session. (This is omitted from Component interactions for a test command for simplicity.)

If the user is not inside a folder, this test command would be rendered invalid. Step 4 would not proceed and an error message is displayed.

Step 4. After checking user is in a folder, ModelManager#startTestSession() method is invoked, which does the following:

  1. currentTestedCardFolder is set to the current folder the user is in, by invoking getCardList() from the active VersionedCardFolder in folders.

    If this folder is empty such that there is no card to present to the user, an EmptyCardFolderException is thrown, to be caught in TestCommand, which then throws a CommandException to display an error message.
  2. The cards in this folder are sorted in ascending scores by invoking sortFilteredCard(comparator), so that lowest score cards will be presented first to the user in a test session.

  3. ModelManager#setCurrentTestedCard(currentTestedCardIndex) is then invoked to set currentTestedCard to the first card in the folder as currentTestedCardIndex is set to 0.

  4. state in Model is set to IN_TEST to specify that user is in a test session from now onwards.

  5. No change to cardAlreadyAnswered as it is by default false.

Step 5. For TestCommand to obtain the first card to present in the test session, ModelManager#getCurrentTestedCard() is invoked and the Card, c, is returned.

Step 6. With control now transferred back to the logic unit, TestCommand creates a CommandResult object, r with the type START_TEST_SESSION, and set testSessionCard in CommandResult to c obtained in Step 5.

Step 7. r is returned to LogicManager which then terminates and returns r to the caller method.

Step 8. The caller method here is in MainWindow. Control is now transferred to the UI component.

Step 9. MainWindow sees that CommandResult object r has the type START_TEST_SESSION. It invokes MainWindow#handleStartTestSession(currentTestedCard) to display the currentTestedCard question and hints to the user.

TestCommandSequenceDiagram
Figure 6. Component interactions for a test command
Design Considerations
Aspect: Way to execute a test/end command
  • Alternative 1 (current choice): test is executed when inside a folder. The user does not have to specify the folder index and test would just immediately display the first card in this current folder.

    • Pros: The most logical way of carrying out a test session is when the user is in the folder that he or she wants to be tested on. Lesser dependency on entering and exiting folder methods.

    • Cons: Requires the extra step of entering the folder before it can test the folder. User may actually see the questions before the test session.

  • Alternative 2: test is executed when outside a folder, in the home directory. Test command would require a folder index, e.g test 1 to test the first folder. Implementation of getting the card from the folder would rely on enter folder command as well.

    • Pros: Fast way to enter test session from home directory

    • Cons: Not logical for test to be called from inside the home directory which should only allow folder operations. test will then have to implicitly enter the folder to gain access to the cards in it in order to display them, creating a dependency between the test and enter folder commands. Similar issue will arise for the end test session command where user will need to implicitly exit the folder.

Evaluation: Overall, Alternative 1 is a better choice following the Single Level of Abstraction Principle(SLAP) where a function should not mix different levels of abstractions. We can then better achieve higher cohesion and lower coupling. Also, user being able to see the questions before the test session is not a big issue since the answer will not be shown unless user selects the card.

Use Cases

UC01 Test flashcards

MSS

  1. Student is inside a folder and begins a test session.

  2. System presents the question on the lowest-performing flashcard first.

  3. Student inputs his/her answer.

  4. System indicates whether student’s answer is correct or wrong and shows the answer of the flashcard.

  5. Student navigates to next flashcard.

  6. Repeat steps 2-4 until all the flashcards in the folder are tested.

    Use case ends

Extensions

  • 3a. Student doesn’t know the answer and wants to see the answer without attempting.

    • 3a1. Student uses the reveal command.

    • 3a2. Answer is displayed to the student.

Starting and ending a test session

  1. Start a test session while inside a folder

    1. Prerequisites: Enter a folder using the cd command. For example, cd 1 will enter the first folder. All the cards in the folder are listed.

    2. Test case: test
      Expected: Enters a test session, where the display area enters a fullscreen and the lowest scoring flashcard question and hints (if any) will be displayed first. In Test Session is shown on the status message and status bar.

    3. Test case: test on an empty folder (this folder has no cards)
      Expected: The error This command is not valid on an empty folder is shown in the status message. Status bar remains the same (still in folder).

    4. Test case: test when not inside a folder (prerequisite not fulfilled, like being in the home directory, already in a test session or in report display)
      Expected: The error Command can only be executed in folder is shown in the status message. Status bar remains the same.

  2. Ends a current test session

    1. Prerequisites: Enter a test session by typing test when inside a folder. Display area enters fullscreen and lowest scoring flashcard question and hints are displayed. Tester can also be in any state in the test session

    2. Test case: end
      Expected: Ends the current test session, where the display area exits fullscreen and be back inside the folder. End Test Session is shown on the status message and status bar shows that tester is back inside the folder.

    3. Test case: end when not inside a test or report (prerequisite not fulfilled, like being in the home directory or in a folder)
      Expected: The error This command is not valid outside a test or report is shown in the status message. Status bar remains the same.