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
andJava 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:
-
Did documentation in Developer Guide. (See Contributions to the Developer Guide below)
-
Maintained the Command List Summary (See Section 7 of Contributions to the User Guide below)
-
-
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
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
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
-
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
orwrong
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
-
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 ornext
to go to the next question.
Java/Javascript Cards: code
-
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.
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:
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:
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).