Py-FSRS
🧠🔄 Build your own Spaced Repetition System in Python 🧠🔄
Py-FSRS is a python package that allows developers to easily create their own spaced repetition system using the Free Spaced Repetition Scheduler algorithm.
Table of Contents
Installation
You can install the fsrs
python package from PyPI using pip:
pip install fsrs
Quickstart
Import and initialize the FSRS scheduler
from fsrs import Scheduler, Card, Rating, ReviewLog
scheduler = Scheduler()
Create a new Card object
card = Card()
Choose a rating and review the card with the scheduler
rating = Rating.Good
card, review_log = scheduler.review_card(card, rating)
print(f"Card rated {review_log.rating} at {review_log.review_datetime}")
See when the card is due next
from datetime import datetime, timezone
due = card.due
time_delta = due - datetime.now(timezone.utc)
print(f"Card due on {due}")
print(f"Card due in {time_delta.seconds} seconds")
Usage
Custom parameters
You can initialize the FSRS scheduler with your own custom parameters.
from datetime import timedelta
scheduler = Scheduler(
parameters = (
0.2172,
1.1771,
3.2602,
16.1507,
7.0114,
0.57,
2.0966,
0.0069,
1.5261,
0.112,
1.0178,
1.849,
0.1133,
0.3127,
2.2934,
0.2191,
3.0004,
0.7536,
0.3332,
0.1437,
0.2,
),
desired_retention = 0.9,
learning_steps = (timedelta(minutes=1), timedelta(minutes=10)),
relearning_steps = (timedelta(minutes=10),),
maximum_interval = 36500,
enable_fuzzing = True
)
Explanation of parameters
parameters
are a set of 21 model weights that affect how the FSRS scheduler will schedule future reviews. If you're not familiar with optimizing FSRS, it is best not to modify these default values.
desired_retention
is a value between 0 and 1 that sets the desired minimum retention rate for cards when scheduled with the scheduler. For example, with the default value of desired_retention=0.9
, a card will be scheduled at a time in the future when the predicted probability of the user correctly recalling that card falls to 90%. A higher desired_retention
rate will lead to more reviews and a lower rate will lead to fewer reviews.
learning_steps
are custom time intervals that schedule new cards in the Learning state. By default, cards in the Learning state have short intervals of 1 minute then 10 minutes. You can also disable learning_steps
with Scheduler(learning_steps=())
relearning_steps
are analogous to learning_steps
except they apply to cards in the Relearning state. Cards transition to the Relearning state if they were previously in the Review state, then were rated Again - this is also known as a 'lapse'. If you specify Scheduler(relearning_steps=())
, cards in the Review state, when lapsed, will not move to the Relearning state, but instead stay in the Review state.
maximum_interval
sets the cap for the maximum days into the future the scheduler is capable of scheduling cards. For example, if you never want the scheduler to schedule a card more than one year into the future, you'd set Scheduler(maximum_interval=365)
.
enable_fuzzing
, if set to True, will apply a small amount of random 'fuzz' to calculated intervals. For example, a card that would've been due in 50 days, after fuzzing, might be due in 49, or 51 days.
Timezone
Py-FSRS uses UTC only.
You can still specify custom datetimes, but they must use the UTC timezone.
Retrievability
You can calculate the current probability of correctly recalling a card (its 'retrievability') with
retrievability = scheduler.get_card_retrievability(card)
print(f"There is a {retrievability} probability that this card is remembered.")
Serialization
Scheduler
, Card
and ReviewLog
objects are all JSON-serializable via their to_dict
and from_dict
methods for easy database storage:
scheduler_dict = scheduler.to_dict()
card_dict = card.to_dict()
review_log_dict = review_log.to_dict()
new_scheduler = Scheduler.from_dict(scheduler_dict)
new_card = Card.from_dict(card_dict)
new_review_log = ReviewLog.from_dict(review_log_dict)
Optimizer (optional)
If you have a collection of ReviewLog
objects, you can optionally reuse them to compute an optimal set of parameters for the Scheduler
to make it more accurate at scheduling reviews. You can also compute an optimal retention rate to reduce the future workload of your reviews.
Installation
pip install "fsrs[optimizer]"
Optimize scheduler parameters
from fsrs import ReviewLog, Optimizer, Scheduler
review_logs = [ReviewLog1, ReviewLog2, ...]
optimizer = Optimizer(review_logs)
optimal_parameters = optimizer.compute_optimal_parameters()
scheduler = Scheduler(optimal_parameters)
Optimize desired retention
optimal_retention = optimizer.compute_optimal_retention(optimal_parameters)
scheduler = Scheduler(optimal_parameters, optimal_retention)
Note: The computed optimal parameters and retention may be slightly different than the numbers computed by Anki for the same set of review logs. This is because the two implementations are slightly different and updated at different times. If you're interested in the official Rust-based Anki implementation, please see here.
Reference
Card objects have one of three possible states
State.Learning
State.Review
State.Relearning
There are four possible ratings when reviewing a card object:
Rating.Again
Rating.Hard
Rating.Good
Rating.Easy
API Documentation
You can find additional documentation for py-fsrs here.
Other FSRS implementations
You can find various other FSRS implementations and projects here.
Other SRS python packages
The following spaced repetition schedulers are also available as python packages:
Contribute
If you encounter issues with py-fsrs or would like to contribute code, please see CONTRIBUTING.