By: Team F09-2
Since: Aug 2019
Licence: MIT
1. Setting up
Refer to the guide here.
2. Design
2.1. Architecture
Commons
represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
-
LogsCenter
: Used by many classes to write log messages to the App’s log file.
The rest of the App consists of four components.
The sections below give more details of each component.
2.3. Logic component
API :
link:https://github.com/AY1920S1-CS2103-F09-2/main/blob/master/src/main/java/dream/fcard/logic [Logic Package
]
The Logic package manages the internal logic of the application.
When the User passes in their commands from the Command Line, it is passed to the Responder
class via the method takeInput()
.
This then passes the input String to the Responses enumerations which will parse the String into the appropriate command.
While parsing, Responses
will consider 2 criteria:
-
Only the
Responses
that exist in theResponseGroup
matching theState.currState
StateEnum
will be considered. -
Only
Responses
with a regex that matches the input String will be considered.
As such, depending on the StateEnum
(a.k.a. the current 'mode' of the application), only some Responses
will be
considered. For simplicity’s sake, the Responses
that exist for each application 'mode' can be said to exist in a
specific bucket (when the application is in TEST
mode, the Responses
that exist in the Test bucket are TEST_NEXT
,
TEST_PREV
and TEST_EXIT
).
When the right command is found, the specific Responses
enumeration will execute its own ResponseFunc
, which is the
implementation of the specific command (eg a help
command will print out the appropriate help message for the user).
To assist with the running of certain commands, the HelpCommand
and CreateCommand
classes are used to abstract the logic
further.
2.4. Model component
API : Model
FlashCard
:
-
There are 3 types of cards used by our App, the
JavascriptCard
,FrontBackCard
andMultipleChoiceCard
.
-
JavascriptCard
andFrontBackCard
implements fromFlashCard
, an interface class. -
MultipleChoiceCard
inherits fromFrontBackCard
. -
The interface class
FlashCard
also implementsJsonInterface
class to allow loading and saving to Json format.
Refer to the activity diagram below to see the process of creating a MultipleChoiceCard
:
For the MultipleChoiceCard
, the choices provided by the user must be unique, i.e. there cannot be any duplicate in the choices provided.
If a duplicate choice is detected, then the creation of the MultipleChoiceCard
will not be successful.
Each FlashCard has an associated priority level, which the user can indicate his/her value of the importance of the card.
The priority levels are described below:
Priority | Value | Intended Action |
---|---|---|
HIGH_PRIORITY |
10 |
Valued as important by user, should be tested more often |
LOW_PRIORITY |
1 |
Valued, but less important by user, should be tested less often |
The sequence diagram below shows how the ExamRunner
component can use the createSubsetForTest()
method in the Deck
and make use of the priorities associated with the FlashCards
to create a test that emphasises the FlashCards
that the user deems as important.
-
Step 1: Constructor of
ExamRunner
is called. -
Step 2: In the constructor of
ExamRunner
, a method call is made toDeck
to create a subset of cards for test. -
Step 3: If there are less than 10 cards in
Deck
, return all the cards. -
Step 4 - 10: Return a set of cards with both
HIGH_PRIORITY
andLOW_PRIORITY
cards, which the proportion is weighted at 60% to 40% ratio respectively. -
Step 11:
Deck
returns the test set toExamRunner
.
2.5. Design Considerations
2.5.1. Aspect: how to store and select the HIGH_PRIORITY
and LOW_PRIORITY
cards
-
Alternative 1: Use a priority queue to store the cards
-
Pros: Allows the user to test the cards according to
HIGH_PRIORITY
cards first, effectively choosing onlyHIGH_PRIORITY
cards first, thenLOW_PRIORITY
cards. -
Cons: Certain
LOW_PRIORITY
cards may not be tested if the test set size is smaller than the number ofHIGH_PRIORITY
cards -
Cons: FlashCard Pro cannot have the flexibility of letting the user select the number of
LOW_PRIORITY
cards in the test set.
-
-
Alternative 2: (Current Choice) Maintain two lists of cards,
HIGH_PRIORITY
andLOW_PRIORITY
cards-
Pros: Can control the ratio of
HIGH_PRIORITY
andLOW_PRIORITY
cards in the test set created -
Pros: Have the flexibility to randomize the card order and choose a random set each time
-
Cons: FlashCard Pro cannot have the flexibility of letting users assign more than 2 priority levels
-
2.6. Storage component
API : StorageManager.java
API : JsonParser.java
API : FileReadWrite.java
The Storage
component,
-
interface to save deck by calling
FileReadWrite
-
interface to load deck by calling
FileReadWrite
, send string toJsonParser
and creating deck objects fromJsonValue
The JsonParser
component,
-
takes any string of JSON format and returns a
JsonValue
The FileReadWrite
component,
-
resolves root directory for app save data
-
interface for user to provide their custom root directory
-
writes file and creates path directories if none
2.6.1. Implementation
The parsing is done by JsonParser
.
It takes a string and attempts to read it as one of a JsonValueTypes
and create its corresponding object wrapped in JsonValue
.
Since Objects and Arrays can recursively contain a json value, their contents are also read, created and wrapped.
-
JsonParser#parseJsonInput()
— constructs theJsonValue
object from a string input
Given below is the overview activity diagram of parsing a json string input.
It will first be tested to see if its an integer and if it fails it will be tested for a double. Consequently, boolean, string, json object, json array.
Json object values are themselves json values thus the activity diagram is called recursively Likewise for json array values.
If all parsing types fail, there must be an error with the string input, thus a JsonFormatException is thrown. |
2.6.2. Design Considerations
The JsonParser is designed to be a utility class with a pure function without any mutation of state. Thus it should be self contained within a single function call.
2.7. Code Component
The Code
component supports code-running flashcards in Java and Javascript. Cards will take in user input
via the JavaScript card (Java card to be implemented soon) and
the JavascriptRunner
class
-
can evaluate JS code from a file using the
FileImporter
class -
can evaluate JS code as an input string
the JavaRunner
class
-
Read/write to the
Solution.java
file during runtime after user has typed Java code into the file -
Compile and run
Solution.java
-
the Java code written in each card is stored in the card itself, but this
Solution.java
will be overwritten and used to run the code in each card.
To be implemented: An in-app Flashcard Pro compiler and debugger for JS and Java as a playground for the user
2.8. Regex Component
Having that we are using the regex approach to parsing, some common parsing and regex creation methods are stored in the following class:
API : RegexUtil.java
RegexUtil#commandFormatRegex` creates a regex that starts with the command
argument and lookaheads
for the elements of args
. Thus a regex for the input create front/asd back/dsa
can be created with
commandFormatRegex("create", new String[]{"front/", "back/"});
.
RegexUtil#parseCommandFormat
is an algorithm that parses user input and returns the resulting values
from the input. Following the previous example, parsing the input will create an arraylist of two arraylists.
The first arraylist contains one element "asd"
and the second arraylist contains one element "dsa"
;
parallel to the arguments of the input.
2.9. Common classes
Classes used by multiple components are in the dream.fcard.datastructures
package and root of dream.fcard.util
3. Implementation
3.1. Logging
We are using java.util.logging
package for logging. The LogsCenter
class is used to manage the logging levels and logging destinations.
-
The logging level can be controlled using the
logLevel
setting in the configuration file (See Section 3.2, “Configuration”) -
The
Logger
for a class can be obtained usingLogsCenter.getLogger(Class)
which will log messages according to the specified logging level -
Currently log messages are output through:
Console
and to a.log
file.
Logging Levels
-
SEVERE
: Critical problem detected which may possibly cause the termination of the application -
WARNING
: Can continue, but with caution -
INFO
: Information showing the noteworthy actions by the App -
FINE
: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size
3.2. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
3.3. UI
The GUI of the application is started up by the UiManager
class, when the application is initialised.
The GUI
class handles operations on the GUI, such as rendering nodes to the application window,
and passing user command input to the Responder
class.
3.4. Test
3.4.1. 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.
3.4.2. 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.
3.4.3. 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).
3.4.4. 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).
3.5. Running a code flashcard
3.5.1. Proposed Implementation
The code flashcard is a card that allows users to answer coding questions by running code directly. The following use case illustrates how the card works.
-
System: FlashCard Pro
-
Actor: User
-
Use case: Create a code flashcard
MSS:
-
The user initialises the card for the appropriate language (i.e. Java or JS)
-
The user enters starter code if necessary (e.g boilerplate code, helper methods)
-
The user enters test cases (specifying inputs and corresponding expected outputs).
-
FlashCard Pro saves the newly created card.
Use case ends.
*Extensions:
-
a) The user enters 0 test cases.
-
1) FlashCard Pro prompts for at least 1 test case.
-
2) The user enters a test case.
-
Use case resumes from step 4.
3.6. Undo/Redo Commands
Undo and Redo are commands meant to reverse any alterations to the ArrayList
of Decks in State. As such, any mistake
can be easily recovered from.
Please refer to the following Use case for an example of the uses of Undo/Redo.
3.6.1. Use case for Undo/Redo
-
System: FlashCard Pro
-
Actor: User
-
Use case: Accidentally deleting the wrong deck and recovering it.
MSS:
-
The user creates 2 decks: Deck1 and Deck2.
-
The user wishes to delete Deck1, but accidentally deletes Deck2.
-
In order to recover Deck2, the user types in the command
undo
into the CLI. -
Deck2 is recovered.
Use case ends.
*Extensions:
-
a) The user decides that they prefer Deck2 to be deleted.
-
) The user types 'redo' into the CLI.
-
) Deck2 is deleted again.
-
Use case ends.
3.6.2. General Activity Diagram of Undo/Redo
Before an Undo/Redo command is called:
Whenever the State’s `decks
are altered, State.addCurrDecksToDeckHistory()
is called. This adds a deep copy of the
current State.decks
to State.deckHistory
. Also, State.resetUndoHistory()
which re-initialises State.undoHistory
.
Then, the changes to State are carried out.
When an Undo/Redo command is called:
The Undo and Redo commands are implemented in similar ways. As such, I will be explaining both commands simultaneously. |
When an Undo/Redo command is parsed by Responder and Responses, it calls the appropriate method in State
(for undo:
State.undoDeckChanges()
, for redo: State.redoDeckChanges()
). This then sets State.deck
to the topmost ArrayList
of Decks from the appropriate Stack (for undo: State.deckHistory
, for redo: State.undoHistory
).
3.7. [Proposed] Configure difficulty of test set in test
mode
Currently, the user is restricted to a test set of 60% HIGH_PRIORITY
and 40% LOW_PRIORITY
cards in the test set.
In V2.0, the user should be able to configure the proportion of HIGH_PRIORITY
and LOW_PRIORITY
cards in the test set to pitch the level of difficulty of the test.
The ExamRunner will be expanded to allow the user to take in the ratio of HIGH_PRIORITY
.
Then, the computation of the number of HIGH_PRIORITY
and LOW_PRIORITY
cards will be done according to the ratio provided by the user.
3.8. Saving and viewing user statistics
-
The Statistics feature revolves around the storage and interpretation of the user’s sessions, be it login sessions or test sessions.
-
Therefore, the
Session
class is the main building block of all Statistics-related classes. They are stored inSessionList
objects. -
Due to design considerations, the
UserStats
andDeckStats
objects are intended to be singletons, created upon application startup and modified, but never duplicated or deleted.-
Thus, they are accessible via the static methods
getUserStats()
andgetDeckStats()
accessible via theStatsHolder
class. -
This method of implementation is similar to what my teammates have used to store
State
. -
Initially, the
UserStats
andDeckStats
objects were intended to be stored withinState
as well. However, the addition of undo/redo functionality complicated matters. Thus, the statistics objects have been decoupled fromState
.
-
The structure of Statistics-related classes is depicted in the class diagram below.
Or, simplified:
The following sequence diagram depicts the starting, ending and saving of the user’s Session
when they open and close the app.
3.8.1. Challenges in implementation
-
Because of the custom
StorageManager
class used to load and save JSON objects, the implementation of loading and saving statistics is somewhat tightly coupled withStorageManager
.-
It is insufficient to simply override the
toJson()
method to ensure that the statistics objects would be stored correctly. Instead, the underlying structure of the statistics objects must be known and exposed during the implementation of e.g. theloadDeckStats()
andsaveDeckStats()
methods inStorageManager
. -
Perhaps in v2.0, refactoring of
StorageManager
could allow for a higher level of abstraction of storage-related methods and reduced coupling betweenStorageManager
and the unrelated Statistics classes.
-
-
As our application is quite significantly different than AB3, we used an MSS-focused approach to development: i.e. we focused on making sure that the user’s "happy path" could be completed via the GUI, before linking up the app’s behaviour with the CLI commands. This resulted in insufficient clarity and tight coupling of the
Responses
class with other classes.-
The logic of parsing CLI input, handling incorrect commands, determining if the application is in an appropriate
State
etc., along with the actual handling of the command, is all bundled withinResponses
at present. -
In v2.0, we could focus on removing duplicated code between the CLI and GUI implementations.
-
In v2.0, we could also work towards abstracting out the app’s desired response to a command in
Command
classes, allowing for aParser
to handle CLI calls and aDispatcher
to handle allCommand
s, whether they originate from the CLI or GUI. -
By abstracting out the handling of each command into separate classes, each team member can check the logic of how each
Command
interacts with their component with ease and avoid duplicated code. e.g. AstartTestSessionCommand
could initialise theExamRunner
, updateStatistics
, and so on. -
Because of the current less-than-ideal implementation of the app’s behaviour, in order to support creating/renaming/deleting decks along with undo/redo, code pertaining to
DeckStats
needed to be inserted at many disparate places in the code, e.g. within a button action in theEditDeckDisplay
controller and inResponses
.
-
3.8.2. Proposed extension: Statistics for individual cards in a deck
-
Statistics for specific cards in a deck could be stored within the
Session
object representing the user’s test session on a deck.-
In this way, summary statistics e.g. how many times the card was reviewed in the past week or whether the user attempted the card correctly on average, can be generated with ease.
-
There is no need to store duplicated data about when each card is accessed.
-
-
One challenge for the implementation of card-specific statistics is the tight coupling of
Responses
with other classes, as mentioned above.-
Because individual cards are prone to change, e.g. when the user edits the front or back of the card, not to mention the decks themselves can also be renamed or deleted, it is important that the implementation of
DeckStats
is fully cleaned up before work onCardStats
can begin.
-
4. Documentation
Refer to the guide here.
5. Testing
Refer to the guide here.
6. Dev Ops
Refer to the guide here.
Appendix A: Product Scope
Target user profile:
-
wishes to learn new materials by retrieval learning and self-testing
-
is an independent learner
-
contents of learning are largely textual
-
prefer desktop apps over other types
-
can type fast
-
prefers typing over mouse input
-
is reasonably comfortable using CLI apps
Value proposition: allow effective reinforcement learning of textual content by answering using CLI input to a question prompt from a GUI
Appendix B: User Stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
|
user |
add a new deck |
create a new topic collection of flash cards to test myself |
|
user |
add a new card to a deck |
include a new question into the topic of the deck to test myself |
|
user |
save my deck of flash cards into my local drive |
I can share it with my friends |
|
user |
load my deck of flash cards into the app |
I can reuse the deck of cards created |
|
user that takes flash card tests |
select an option out of four that best matches the front of a flash card |
I can check that I have understood the concept the flash card aims to impart |
|
learner who wants to track his/her progress |
view the questions I have not done well in |
improve my understanding on these concepts tested |
|
learner who wants to prioritise some test questions over others |
set which questions are more important |
be exposed to these important questions more in the tests |
|
beginner user |
access a help page |
i can learn about the features at a glance |
|
student with subjects of different language mediums |
add flashcards of differing languages |
I can customise my flashcards to the subject I am interested to do |
|
user creating flash cards |
save collections of thematically similar flash cards |
I can share my cards easily to other users |
|
user |
view the list of flashcards in a deck |
remember the material at the back of the flashcard |
|
user |
edit the front and/or back of the flashcard in a deck |
|
|
user |
delete a flashcard from a deck |
|
|
user |
view the decks of flashcards in my library |
I know what are the decks available for my usage |
|
intermediate learner |
vary the amount of difficult questions in a test |
expose myself to a test with varying difficult each time I test myself |
|
expert learner with MCQ flashcard test |
remove the choices given by the MCQ choices and enter the answers via CLI |
test my understanding of the concept without a MCQ choice prompt |
|
learner attempting MCQ questions |
have randomised choices each time I try the test |
I will not copy the choice from the previous test |
|
user |
restore my library state of my previous session |
continue using FlashCard Pro without much time wasted |
|
user attempting a test |
view my score after the test |
|
|
user who attempted a test |
track my progress across mutliple test |
monitor my attempts and correctness |
{More to be added}
Appendix C: Use Cases
(For all use cases below, the System is the FlashCard Pro
and the Actor is the learner
, unless specified otherwise)
Use case: Create a deck of cards
MSS
-
Learner creates a new empty deck and specifies the name of the deck of cards.
-
Learner adds individual cards to the deck and specifies the content of the front and back of the cards.
Use case ends.
Extensions
-
1a. FlashCard Pro detects deck name provided by learner is identical to an existing deck of cards in the library.
-
1a1. FlashCard Pro informs the learner that deck creation is unsuccessful.
-
1a2. Learner creates a new deck with another unique deck name.
-
Steps 1a1-1a2 are repeated until the data entered are correct.
-
Use case resumes from step 2.
-
-
2a. FlashCard Pro detects no front and/or back content specified by the learner.
-
2a1. FlashCard Pro informs the learner that card creation is unsuccessful.
-
2a2. Learner creates a new card with the correct front and/or back content.
-
Steps 2a1-2a2 are repeated until the format of the command entered is correct.
(Was wondering if FlashCard Pro should create the deck, but with a numbering like untitled_1, untitled_2 etc)
-
Use case: Start a untimed test
MSS
-
Learner starts untimed test with a deck of cards by specifying deck name.
-
FlashCard Pro begins test.
-
FlashCard Pro flashes text on the front of a flash card to learner.
-
FlashCard Pro waits for learner’s answer.
-
Learner enters answer.
-
FlashCard Pro matches answer with text on back of flash card.
-
FlashCard Pro informs learner about correctness of the learner’s answer.
-
FlashCard Pro displays the correct answer, the text on the back of the flash card.
Steps 3-8 are repeated until all the flash cards in the deck are completed.
Use case ends.
Use case: Import an existing deck of cards from a JSON file
MSS
-
Learner specifies the filepath of the deck of cards to import, in a JSON file format.
-
FlashCard Pro loads the file in the filepath.
-
FlashCard Pro parses the fields in the JSON file.
-
FlashCard Pro constructs the deck of cards.
-
FlashCard Pro stores the deck of cards in the library.
Use case ends.
Extensions
-
2a. FlashCard Pro detects filepath is invalid.
-
2a1. FlashCard Pro informs the learner that import of deck of cards is unsuccessful.
Use case ends.
-
-
2b. FlashCard Pro detects that filepath does not lead to a JSON file.
-
2b1. FlashCard Pro informs the learner that import of deck of cards is unsuccessful.
Use case ends.
-
Use case: Running a test using Front Back Cards
MSS
-
User enters command to start test with a deck of card and supplies deck name.
-
System obtains the deck of cards.
-
System starts test session.
-
System shows front of card to user, waits for answer.
-
User enters the answer.
-
System evaluates the answer.
-
System reports the correctness of the answer.
-
System moves to next card.
Step 4-8 repeated until there are no cards in the deck remaining.
Use case ends.
Extensions
-
1a. System does not find a deck with the deck name specified by the user
-
1a1. System tells user that there is no deck with specified name.
-
1a2. System exits test creation.
Use case ends.
-
-
1b. System has no decks in library.
-
1b1. System tells user that there are no decks in the library.
-
1b2. System exits test creation.
Use case ends.
-
C.1. Use case: Creating a deck of cards
MSS
-
User enters command to create a deck.
-
System creates a new deck.
-
User enters command to create a new card in the deck.
-
System creates a card.
-
System stores the card in the deck.
Steps 2-5 repeats as long as the user wants to add a card.
Use case ends.
Use case: Untimed Test with a deck of Multiple Choice Cards
MSS
-
User enters command to start test on a deck. (System creates a test subset)
-
System gets the deck the user wants to test on.
-
System starts test session.
-
System randomises the choice ordering.
-
System displays the front of card and choices.
-
User enters the choice of correct answer.
-
System evaluates the answer.
-
System shows the correctness of the answer.
-
System moves to next card.
Steps 4-9 are repeated until there are no more cards in the test set.
Use case ends.
Extensions
-
1a. System does not find a deck with the deck name specified by the user
-
1a1. System tells user that there is no deck with specified name.
-
1a2. System exits test creation.
Use case ends.
-
-
1b. System has no decks in library.
-
1b1. System tells user that there are no decks in the library.
-
1b2. System exits test creation.
Use case ends.
-
-
6a. User enters an invalid choice.
-
6a1. System checks if choice is valid.
-
6a2. System tells User that choice entered is invalid.
-
6a3. System requests User to enter another choice.
Steps 6a1-6a3 repeats until the User enters a valid choice.
-
Use case: Timed Test with a deck of Multiple Choice Cards
MSS
-
User enters command to start test on a deck.
(System creates a test subset)
-
System gets the deck the user wants to test on.
-
System starts test session.
-
System randomises the choice ordering.
-
System displays the front of card and choices.
-
User enters the choice of correct answer.
-
System evaluates the answer.
-
System shows the correctness of the answer.
-
System moves to next card.
Steps 4-9 are repeated until there are no more cards in the test set.
Use case ends.
Extensions
-
1a. System does not find a deck with the deck name specified by the user
-
1a1. System tells user that there is no deck with specified name.
-
1a2. System exits test creation.
Use case ends.
-
-
1b. System has no decks in library.
-
1b1. System tells user that there are no decks in the library.
-
1b2. System exits test creation.
Use case ends.
-
-
6a. User enters an invalid choice.
-
6a1. System checks if choice is valid.
-
6a2. System tells User that choice entered is invalid.
Steps 6a1-6a3 repeats 3 times.
-
6a4. User enters invalid choice for 4th time.
-
6a5. System receives invalid choice for 4th time.
-
6a6. System terminates test.
-
6a7. System tells User that test has terminated due to incorrect inputs.
Use case ends.
-
Use case: Creating a Multiple Choice Card
MSS
-
User enters command to create a MCQ Card to a deck.
-
System starts MCQ Card creation.
-
System stores MCQ card in deck.
Use case ends.
Extension
-
1a. User enters duplicated choices.
-
1a1. System detects duplicated choices in choices provided by user.
-
1a2. System tells User that there are duplicates in choices provided.
-
1a3. System ends card creation.
Use case ends.
-
Appendix D: Non Functional Requirements
-
Should work on any mainstream OS as long as it has Java
11
or above installed. -
Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
-
A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
-
Should handle text input of english alphabets.
{More to be added}
Appendix F: Instructions for Manual Testing
Given below are instructions to test the app manually.
To create an empty deck with name German
:
-
create deck/German
To add a Front Back card with default priority level of low
to the deck German
:
-
add deck/German front/hello back/moin moin
To add a Front and Back card with priority level of high
to the deck German
:
-
add deck/German priority/high front/Good morning back/guten morgen
To edit a Front and Back card’s front text, with the card as the only card in the German
deck:
-
edit deck/German index/1 front/Good bye
To add an Multiple Choice card with priority level of high
3 options and the second option is the correct answer:
-
add deck/German priority/high front/Good morning back/2 choice/klair choice/guten morgen choice/moin
To delete the first card from the German
deck:
-
delete deck/German index/1
To delete the deck German
:
-
delete deck/German
These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. |