fsrs


Namefsrs JSON
Version 5.1.2 PyPI version JSON
download
home_pageNone
SummaryFree Spaced Repetition Scheduler
upload_time2025-02-09 08:08:25
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT License Copyright (c) 2022 Open Spaced Repetition Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords spaced-repetition flashcard
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <div align="center">
  <img src="https://avatars.githubusercontent.com/u/96821265?s=200&v=4" height="100" alt="Open Spaced Repetition logo"/>
</div>
<div align="center">

# Py-FSRS

</div>
<div align="center">
  <em>🧠🔄 Build your own Spaced Repetition System in Python 🧠🔄   </em>
</div>
<br />
<div align="center" style="text-decoration: none;">
    <a href="https://pypi.org/project/fsrs/"><img src="https://img.shields.io/pypi/v/fsrs"></a>
    <a href="https://pypi.org/project/fsrs/"><img src="https://img.shields.io/badge/python-3.10%2B-blue"></a>
    <a href="https://github.com/open-spaced-repetition/py-fsrs/blob/main/LICENSE" style="text-decoration: none;"><img src="https://img.shields.io/badge/License-MIT-brightgreen.svg"></a>
    <a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json"></a>
</div>
<br />


**Py-FSRS is a python package that allows developers to easily create their own spaced repetition system using the <a href="https://github.com/open-spaced-repetition/free-spaced-repetition-scheduler">Free Spaced Repetition Scheduler algorithm</a>.**


## Table of Contents
- [Installation](#installation)
- [Quickstart](#quickstart)
- [Usage](#usage)
- [Optimizer (optional)](#optimizer-optional)
- [Reference](#reference)
- [Other FSRS implementations](#other-fsrs-implementations)
- [Other SRS python packages](#other-srs-python-packages)
- [Contribute](#contribute)

## Installation
You can install the `fsrs` python package from [PyPI](https://pypi.org/project/fsrs/) using pip:
```
pip install fsrs
```

## Quickstart

Import and initialize the FSRS scheduler

```python
from fsrs import Scheduler, Card, Rating, ReviewLog

scheduler = Scheduler()
```

Create a new Card object
```python
# note: all new cards are 'due' immediately upon creation
card = Card()
```

Choose a rating and review the card with the scheduler
```python
# Rating.Again (==1) forgot the card
# Rating.Hard (==2) remembered the card with serious difficulty
# Rating.Good (==3) remembered the card after a hesitation
# Rating.Easy (==4) remembered the card easily

rating = Rating.Good

card, review_log = scheduler.review_card(card, rating)

print(f"Card rated {review_log.rating} at {review_log.review_datetime}")
# > Card rated 3 at 2024-11-30 17:46:58.856497+00:00
```

See when the card is due next
```python
from datetime import datetime, timezone

due = card.due

# how much time between when the card is due and now
time_delta = due - datetime.now(timezone.utc)

print(f"Card due on {due}")
print(f"Card due in {time_delta.seconds} seconds")

# > Card due on 2024-11-30 18:42:36.070712+00:00
# > Card due in 599 seconds
```

## Usage

### Custom parameters

You can initialize the FSRS scheduler with your own custom parameters.

```python
from datetime import timedelta

# note: the following arguments are also the defaults
scheduler = Scheduler(
    parameters = (
            0.40255,
            1.18385,
            3.173,
            15.69105,
            7.1949,
            0.5345,
            1.4604,
            0.0046,
            1.54575,
            0.1192,
            1.01925,
            1.9395,
            0.11,
            0.29605,
            2.2698,
            0.2315,
            2.9898,
            0.51655,
            0.6621,
        ),
    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 19 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

```python
retrievability = card.get_retrievability()

print(f"There is a {retrievability} probability that this card is remembered.")
# > There is a 0.94 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:

```python
# serialize before storage
scheduler_dict = scheduler.to_dict()
card_dict = card.to_dict()
review_log_dict = review_log.to_dict()

# deserialize from 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

```python
from fsrs import ReviewLog, Optimizer, Scheduler

# load your ReviewLog objects into a list (order doesn't matter)
review_logs = [ReviewLog1, ReviewLog2, ...]

# initialize the optimizer with the review logs
optimizer = Optimizer(review_logs)

# compute a set of optimized parameters
optimal_parameters = optimizer.compute_optimal_parameters()

# initialize a new scheduler with the optimized parameters
scheduler = Scheduler(optimal_parameters)
```

### Optimize desired retention

```python
optimal_retention = optimizer.compute_optimal_retention(optimal_parameters)

# initialize a new scheduler with both optimized parameters and retention
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](https://github.com/open-spaced-repetition/fsrs-rs).

## Reference

Card objects have one of three possible states
```python
State.Learning # (==1) new card being studied for the first time
State.Review # (==2) card that has "graduated" from the Learning state
State.Relearning # (==3) card that has "lapsed" from the Review state
```

There are four possible ratings when reviewing a card object:
```python
Rating.Again # (==1) forgot the card
Rating.Hard # (==2) remembered the card with serious difficulty
Rating.Good # (==3) remembered the card after a hesitation
Rating.Easy # (==4) remembered the card easily
```

## Other FSRS implementations

You can find various other FSRS implementations and projects [here](https://github.com/orgs/open-spaced-repetition/repositories?q=fsrs+sort%3Astars).

## Other SRS python packages

The following spaced repetition schedulers are also available as python packages:

- [SM-2](https://github.com/open-spaced-repetition/sm-2)
- [Leitner System](https://github.com/open-spaced-repetition/leitner-box)
- [Anki Default Scheduler](https://github.com/open-spaced-repetition/anki-sm-2)

## Contribute

If you encounter issues with py-fsrs or would like to contribute code, please see [CONTRIBUTING](https://github.com/open-spaced-repetition/py-fsrs/blob/main/CONTRIBUTING.md).

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "fsrs",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "spaced-repetition, flashcard",
    "author": null,
    "author_email": "Jarrett Ye <jarrett.ye@outlook.com>, Joshua Hamilton <hamiltonjoshuadavid@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/e9/c6/cddf07541edf265a082eec06da2e635dfedef2b5d26e201db30cc18c579d/fsrs-5.1.2.tar.gz",
    "platform": null,
    "description": "<div align=\"center\">\n  <img src=\"https://avatars.githubusercontent.com/u/96821265?s=200&v=4\" height=\"100\" alt=\"Open Spaced Repetition logo\"/>\n</div>\n<div align=\"center\">\n\n# Py-FSRS\n\n</div>\n<div align=\"center\">\n  <em>\ud83e\udde0\ud83d\udd04 Build your own Spaced Repetition System in Python \ud83e\udde0\ud83d\udd04   </em>\n</div>\n<br />\n<div align=\"center\" style=\"text-decoration: none;\">\n    <a href=\"https://pypi.org/project/fsrs/\"><img src=\"https://img.shields.io/pypi/v/fsrs\"></a>\n    <a href=\"https://pypi.org/project/fsrs/\"><img src=\"https://img.shields.io/badge/python-3.10%2B-blue\"></a>\n    <a href=\"https://github.com/open-spaced-repetition/py-fsrs/blob/main/LICENSE\" style=\"text-decoration: none;\"><img src=\"https://img.shields.io/badge/License-MIT-brightgreen.svg\"></a>\n    <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\"></a>\n</div>\n<br />\n\n\n**Py-FSRS is a python package that allows developers to easily create their own spaced repetition system using the <a href=\"https://github.com/open-spaced-repetition/free-spaced-repetition-scheduler\">Free Spaced Repetition Scheduler algorithm</a>.**\n\n\n## Table of Contents\n- [Installation](#installation)\n- [Quickstart](#quickstart)\n- [Usage](#usage)\n- [Optimizer (optional)](#optimizer-optional)\n- [Reference](#reference)\n- [Other FSRS implementations](#other-fsrs-implementations)\n- [Other SRS python packages](#other-srs-python-packages)\n- [Contribute](#contribute)\n\n## Installation\nYou can install the `fsrs` python package from [PyPI](https://pypi.org/project/fsrs/) using pip:\n```\npip install fsrs\n```\n\n## Quickstart\n\nImport and initialize the FSRS scheduler\n\n```python\nfrom fsrs import Scheduler, Card, Rating, ReviewLog\n\nscheduler = Scheduler()\n```\n\nCreate a new Card object\n```python\n# note: all new cards are 'due' immediately upon creation\ncard = Card()\n```\n\nChoose a rating and review the card with the scheduler\n```python\n# Rating.Again (==1) forgot the card\n# Rating.Hard (==2) remembered the card with serious difficulty\n# Rating.Good (==3) remembered the card after a hesitation\n# Rating.Easy (==4) remembered the card easily\n\nrating = Rating.Good\n\ncard, review_log = scheduler.review_card(card, rating)\n\nprint(f\"Card rated {review_log.rating} at {review_log.review_datetime}\")\n# > Card rated 3 at 2024-11-30 17:46:58.856497+00:00\n```\n\nSee when the card is due next\n```python\nfrom datetime import datetime, timezone\n\ndue = card.due\n\n# how much time between when the card is due and now\ntime_delta = due - datetime.now(timezone.utc)\n\nprint(f\"Card due on {due}\")\nprint(f\"Card due in {time_delta.seconds} seconds\")\n\n# > Card due on 2024-11-30 18:42:36.070712+00:00\n# > Card due in 599 seconds\n```\n\n## Usage\n\n### Custom parameters\n\nYou can initialize the FSRS scheduler with your own custom parameters.\n\n```python\nfrom datetime import timedelta\n\n# note: the following arguments are also the defaults\nscheduler = Scheduler(\n    parameters = (\n            0.40255,\n            1.18385,\n            3.173,\n            15.69105,\n            7.1949,\n            0.5345,\n            1.4604,\n            0.0046,\n            1.54575,\n            0.1192,\n            1.01925,\n            1.9395,\n            0.11,\n            0.29605,\n            2.2698,\n            0.2315,\n            2.9898,\n            0.51655,\n            0.6621,\n        ),\n    desired_retention = 0.9,\n    learning_steps = (timedelta(minutes=1), timedelta(minutes=10)),\n    relearning_steps = (timedelta(minutes=10),),\n    maximum_interval = 36500,\n    enable_fuzzing = True\n)\n```\n\n#### Explanation of parameters\n\n`parameters` are a set of 19 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.\n\n`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.\n\n`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=())`\n\n`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.\n\n`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)`.\n\n`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.\n\n### Timezone\n\n**Py-FSRS uses UTC only.** \n\nYou can still specify custom datetimes, but they must use the UTC timezone.\n\n### Retrievability\n\nYou can calculate the current probability of correctly recalling a card (its 'retrievability') with\n\n```python\nretrievability = card.get_retrievability()\n\nprint(f\"There is a {retrievability} probability that this card is remembered.\")\n# > There is a 0.94 probability that this card is remembered.\n```\n\n### Serialization\n\n`Scheduler`, `Card` and `ReviewLog` objects are all JSON-serializable via their `to_dict` and `from_dict` methods for easy database storage:\n\n```python\n# serialize before storage\nscheduler_dict = scheduler.to_dict()\ncard_dict = card.to_dict()\nreview_log_dict = review_log.to_dict()\n\n# deserialize from dict\nnew_scheduler = Scheduler.from_dict(scheduler_dict)\nnew_card = Card.from_dict(card_dict)\nnew_review_log = ReviewLog.from_dict(review_log_dict)\n```\n\n## Optimizer (optional)\n\nIf 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.\n\n### Installation\n\n```\npip install \"fsrs[optimizer]\"\n```\n\n### Optimize scheduler parameters\n\n```python\nfrom fsrs import ReviewLog, Optimizer, Scheduler\n\n# load your ReviewLog objects into a list (order doesn't matter)\nreview_logs = [ReviewLog1, ReviewLog2, ...]\n\n# initialize the optimizer with the review logs\noptimizer = Optimizer(review_logs)\n\n# compute a set of optimized parameters\noptimal_parameters = optimizer.compute_optimal_parameters()\n\n# initialize a new scheduler with the optimized parameters\nscheduler = Scheduler(optimal_parameters)\n```\n\n### Optimize desired retention\n\n```python\noptimal_retention = optimizer.compute_optimal_retention(optimal_parameters)\n\n# initialize a new scheduler with both optimized parameters and retention\nscheduler = Scheduler(optimal_parameters, optimal_retention)\n```\n\nNote: 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](https://github.com/open-spaced-repetition/fsrs-rs).\n\n## Reference\n\nCard objects have one of three possible states\n```python\nState.Learning # (==1) new card being studied for the first time\nState.Review # (==2) card that has \"graduated\" from the Learning state\nState.Relearning # (==3) card that has \"lapsed\" from the Review state\n```\n\nThere are four possible ratings when reviewing a card object:\n```python\nRating.Again # (==1) forgot the card\nRating.Hard # (==2) remembered the card with serious difficulty\nRating.Good # (==3) remembered the card after a hesitation\nRating.Easy # (==4) remembered the card easily\n```\n\n## Other FSRS implementations\n\nYou can find various other FSRS implementations and projects [here](https://github.com/orgs/open-spaced-repetition/repositories?q=fsrs+sort%3Astars).\n\n## Other SRS python packages\n\nThe following spaced repetition schedulers are also available as python packages:\n\n- [SM-2](https://github.com/open-spaced-repetition/sm-2)\n- [Leitner System](https://github.com/open-spaced-repetition/leitner-box)\n- [Anki Default Scheduler](https://github.com/open-spaced-repetition/anki-sm-2)\n\n## Contribute\n\nIf you encounter issues with py-fsrs or would like to contribute code, please see [CONTRIBUTING](https://github.com/open-spaced-repetition/py-fsrs/blob/main/CONTRIBUTING.md).\n",
    "bugtrack_url": null,
    "license": "MIT License\n        \n        Copyright (c) 2022 Open Spaced Repetition\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE.\n        ",
    "summary": "Free Spaced Repetition Scheduler",
    "version": "5.1.2",
    "project_urls": {
        "Homepage": "https://github.com/open-spaced-repetition/py-fsrs"
    },
    "split_keywords": [
        "spaced-repetition",
        " flashcard"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8808ef216ebc0ed08782ad9b852fcd6eceb009964f1bbfa9606c7981189601f0",
                "md5": "85d9b2d6df0219f298732faebd4338d7",
                "sha256": "91e9eaaec7685cea6e86f0ba8a8d26ddb8473d606e60c3dcfd03eba10db92a51"
            },
            "downloads": -1,
            "filename": "fsrs-5.1.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "85d9b2d6df0219f298732faebd4338d7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 17387,
            "upload_time": "2025-02-09T08:08:23",
            "upload_time_iso_8601": "2025-02-09T08:08:23.944959Z",
            "url": "https://files.pythonhosted.org/packages/88/08/ef216ebc0ed08782ad9b852fcd6eceb009964f1bbfa9606c7981189601f0/fsrs-5.1.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e9c6cddf07541edf265a082eec06da2e635dfedef2b5d26e201db30cc18c579d",
                "md5": "e52c8516d5e31ef11374ca67ebd7c232",
                "sha256": "e9a15a2970a3a2d2c465aefe165398768b63a1eb932d04e42670f70d2c3dcd28"
            },
            "downloads": -1,
            "filename": "fsrs-5.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "e52c8516d5e31ef11374ca67ebd7c232",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 24291,
            "upload_time": "2025-02-09T08:08:25",
            "upload_time_iso_8601": "2025-02-09T08:08:25.106111Z",
            "url": "https://files.pythonhosted.org/packages/e9/c6/cddf07541edf265a082eec06da2e635dfedef2b5d26e201db30cc18c579d/fsrs-5.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-09 08:08:25",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "open-spaced-repetition",
    "github_project": "py-fsrs",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "fsrs"
}
        
Elapsed time: 0.40190s