Overview
FlashCard Pro is an application designed for students who prefer to use a desktop app for managing flashcards. It is optimised for users who are comfortable with Command Line Interface-based interaction.
FlashCard Pro has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC.
Summary of contributions
Major enhancement: added the ability for user to view their statistics.
-
What it does:
-
Allows the user to see their past login sessions, total duration spent in the app, and their test sessions involving each deck.
-
More detailed statistics are also provided, allowing the user to drill down into a granular view of their activity, e.g. login sessions by week.
-
The user can also see their statistics by deck, which is useful if they want to gauge how much time they’re spending reviewing each subject. The average score for test sessions conducted on the deck is also provided, giving the user feedback on their performance.
-
-
Justification:
-
This feature improves the product by allowing the user to reflect on their activity in the app, and whether the time spent was productive.
-
Users can also see their improvement over time and feel encouraged by it.
-
-
Highlights:
-
This enhancement required some degree of analysis of how the application handles various commands, in particular the startup and shutdown of the application, in order to time the duration of each login session.
-
Additions to the
Storage
component and learning to use Haliq’s JSON storage features were required to store and load theSessionList
objects. -
My team’s decision to make
State
non-static influenced me to decoupleUserStats
andDeckStats
fromState
. This required some degree of refactoring quite close to the deadline of the project. -
To get aggregate data from
LocalDateTime
andDuration
objects, I implemented a number of utilities in theDateTimeUtil
class (and some others). I also implementedSessionListUtil
andStatsDisplayUtil
for handling the calculation of average scores and the display ofTableView
objects. The process of writing and testing these utilities was quite enjoyable and increased my confidence in working with Java APIs.
-
The Statistics window contains key statistics like the user’s number of login sessions, duration of login sessions, number of decks, number of cards, and average score for test sessions. It also displays the user’s login sessions in a table format, which can be sorted by clicking on the column headers. Similarly, the user’s decks are summarised in a table. Double-clicking on a table row will open the corresponding deck statistics window.
The Deck Statistics window shows the user’s statistics pertaining to the deck, and all of their test sessions involving the deck in a table format.
Major enhancement: contributions to the GUI of the app.
-
What I’ve done:
-
I was initially responsible for building and maintaining GUI of the app. The GUI I had envisioned was much simpler and had a custom layout — conceptualised in Figma, then built from scratch. It did not use the MVC pattern.
-
However, it was for the better that our team eventually decided to move on to an MVC-based GUI. This allowed us to focus on building the happy path of the app, before working on integrating the GUI and CLI, then making various cosmetic improvements. This new version of the GUI was authored by Timothy (hence, it is no longer my main feature), but I have made a number of improvements since.
-
Justification:
-
Although the application was and would be functional without many of these enhancements I have made, I believe they help to increase the usability of the application. For example, the box containing the MCQ options the user has inputted was previously too small. I have changed it to expand and show all MCQ options by default.
-
To see some more examples of my work, refer to the table below.
-
Cosmetic changes help make our app more appealing to the user and appear more polished overall.
-
-
Planned future enhancements:
-
For scrollable content, set the default scrollbar position to the top, rather than the bottom, when dealing with scrollable content. This was something that troubled me for a while, but I did not manage to fix in the end.
-
Wrap the cards in a deck within a scrollable pane, so that the whole layout will fit in view.
-
-
Highlights:
-
From my first baby steps in working with GUIs during the individual project, I can safely say that I have learnt a great deal since. In particular, I am now more familiar with the JavaFX library.
-
I can now build a JavaFX GUI (albeit a simpler one) programmatically, without using SceneBuilder, as I have done in the earlier stages of the project.
-
I can also author new components via SceneBuilder (such as
StatisticsWindow
) and make significant changes to existing components (such asMainWindow
and the various displays). By referring to the API, I was able to overcome a number of challenges to achieve my desired behaviour (e.g. components being laid out with appropriate padding, preserving the size and scale of components when the window is resized). -
I have also designed a different layout for my statistics windows, consisting of big numbers with labels, which is more creative and visually appealing than my initial design, which displayed the information in a bland way.
-
-
My old design for the statistics window, which has since been substantially improved, as my comfort level with JavaFX has increased. See above for the new statistics window.
My initial design work on Figma.
The following table provides a summary of some of my GUI enhancements:
Description | Old screenshot | Updated screenshot |
---|---|---|
Improve appearance of code editor windows |
||
Allow MCQ options in the "add card" and "edit card" displays to expand, instead of using a scroll pane. |
||
Same as above, but for Java card test cases. Also added prompt text to help user with inputting test cases. |
||
Set a constrained minimum size for the application window, to maintain visibility when the window is resized by the user. |
The window can be resized beyond reasonable limits. |
The window maintains its minimum size. |
Increase the size of the question and answer text areas in the "add card" and "edit card" displays, allowing for user-friendly scrolling and multi-line input. |
||
Modify the display of the card in a test, so that long questions and MCQ options display as expected. |
|
|
Change the display of cards in a deck to become scrollable, flexible-width, and display long questions correctly. |
||
Improve the appearance of the result popup that appears upon completing a test. Also, add the app icon to all popup windows. |
-
Code contributed: [Functional code] [Test code for utilities] [Test code for other statistics classes]
-
Other contributions:
-
Team tasks:
-
Updated the app’s icon, including for all popup windows.
-
Also updated the title of JS and Java editors and playgrounds to include "FlashCard Pro:" as a prefix.
-
-
Project management:
-
Wrote issues upon discovering bugs and assigned them to respective team members.
-
Went through the issues from PE dry run and assigned them to respective team members.
-
-
Documentation:
-
I authored the Introduction section of the User Guide, as I was quite involved in the initial conceptualisation of the project. See Contributions to the User Guide below.
-
Subsequently, I made non-trivial improvements to the clarity of the writing throughout the User Guide. In particular, I abstracted out the What is a flashcard? and Interacting with flashcards sections from the Introduction.
-
I also helped to clean up various sections of the User Guide, especially in the first draft, to make sure they adhered to a consistent format.
-
I documented my own features (Statistics) in the Developer Guide. See Contributions to the Developer Guide below.
-
-
Community:
-
PRs reviewed (with non-trivial review comments): #250
-
-
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. |
Introduction
FlashCard Pro is an application designed for students who prefer to use a desktop app for managing flashcards. It is also useful for teachers who would like to provide resources, in the form of custom flashcard decks, to support their students’ learning.
FlashCard Pro is optimised for users who are comfortable with Command Line Interface-based interaction, allowing them to work more efficiently than with traditional Graphical User Interface (GUI)-based flashcard apps, while still being able to use their flashcards in a familiar GUI format.
What is a flashcard?
Flashcards are containers for information. Each card has a “front” and a “back”. One recommended use case is such: the user stores a question on the “front” of the card, and the answer on the “back”.
Interacting with flashcards
After sets of flashcards (known as “decks”) have been created, the user can interact with the flashcards in various ways. For example, they may test themselves on the content of the decks via timed and untimed tests. For ordinary cards with a front and back, the user can gauge their own understanding of the material by pressing either the "I got it right!" or "I got it wrong :(" buttons on the back of the flashcard.
Other types of flashcards support more advanced interactions. Cards with multiple choices for their answers will prompt the user to select an answer, and the app will automatically determine if the answer is correct.
At the end of each test, FlashCard Pro will provide the user with a score. Comprehensive statistics on the user’s test sessions and login sessions are recorded, which can be accessed via the Statistics menu in FlashCard Pro. The user may use these statistics to assess the frequency of their usage and their performance over time. Statistics are also provided on each card in a deck, so that the user can identify specific cards they may have problems with [coming in v2.0].
As with physical flashcards, the flashcards in FlashCard Pro can be shuffled, used in reverse, mixed between decks, etc [coming in v2.0]. Unlike physical flashcards, flashcards in FlashCard Pro are dynamic, offering a range of possibilities from traditional memorisation-type uses, to support for learning programming.
With FlashCard Pro’s Java and JavaScript cards, teachers can define basic coding problems for their students. Based on the test cases provided by the teachers, FlashCard Pro will evaluate the output of the student’s solution, allowing students to gauge their own coding knowledge, and teachers to evaluate their students’ progress. Test decks can be passed easily from student to teacher, as they are stored in convenient, lightweight JSON files which can be imported or exported natively in FlashCard Pro.
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. |
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.
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
.
-
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.
-