Flashcard App NEA
Analysis
Scope [draft]
Spaced repetition is the scientifically-proven most efficient way to improve memory recall when studying. Algorithms like the SuperMemo 2 algorithm employ a combination of active recall strategies and timing between recalls to help users memorise information in the most efficient way possible.
However, the majority of digital tools used to implement spaced repetition are too verbose in terms of functionality, and users would benefit from a more abstracted version of a program like Anki which is far simpler to use and is instantly available to users.
One problem with Anki is that it does not enable the simple review of flashcard decks. It is too rigid to the spaced repetition system and its settings for cramming and deck review are too complicated to use and require technical setup. The program should have a default spaced repetition mode and others, like a ‘cram mode’, to improve the user experience.
The Anki UI is also rather unpleasant and requires some knowhow to use. In contrast, the new app’s UI will be sleek, and the SwiftUI system will help me to synchronise seamless user interfaces on both iPhone and Mac devices.
https://super-memory.com/english/ol/sm2.htm
Critical Path Prototype
1. Flashcard setup and deck management
Requirements:
- Users can create, edit and delete flashcards.
- These flashcards can be organised into decks.
- UI for card creation is clear.
Measurements:
- Users can add flashcards without errors.
- Decks and cards are saved, and reload correctly upon reopening the app.
- Beta testers find the process simple.
Notes:
Users tend to feel overwhelmed by the Anki card creation process, which requires a simpler approach.
Standard study mode
Requirements:
- Allow users to study their cards in an order that doesn’t depend on the spaced repetition review dates.
- Enable sorting and shuffling of decks.
Measurements:
- Users can study any card (or a selection of cards) in manual study mode.
- Cards are presented to the user in the order of their choosing.
Spaced repetition study mode
Requirements:
- Implement the SuperMemo2 (SM-2) algorithm.
- Allow users to review each flashcard intuitively (wrong, easy, hard).
- Update the next review date, and keep algorithm parameters up to date.
Measurements:
- Cards are presented to the users in the order computed by the SM-2 algorithm.
- The algorithm understands the reviews given by the user after each recall, and spaces cards accordingly.
- Users can choose between the manual study mode and the spaced repetition mode without either one impeding on the other.
Mode switching
Requirements:
- Enable users to study the same decks in both spaced and standard modes.
- Ensures that the SM-2 algorithm data and parameters persist across modes.
Measurements:
- Beta testers report it is simple to choose between modes and requires very little setup.
- Switching modes does not lose data or functionality.
Improved, simple UI/UX
Requirements:
- Clean and modern design which is minimal, bright, and contains large, rounded elements.
- Program is functional without overwhelming the user.
Measurements:
- Positive results of beta testing. Users get the gist of the program quickly, finding it clean, intuitive and approachable.
Progress tracking
Requirements:
- Provide simplified insights graphically, using SwiftCharts.
Measurements:
- Beta testers can identify important metrics related to their study through graphs.
Notifications
Requirements:
- Send spaced repetition mode users reminders to review due cards.
- Allow users to toggle notifications on and off.
Data management
Requirements
- Store data using SQLite.
- Ensure data remains persistent across sessions, devices and accounts.
Performance adjustments
Requirements:
- Use efficient data fetching and implement lazy loading.
Embellishments
Requirements:
- Allow users to switch between light and dark modes.
- Allow users to incorporate LaTeX / MathJax math formatting into their cards.
Research
The third-party end user is preferably someone coming from a non-spaced repetition system like Quizlet. They want to receive the same ease-of-use and UI of Quizlet, but without the steep learning curve of Anki.
The first critical activities are to find proof of concept in certain areas - namely, the spaced repetition algorithm and the UI. From here, functionality needs to be included. This involves:
- A user login for synchronising devices
- A smooth UI that transfers between iPhone and Mac via SwiftUI
- A competent backend for storing user flashcards
- The implementation of non-spaced review modes (card-by-card cramming, complete deck review. The deck review system for Anki is inefficient).
- Adding LaTeX capability to flashcards where users can include mathematical notation in their flashcards.
- Use SwiftCharts to visualise learning data
Swift app design
This is further down the line - currently trying to get proof of concept with the spaced repetition idea, then if that fails, the regular flashcard idea.
SuperMemo2
I’ve found details of the SuperMemo2 algorithm in Delphi, and it will just be a case of translating the algorithm to Swift and making it compatible with the structure of the Card class.
Planning the Backend
Swift database management can be carried out with SQLite. I will be creating a fully normalised database along with an entity relationship diagram to represent each table.
User authentication
Added flashcard functionality (LaTeX, images, text formatting)
User requirements
Probable user suggestions:
- Intuitive and easy to use
- UI/UX is simpler than Anki; similar to Quizlet but with the potential for more analytical features
- User able to analyse historical recall performance to see any memory improvements aided by the app
- Simple to add, remove and edit flashcards and their respective decks
- User should be able to format their flashcards with images, highlighting, bold text, LaTeX equations etc.
Documented Design
Prototyping the flashcard mechanism
As identified in the analysis section, I decided that the first approach to make would be to prototype the flashcard mechanism, and go on to implement the SuperMemo2 spaced repetition algorithm.
I thought the most plausible way to go about this is to write a console app in a Swift playground environment to demonstrate how the classes would interlink.
I knew from the outset it would be best to represent the decks and cards as classes. Logically, this makes sense, and slots in perfectly with object oriented design principles. For example, it is a natural approach to represent the relationship between a deck and its cards as a composition relationship. A card cannot exist independently of a deck, and a deck is made up of cards. This sets up a strong relationship between the two that can be modelled using the object-oriented paradigm.
However, it arose that some operations require control over the collection of decks. This requires a more abstract class model, which contains methods that oversee CRUD operations on the collection of decks.
To do this, I modelled a DeckManager class composed of decks, which cannot exist independently of this DeckManager class. There is a single, centralised instance of DeckManager which handles all deck modifications, so using a class instead of a structure in Swift means changes made to the DeckManager will be reflected consistently, and maintain a shared state across different parts of the app. This difference was explained in the Apple Developer Documentation.
Adapting and integrating the SM-2 algorithm
Once I had proven the flashcard app prototype to be effective, I began to approach implementing the SuperMemo2 algorithm. The most efficient way to integrate it into the program was rather simple - the algorithm can be reduced to a subroutine that calculates the optimal time for the card to be next reviewed. For optimal memorisation, the user should review the flashcard the moment it is due, which is why push notifications will be implemented to remind the user of cards they have due for review (potentially in bulk - notification for each one get annoying).
Need to explain how EF is connected to the thing
The formula for calculating the easiness factor of a card is as follows, according to the creators of SM-2:
Where EF is the easiness factor, and q is a survey from 0-5 rating the difficulty of the recall:
- 5: perfect response
- 4: correct response after a hesitation
- 3: correct response recalled with serious difficulty
- 2: incorrect response; where the correct one seemed easy to recall
- 1: incorrect response; the correct one remembered
- 0: complete blackout
While the amount of variation in the user inputs regarding difficulty makes for a more flexible and accurate algorithm, this makes the user experience rather unpleasant as it requires them to juggle metacognition with actually recalling the answers in the first place. Anki, for instance, uses four, being labelled Again, Hard, Good and Easy.
Anki’s system of response is simpler for users to get the hang of. However, while using it I often found it hard to distinguish between what ‘Good’ and ‘Easy’ felt like, and whether ‘Good’ and ‘Hard’ are too similar as well, as I instinctively felt like a difficult recall (which makes sense as Hard) was Good, too.
Therefore, I think the perfect approach is to remove this Good label and leave Again, Easy and Hard. Users can quickly and easily distinguish between cards that feel Easy and Hard to recall, reducing the amount of metacognition required to respond and update the SM-2 algorithm.
Modifying the number of values of q from 6 to 3 required a logical approach. The first idea that came to mind was to see how the easiness factor changes with q. There was no real way to identify the changes to make without analysing each individual value - as q is a discrete value, this was quite simple, and I chose to view each value graphically using Desmos Graphic Calculator.
As we can see, a perfect response is the only response that yields an increase in the easiness factor, therefore q = 5 must be included as a valid difficulty score, and will be the input for an ‘Easy’ response from the user.
This leaves the other two. I thought it logical for q = 3 to be a valid response too, as my idea of a ‘Hard’ response from the user corresponds with the original SM-2 definition of a ‘correct response recalled with [serious] difficulty’.
Choosing whether to use q = 1 or q = 0 for an incorrect response proved to be less obvious. In the end, I reasoned that using q = 1 results in a more forgiving penalty than q = 0, which provides users with a more gentle learning curve on cards and, therefore, a more flexible user experience.
To visualise the process, I put together a flowchart of the algorithm and its implementation, including a simple subroutine that manages the user input. This procedure can be embedded into the class definition of a card - if a card is retrieved, then at this stage it makes sense for the card to handle those operations itself with methods called on its instance.
The procedure also takes care to keep a running list of reviewed cards, allowing users to see their card history. This is also important cause decks may be updated only at the end of review to reduce the number of CRUD operations necessary.
Prototyping the UX