# Spaced Repetition System

## Objective

To get more experience working on complex Java programs combining multiple classes, files, exceptions and the use of the Java API.

For this project, you will create a flash-card like program that will allow users to study things they wish to memorize. The program will represent a flash card containing a question, such as "What is the capital of Morocco?"; and an answer, such as "Rabat".

The program will not ask the user to type the answer in, or check if they got it right. Instead, it will display the question and then just wait for the user to show they're ready by pressing enter. It will then show the user the answer and ask them if they got it right. Since the program is intended for self-study, there's no reason for the user to lie!

The cards will be organized into multiple decks. For instance, we might have one deck for world capitals, another for German verbs, and a third for the names of human bones. Each deck will be stored in a file. The program will let us study the cards in a deck, add new cards to a deck, and create new decks.

## Spaced Repetition

This program will also keep track of when each card is due to be studied again. The more somebody gets a question wrong, the more often they will need to review it. Rather than just asking if someone got the question right or wrong, we will actually provide them with four options:

• Easy
• Correct
• Difficult
• Wrong

Questions that are easy will not be due again for longer than questions that were difficult, with "correct" ones somewhere in between. Questions the user gets wrong will be repeated again in this same study session until they get them right.

This idea is called Spaced repetition and has been shown to be an effective way to memorize information. The program Anki is an example of a spaced repetition program.

To implement this, each card will store the number of days between reviews. As the user gets the card correct, this number will increase. It will start at 1, then perhaps go to 2, then 4, then 7, then 13, and so on. In addition to storing this number, each Card will store a due date. I recommend using Java's LocalDate class for this purpose.

Each time a user answers a question, the days between study will be updated. There are many ways we can do this, but the following scheme will work pretty well:

• If they report that the question is easy, then:
numDays = round((numDays + 1) * 1.5)
• If they report that they got the question correct, then:
numDays = round((numDays + 1) * 1.25)
• If they report that the question is difficult, then:
numDays = round((numDays + 1) * 1.1)
• If they get the question wrong, then:
numDays = 0

## Deck File Format

The decks will be stored in a directory called "decks", with a separate file for each deck. The files will have the ".deck" extension. You can look at my decks directory which has three decks. One has some random Spanish words in it, one has all of the capital cities of the world, and one has all of the elements in the periodic table.

Here are the first few lines of decks/spanish.deck:


camisa
shirt
3
2022-02-16
false

mono
monkey
13
2022-02-26
false


The information for each card takes 5 lines:

1. The "question" shown to the user. In the first case this is the Spanish word camisa.
2. The answer to the question, which the user is supposed to remember. In the first case, it's shirt, which is the meaning of camisa.
3. The number of days the next review is passed the previous one. In this case, the camisa card is at 3 days between reviews.
4. The due date for the card to be studied again. The format is YYYY-MM-DD. The first card is due on February 16, 2022. Combined with the last detail, we can surmise it was last studied on the 13th of February.
5. Whether or not the card is new or not. A card is new if it has never been studied before. As soon as it is reviewed, it is marked as no longer being new. The purpose of this is to prevent a user from being overwhelmed with new cards. When the user studies a deck, only 10 new cards are given, in addition to the old ones that are due for review.

There is one blank line after every card in the file. This just makes the file easier to read should you open it with a text editor.

## Program Operation

Your program provides three main features, which will interact with these deck files:

1. Studying a deck. To do this, you will list which deck files are available, and let the user select one. You will load the deck, and shuffle it. Then go through each card. If it is due, show it to the user, get their response and update the Card's day and due date fields. You'll need to keep track of how many new cards you showed them, limiting it to 10. All non-new cards that are due should be reviewed. When the review is done, you will write all of the cards back into the file. That way, the user's progress is saved.
2. Adding cards. For this action, you will list which decks are available, again letting the user choose one. You will then ask the user for questions and answers, make them into new cards (with 0 for the days between study and a due date of today), and add them to the deck. Users should be able to add multiple cards to a deck in one go (without having to re-choose the deck). After the user is done adding cards, the deck should be written to the file.
3. Creating a deck. To add a deck, ask the user for the name, and create a file for it in the "decks" directory, with the ".deck" file extension. If there is no decks directory, you should create it. Write the empty file when this is done so that it can be later pulled up for adding cards.

## Design

Here is a design you can use as a starting place for this project.

You may add other methods to the classes as well.

## A Few Other Points

• In my version of this program, I paused the program for a few seconds. You can see the pause method in our Pig program to review how to do this.
• I also wanted to clear the screen between each question. Frustratingly, there is no reliable way to do this in Java that will work in every terminal. As a work-around, I just printed out a hundred new lines.
• You will need to look over the LocalDate documentation page to see how to use it. Learning to read these pages and find what methods you need and how they work is an important skill.
• You will also need to find how to list all of the .deck files in the decks directory, and create the decks directory if it does not exist. You can research how to do each of these tasks.

## Running my Solution

You can download my solution as SRS.jar. You can run this program from within IntelliJ by copying it into your project directory. Then right-click the .jar file and choose "Run SRS.jar":

You can also download the deck files and place them in your project directory so that you can use them for testing.

## General Requirements

When writing your program, also be sure to:

• Put each class/enum in its own file.
• Always use capital letters to begin a class or enum name, and lower-case letters to begin method and variable names.
• Your code should include comments — at least one for each class explaining its purpose, and one for each method explaining what its job is.
• All instance variables should be private.
• Your code should be consistently indented.
• Your program should not crash with an exception under any scenario.