Skip to content

Commit

Permalink
add custom args to FSRS class (#46)
Browse files Browse the repository at this point in the history
* add custom args to FSRS class

* bump minor version number
  • Loading branch information
joshdavham authored Jul 17, 2024
1 parent 5136641 commit d3aef27
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 23 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,36 @@ print(f"Card due in {time_delta.seconds} seconds")

## Usage

### Custom scheduler

You can initialize the FSRS scheduler with your own custom weights as well as desired retention rate and maximum interval.

```python
f = FSRS(
w=(
1.14,
1.01,
5.44,
14.67,
5.3024,
1.5662,
1.2503,
0.0028,
1.5489,
0.1763,
0.9953,
2.7473,
0.0179,
0.3105,
0.3976,
0.0,
2.0902,
),
request_retention=0.85,
maximum_interval=3650,
)
```

### Advanced reviewing of cards

Aside from using the convenience method `review_card`, there is also the `repeat` method:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "fsrs"
version = "2.4.0"
version = "2.5.0"
description = "Free Spaced Repetition Scheduler"
readme = "README.md"
authors = [{ name = "Jarrett Ye", email = "[email protected]" }]
Expand Down
9 changes: 7 additions & 2 deletions src/fsrs/fsrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ class FSRS:
DECAY: float
FACTOR: float

def __init__(self) -> None:
self.p = Parameters()
def __init__(
self,
w: Tuple[float, ...] = None,
request_retention: float = None,
maximum_interval: int = None,
) -> None:
self.p = Parameters(w, request_retention, maximum_interval)
self.DECAY = -0.5
self.FACTOR = 0.9 ** (1 / self.DECAY) - 1

Expand Down
53 changes: 33 additions & 20 deletions src/fsrs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,25 +275,38 @@ class Parameters:
maximum_interval: int
w: Tuple[float, ...]

def __init__(self) -> None:
self.request_retention = 0.9
self.maximum_interval = 36500
def __init__(
self,
w: Tuple[float, ...] = None,
request_retention: float = None,
maximum_interval: int = None,
) -> None:
self.w = (
0.4872,
1.4003,
3.7145,
13.8206,
5.1618,
1.2298,
0.8975,
0.031,
1.6474,
0.1367,
1.0461,
2.1072,
0.0793,
0.3246,
1.587,
0.2272,
2.8755,
w
if w is not None
else (
0.4872,
1.4003,
3.7145,
13.8206,
5.1618,
1.2298,
0.8975,
0.031,
1.6474,
0.1367,
1.0461,
2.1072,
0.0793,
0.3246,
1.587,
0.2272,
2.8755,
)
)
self.request_retention = (
request_retention if request_retention is not None else 0.9
)
self.maximum_interval = (
maximum_interval if maximum_interval is not None else 36500
)
91 changes: 91 additions & 0 deletions tests/test_fsrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,94 @@ def test_review_card(self):

print(ivl_history)
assert ivl_history == [0, 5, 16, 43, 106, 236, 0, 0, 12, 25, 47, 85, 147]

def test_custom_scheduler_args(self):

f = FSRS(
w=(
1.14,
1.01,
5.44,
14.67,
5.3024,
1.5662,
1.2503,
0.0028,
1.5489,
0.1763,
0.9953,
2.7473,
0.0179,
0.3105,
0.3976,
0.0,
2.0902,
),
request_retention=0.9,
maximum_interval=36500,
)
card = Card()
now = datetime(2022, 11, 29, 12, 30, 0, 0, timezone.utc)
# scheduling_cards = f.repeat(card, now)
# print_scheduling_cards(scheduling_cards)

ratings = (
Rating.Good,
Rating.Good,
Rating.Good,
Rating.Good,
Rating.Good,
Rating.Good,
Rating.Again,
Rating.Again,
Rating.Good,
Rating.Good,
Rating.Good,
Rating.Good,
Rating.Good,
)
ivl_history = []

for rating in ratings:
# card = scheduling_cards[rating].card
card, _ = f.review_card(card, rating, now)
ivl = card.scheduled_days
ivl_history.append(ivl)
now = card.due
# scheduling_cards = f.repeat(card, now)
# print_scheduling_cards(scheduling_cards)

print(ivl_history)
assert ivl_history == [0, 5, 16, 43, 106, 236, 0, 0, 12, 25, 47, 85, 147]

# initialize another scheduler and verify parameters are properly set
w2 = (
0.1456,
0.4186,
1.1104,
4.1315,
5.2417,
1.3098,
0.8975,
0.0000,
1.5674,
0.0567,
0.9661,
2.0275,
0.1592,
0.2446,
1.5071,
0.2272,
2.8755,
)
request_retention2 = 0.85
maximum_interval2 = 3650
f2 = FSRS(
w=w2,
request_retention=request_retention2,
maximum_interval=maximum_interval2,
)

assert f2.p.w == w2
assert f2.p.request_retention == request_retention2
assert f2.p.maximum_interval == maximum_interval2

0 comments on commit d3aef27

Please sign in to comment.