Skip to content

Commit f793a6c

Browse files
authored
Doc/enhance clarity and detail on FSRS usage and examples (#373)
1 parent 9870d69 commit f793a6c

File tree

1 file changed

+88
-18
lines changed

1 file changed

+88
-18
lines changed

README.md

Lines changed: 88 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,111 @@
22

33
[![crates.io](https://img.shields.io/crates/v/fsrs.svg)](https://crates.io/crates/fsrs) ![](https://github.com/open-spaced-repetition/fsrs-rs/actions/workflows/check.yml/badge.svg)
44

5-
This crate contains a Rust API for training FSRS parameters, and for using them to schedule cards.
5+
The Free Spaced Repetition Scheduler ([FSRS](https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Algorithm)) is a modern spaced repetition algorithm. It springs from [MaiMemo's DHP model](https://www.maimemo.com/paper/), which is a variant of the [DSR model](https://supermemo.guru/wiki/Three_component_model_of_memory) proposed by [Piotr Wozniak](https://supermemo.guru/wiki/Piotr_Wozniak).
66

7-
The Free Spaced Repetition Scheduler ([FSRS](https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Algorithm)) is a modern spaced repetition algorithm. It springs from [MaiMemo's DHP model](https://www.maimemo.com/paper/), which is a variant of the [DSR model](https://supermemo.guru/wiki/Three_component_model_of_memory) proposed by [Piotr Wozniak](https://supermemo.guru/wiki/Piotr_Wozniak), the creator of SuperMemo.
8-
9-
FSRS-rs is a Rust implementation of FSRS. It is designed to be used in [Anki](https://apps.ankiweb.net/), a popular spaced repetition software. [Anki 23.10](https://github.com/ankitects/anki/releases/tag/23.10) has already integrated FSRS as an alternative scheduler.
7+
FSRS-rs is a Rust implementation of FSRS with full training support using [Burn](https://github.com/tracel-ai/burn). It also provides simulation capabilities and basic scheduling functionality.
108

119
For more information about the algorithm, please refer to [the wiki page of FSRS](https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Algorithm).
1210

1311
---
1412

1513
## Quickstart
1614

17-
Read [this](https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Optimal-Retention) for an explanation of how to determine the optimal retention for your use case.
15+
### Add the crate
16+
17+
Add FSRS to your project:
18+
19+
```toml
20+
[dependencies]
21+
fsrs = "5.2.0"
22+
```
23+
24+
The scheduling example below also uses `chrono` to track review times:
25+
26+
```toml
27+
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
28+
```
29+
30+
Run `cargo run --example <name>` to see the complete samples ([`schedule`](examples/schedule.rs), [`migrate`](examples/migrate.rs), [`optimize`](examples/optimize.rs)).
31+
32+
### Schedule reviews
1833

1934
```rust
20-
// Pick whichever percentage is to your liking (see above)
21-
let optimal_retention = 0.75;
22-
// Use default parameters/weights for the scheduler
35+
use chrono::{Duration, Utc};
36+
use fsrs::{FSRS, MemoryState};
37+
2338
let fsrs = FSRS::default();
39+
let desired_retention = 0.9;
40+
let previous_state: Option<MemoryState> = None;
41+
let elapsed_days = 0;
42+
43+
let next_states = fsrs.next_states(previous_state, desired_retention, elapsed_days)?;
44+
let review = next_states.good;
45+
46+
let interval_days = review.interval.round().max(1.0) as u32;
47+
let due = Utc::now() + Duration::days(interval_days as i64);
48+
```
49+
50+
Replace `previous_state`/`elapsed_days` with a stored `MemoryState` and the number of days since the prior review when scheduling existing cards. Full example: [`examples/schedule.rs`](examples/schedule.rs).
51+
52+
### Optimize parameters from review logs
53+
54+
```rust
55+
use chrono::NaiveDate;
56+
use fsrs::{ComputeParametersInput, FSRSItem, FSRSReview, compute_parameters};
57+
58+
let history = vec![
59+
(NaiveDate::from_ymd_opt(2023, 1, 1).unwrap(), 3),
60+
(NaiveDate::from_ymd_opt(2023, 1, 5).unwrap(), 4),
61+
];
62+
63+
let mut accumulated = Vec::new();
64+
let mut items = Vec::new();
65+
let mut last = history[0].0;
66+
67+
for (date, rating) in history {
68+
let delta_t = (date - last).num_days() as u32;
69+
accumulated.push(FSRSReview { rating, delta_t });
70+
items.push(FSRSItem {
71+
reviews: accumulated.clone(),
72+
});
73+
last = date;
74+
}
75+
76+
let parameters = compute_parameters(ComputeParametersInput {
77+
// For best results, `train_set` should contain review histories from many cards.
78+
train_set: items,
79+
..Default::default()
80+
})?;
81+
```
2482

25-
// Create a completely new card
26-
let day1_states = fsrs.next_states(None, optimal_retention, 0)?;
83+
Feed the optimizer a vector of `FSRSItem` instances built from your review history; the returned parameters can then be persisted or supplied to schedulers. Full example: [`examples/optimize.rs`](examples/optimize.rs).
2784

28-
// Rate as `hard` on the first day
29-
let day1 = day1_states.hard;
30-
dbg!(&day1); // scheduled as `in 4 days`
85+
### Migrate from SM-2 style data
3186

32-
// Now we review the card 2 days later
33-
let day3_states = fsrs.next_states(Some(day1.memory), optimal_retention, 2)?;
87+
```rust
88+
use fsrs::{FSRS, FSRSItem, FSRSReview};
89+
90+
let fsrs = FSRS::default();
91+
let sm2_retention = 0.9;
92+
let ease_factor = 2.5;
93+
let interval = 10.0;
3494

35-
// Rate as `good` this time
36-
let day3 = day3_states.good;
37-
dbg!(day3);
95+
let initial_state = fsrs.memory_state_from_sm2(ease_factor, interval, sm2_retention)?;
96+
97+
let reviews = vec![
98+
FSRSReview { rating: 3, delta_t: 5 },
99+
FSRSReview { rating: 4, delta_t: 10 },
100+
];
101+
102+
let memory_state = fsrs.memory_state(
103+
FSRSItem { reviews },
104+
Some(initial_state),
105+
)?;
38106
```
39107

108+
Use `memory_state_from_sm2` when you only have the latest SM-2 ease/interval; pass the result as the starting point while you replay any partial review history. Full example: [`examples/migrate.rs`](examples/migrate.rs).
109+
40110
## Online development
41111

42112
You can use <https://idx.google.com/import>.

0 commit comments

Comments
 (0)