Developer Guide
Weeblingo is a desktop application for learning Japanese, optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). With a nice and friendly interface, users can learn Japanese at a comfortable pace and manage flashcards with this application.
Table of Contents
- Setting Up
- Design
- Implementation
- Documentation, Logging, Testing, Configuration, Dev-ops
- Appendix: Requirements
- Appendix: Instructions For Manual Testing
Setting Up, Getting Started
Refer to the guide Setting up and getting started.
Design
Architecture
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
.puml
files used to create diagrams in this document can be found in the diagrams folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Main
has two classes called Main
and MainApp
. It is responsible for,
- At app launch: Initializes the components in the correct sequence, and connects them up with each other.
- At shut down: Shuts down the components and invokes cleanup methods where necessary.
Commons
represents a collection of classes used by multiple other components.
The rest of the App consists of four components.
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the hard disk.
Each of the four components,
- defines its API in an
interface
with the same name as the Component. - exposes its functionality using a concrete
{Component Name}Manager
class (which implements the corresponding APIinterface
mentioned in the previous point).
For example, the Logic
component (see the class diagram given below) defines its API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class which implements the Logic
interface.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command learn
.
The sections below give more details of each component.
UI Component
API :
Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
,
FlashcardListPanel
, ScoreHistoryListPanel
, StatusBarFooter
etc.
All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files
that are in the src/main/resources/view
folder.
For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
- Executes user commands using the
Logic
component. - Listens for changes to
Model
data so that the UI can be updated with the modified data.
Logic Component
API :
Logic.java
-
Logic
uses theWeeblingoParser
class to parse the user command. - This results in a
Command
object which is executed by theLogicManager
. - The command execution can affect the
Model
(e.g. updating mode). - The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
. - In addition, the
CommandResult
object can also instruct theUi
to perform certain actions, such as displaying help to the user.
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("learn")
API call.
LearnCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Model Component
API : Model.java
The Model
,
- stores a
UserPref
object that represents the user’s preferences. - stores the flashcard book data.
- exposes an unmodifiable
ObservableList<Flashcard>
andObservableList<Score>
that can be ‘observed’ e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. - does not depend on any of the other three components.
Tag
list in the FlashcardBook
, which Flashcard
references. This allows FlashcardBook
to only require one Tag
object per unique Tag
, instead of each Flashcard
needing their own Tag
object.Storage Component
API : Storage.java
The Storage
component,
- can save
UserPref
objects in json format and read it back. - can save the flashcard book data (flashcards and scores) in json format and read it back.
Common Classes
Classes used by multiple components are in the seedu.weeblingo.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Learn Mode
The learn
command is used to enter Learn Mode, allowing the user to view all flashcards with the question and answer
both displayed. Tagging and deletion of tags is also only available in this mode.
The following activity diagram summarizes what happens when a user attempts to enter Learn Mode:
[Implemented] Tagging Flashcards
The tagging mechanism allows users to add tags to flashcards of their choice while in the Learn Mode of the Weeblingo application. Each flashcard has a set of default tags which cannot be edited, followed by any unique user added tags.
The following activity diagram summarizes what happens when a user adds a new tag:
The tags function ties together with the Start, Learn and Quiz function of the application, as users can choose to start a quiz, enter Start Mode or enter Learn Mode with a filtered set of flashcards.
[Implemented] Deleting Tags from Flashcards
This mechanism works with the above flashcard tagging feature to allow users to customise tags for their flashcards while in the Learn Mode of the Weeblingo application.
The following sequence diagram summarises how the DeleteTagCommand works:
Default tags cannot be deleted by this command and will throw an error if the user attempts to do so.
[Implemented] Quiz Feature
The quiz feature for users to test the vocabulary is facilitated by Model#Quiz
, Model#Mode
and Logic
. It does so by allowing a Command
to set model to quiz mode. When model is in quiz mode, it will take commands allowing users to start a quiz session,
attempt answering the quiz question or skip the flashcard.
Model#Mode
implements the following operations:
-
switchModeQuiz()
: Sets model to quiz mode -
switchModeQuizSession()
: Sets model to quiz session mode -
switchModeCheckSuccess()
: Sets model to check success mode -
switchModeQuizSessionEnded()
: Sets model to quiz session ended mode
Model#Quiz
implements the following operations:
-
getRandomisedQueue()
: Generates randomised questions for the quiz session -
getNextQuestion()
: Provides a question to be bested -
isCorrectAttempt(Answer attempt)
: Checks if attempt is correct English definition of question shown on flashcard
These operations are executed through QuizCommand
, StartCommand
, CheckCommand
and NextCommand
in the Logic
class.
Entering Quiz Mode
The quiz
command is used to enter Quiz mode, allowing the user to start various quizzes from there.
The following activity diagram summarizes what happens when a user enters the Quiz command:
The following sequence diagram shows how the Quiz command works:
Starting a Session
The start
command is used to start a quiz session, enabling users to define the number and categories of
questions they want to be tested on. The activity diagram below shows the flow of events when a user
enters the start command.
Thr following sequence diagram shows the interactions that occur when the start command is executed:
Checking User Attempt
The check
command is used to check if user provided attempt is correct. This feature is implemented by creating an
instance of CheckCommand
that can be executed on the Model
. The Model
will then invoke appropriate methods in Quiz
.
Depending on whether the user attempt is correct, CheckCommand
will return an instance of CommandResult
which will
inform the MainWindow
if it is time to reveal the answer of current question.
The following activity diagram summarizes the general workflow of check
command:
The following sequence diagram shows how the check
command works:
Quiz Scoring
The quiz can be scored for each individual quiz session. The scoring data will be written into the storage file after the quiz session is completed. A quiz session is completed if and only if the message indicating the end of quiz is displayed in the GUI window. The following activity diagrams summarize how the score is generated and recorded along with each quiz session.
View Past Quiz Attempts
The view quiz history mechanism allows users to view their past attempts of quizzes. Each entry of quiz history is represented in a way similar to how the flashcards are represented in the Weeblingo application.
Below is the class diagram
for how Score
is represented in Model component.
The UI component, which originally only handles the display of flashcards, now needs to handle the display for scoring history as well.
The following sequence diagram shows how the UI switches display from flashcards to score history. The mechanism of switching UI display the other way around is similar.
Design consideration:
Aspect: How to represent Score
in the application
-
Alternative 1 (current choice): Make
Score
andFlashcard
two separate classes.- Pros: Easy to implement.
- Cons:
- May have the overhead of writing similar code. For instance,
JsonAdaptedFlashcard
andJsonAdaptedScore
. - Changing the GUI display from flashcards to score history may be cumbersome.
- May have the overhead of writing similar code. For instance,
-
Alternative 2: Let
Score
have inheritance relationship withFlashcard
.- Pros: Changing GUI display is easy.
- Cons:
- The design choice is not intuitive (
Score
does not seem to be aFlashcard
and vice versa). - The overhead of maintaining the inheritance is non-trivial.
- The design choice is not intuitive (
[Proposed] Auto-tagging feature for difficult Flashcards
The proposed feature will track user attempts for each flashcard and suggest tagging flashcards that took more than a
set number of attempts as difficult at the end of the quiz. This is facilitated by the check
command triggering an
internal check on the current number of attempts for this flashcard
. Beyond a set number of attempts, the Quiz
will
store the current flashcard
in a separate list to be shown at the end of the quiz. The user can then tag them as
difficult if they so wish to.
Model#Quiz
will implement the following operation:
-
Quiz#updateDifficult
: Adds the currentflashcard
to the list of difficult flashcards.
[Proposed] Tag Search
The tag searching feature will allow users to view and search through the tags that exist, such that they can easily
know what tags are available to be used. Tag
will store a static map of each tag to the number of flashcards with
that tag, updating as needed when a tag is added or deleted.
Model#Tag
will implement the following operations:
-
Tag#showTags()
: Iterates through the map and shows all existing tags. -
Tag#doesTagExist(Tag tag)
: Checks if tag exists. -
Tag#tagCount(Tag tag)
: Searches the map for the number of flashcards with the provided tag. If the tag does not exist, it should return 0.
These operations will be executed through ShowTagsCommand
and SearchTagsCommand
in the Logic
class.
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile:
- Young aspiring J-Culture enthusiast who wants to learn basic Japanese
- Goes to a Japanese Culture Club so is low on time after school
- Interested in learning the Japanese language
- Prefers using flashcards to learn
- Prefers desktop apps over other types
- Prefers typing to mouse interactions
- Is reasonably comfortable using CLI apps
Value proposition: Ability to learn the Japanese language through flashcards in an efficient, fun and interactive manner
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
new user | view valid commands | learn how to use the Weeblingo |
* * * |
user | view a flashcard | |
* * * |
user | view all flashcards | study the flashcards before a quiz session |
* * * |
user | see the answer to a flashcard | check if I answered correctly |
* * * |
user | start a quiz session | assess my knowledge of the Japanese language |
* * * |
hardworking user | start a quiz containing all flashcards | practice all flashcards in a single quiz session |
* * |
user | quiz myself on a specific set of flashcards | practice a specific group of words that I may be bad at |
* * |
busy user | quiz myself on a specific number of flashcards | roughly control how long I spend on the quiz |
* * |
user | add tags to certain flashcards | group flashcards to test myself (e.g. specific coverage for an exam) |
* * |
results-oriented user | know how well I scored on a Quiz | see how many mistakes I made in this Quiz |
* * |
competitive user | see the duration of a Quiz | gauge how fast I am at answering questions |
* * |
user | see my past quiz attempts | track my progress |
Use cases
(For all use cases below, the System is the Weeblingo
and the Actor is the user
, unless specified otherwise)
Use case : UC01 - See the list of flashcards
MSS
- User requests to enter learn mode.
-
Weeblingo shows a list of flashcards on the screen.
Use case ends.
Use case: UC02 - Take a quiz
MSS
- User requests to enter quiz mode.
- Weeblingo shows a new question on the screen.
- User enters and checks his answer.
- Weeblingo shows whether user’s answer is correct/wrong.
- User requests to see the next question.
- Weeblingo removes this question from the list of questions for this session.
- Go to step 2 again.
Extensions
-
2a. All questions have been shown.
-
2a1. Weeblingo informs user that the quiz is over.
Use case ends.
-
-
3a. User already got the question correct.
-
3a1. Weeblingo prompts user to proceed to the next question.
Use case resumes at step 5.
-
-
4a. User got the question wrong.
-
4a1a. User wants to proceed to the next question.
Use case resumes at step 5.
-
4a1b. User wants to reattempt the same question.
Use case resumes at step 3.
-
-
4b. User got the question correct.
-
4b1. Weeblingo prompts user to proceed to the next question.
Use case resumes at step 5.
-
Use case: UC03 - See my past quiz attempts history
MSS
- User requests to see the history of past attempts.
-
Weeblingo shows the history, including relevant details of the quiz attempts.
Use case ends.
Non-Functional Requirements
- The product should work on any mainstream OS as long as it has Java
11
or above installed. - The product should be available for downloads after each GitHub release.
- The product’s size in terms of the final
Jar
released should not exceed 100MB. - The product should be an offline application, which should work regardless of internet connection.
- The product should be able to hold at least 100 flashcards without causing a delay in commands longer than 0.2 seconds.
- The product is not required to handle concurrency resulting from multiple instances of the applications running at the same time, as the product is supposed to support a single user’s usage.
- The product should be open-sourced in the GitHub repo.
- The project is expected to adhere to a schedule that delivers a new iteration every one or two weeks throughout the whole development cycle.
- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) and should be able to accomplish most of the learning faster using commands than using the mouse/GUI.
Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- Question: A Japanese character/word
- Answer: The pronunciation/translation of the Japanese word given in the corresponding question
- Flashcard: An object that can display a question and its answer
- Quiz Session: During a quiz session, flashcards with only question displayed will be shown one by one. Users may chooses to answer or skip the questions. Score and time spent will be recorded.
- Score: Calculated during a quiz session. Calculated by: number of user correct attempts / number of user checks.
Appendix: Instructions for manual testing
Given below are instructions to test the app manually.
Launch and shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
Using the end
command
-
Returning to menu
-
Prerequisites: Not already in menu
-
Test case:
end
while in a quiz session
Expected: The current quiz session is ended and displayed flashcard disappears. -
Test case:
end
while in menu
Expected: Nothing happens. An error message is displayed to the user telling them the app is already in menu. -
Other correct end commands locations to try: while in learn mode, right after ending a Quiz, …
Expected: Returns to menu.
-
Saving data
-
Dealing with corrupted data files
-
Do an initial launch of the application as described in Launch and shutdown segment above. Type
learn
to view all flashcards available. -
Open
current_folder/data/flashcards.json
. - Do some modifications that are possibly malicious.
- Modify a field name of
flashcards.json
. E.g. changequestion
toquestions
- Modify the
tag
value of some flashcard to include characters that are neither alphabetic or numeric. E.g.&*&
,你好世界
. - Modify the
question
value of some flashcard to include latin-specific characters. E.g.Español
.
- Modify a field name of
-
Relaunch the application. Type
learn
to go into thelearn
mode. Original (unmodified) data content should present. -
Close the application and inspect the
flashcards.json
file. Modified parts of the original data content should disappear.
-
-
Dealing with missing data files
-
Delete the
flashcards.json
file, but keep thedata
folder. -
Relaunch the application. Type
learn
to go into thelearn
mode. Original data content should present. -
Close the application and inspect the
data
folder, a newflashcards.json
loaded with content should be present. -
Now delete the
data
folder recursively (i.e. deleting the file(s) inside it as well). -
Repeat the second step.
-
Close the application, and the
data
folder and theflashcards.json
should be present (regenerated).
-