Skip to content

Elixir direct port of open-spaced-repetition py-fsrs

License

Notifications You must be signed in to change notification settings

lulucatdev/fsrs_ex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fsrs_ex (Fsrs)

Direct Elixir port of open-spaced-repetition/py-fsrs (v6.3.0, FSRS-6).

中文说明:这是 py-fsrs v6.3.0 的 Elixir 直接移植版本。

fsrs_ex provides the FSRS scheduler API for Elixir applications with a strong focus on behavior parity with the Python reference implementation.

Highlights

  • FSRS-6 (21 parameters) default model constants
  • Day-based elapsed-time behavior aligned with py-fsrs
  • Scheduler, Card, ReviewLog, Rating, and State modules
  • reschedule_card/3 for replaying historical review logs
  • Cross-language serialization (to_dict/from_dict, to_json/from_json)
  • Python-vs-Elixir parity fixtures and tests included in this repository

Port Scope

This project intentionally ports and aligns with:

  • Source baseline: open-spaced-repetition/py-fsrs v6.3.0
  • Algorithm generation: FSRS-6
  • Defaults: 21 default parameters and bounds-compatible validation
  • Scheduler semantics: review_card, reschedule_card, retrievability behavior
  • Data interoperability: Python-compatible field names and UTC timestamp formatting (+00:00)

For details, see guides/PORTING_POLICY.md.

Installation

Add fsrs_ex to your dependencies:

def deps do
  [
    {:fsrs_ex, "~> 0.1.2"}
  ]
end

Then run:

mix deps.get

Quick Start

alias Fsrs

scheduler = Fsrs.new_scheduler(enable_fuzzing: false)
card = Fsrs.new_card()

{card, review_log} = Fsrs.review_card(scheduler, card, :good)

card.due
review_log.rating

Chinese note: :again | :hard | :good | :easy correspond to FSRS rating buttons.

Scheduler Options

scheduler = Fsrs.new_scheduler(
  desired_retention: 0.9,
  learning_steps: [{:minutes, 1}, {:seconds, 95}, 300],
  relearning_steps: [{:seconds, 90}, {:minutes, 15}],
  maximum_interval: 36500,
  enable_fuzzing: true
)

learning_steps and relearning_steps accept:

  • integer seconds (for example 600)
  • {:seconds, value}
  • {:minutes, value}

Internally they are normalized to seconds.

Serialization and Interop

json = Fsrs.Card.to_json(card)
card2 = Fsrs.Card.from_json(json)

scheduler_map = Fsrs.Scheduler.to_dict(scheduler)
scheduler2 = Fsrs.Scheduler.from_dict(scheduler_map)

Chinese note: the exported data shape is designed for Python interoperability.

Python Parity Testing

This repository includes full parity assets:

  • fixture generator: test/fixtures/generate_py_fixture.py
  • fixture data: test/fixtures/py_fsrs_v6_3_0_fixture.json
  • Elixir parity tests: test/fsrs_py_parity_test.exs

Re-generate fixtures and re-run parity tests:

python3 -m venv .venv
.venv/bin/pip install fsrs==6.3.0
.venv/bin/python test/fixtures/generate_py_fixture.py test/fixtures/py_fsrs_v6_3_0_fixture.json
mix test test/fsrs_py_parity_test.exs

More details: guides/PARITY_TESTING.md.

Release Automation (Makefile)

Use these targets:

make help
make preflight
make publish-interactive

For CI or non-interactive publishing:

export HEX_API_KEY=...
make release

See guides/RELEASE_PROCESS.md.

Pre-release Checklist

Before publishing a new version:

  1. Bump version in mix.exs.
  2. Run make preflight.
  3. Confirm package file list with mix hex.build output.
  4. Ensure docs render correctly (mix docs, inspect doc/index.html).
  5. Publish with make publish (or make publish-interactive).
  6. Create and push a Git tag (for example v0.1.1).

Chinese note: 建议每次发布前都跑 make preflight,避免遗漏格式、测试和文档问题。

HexDocs

Acknowledgements and References

Core Sources

Author and Community

This project is a community Elixir port and is not an official Open Spaced Repetition repository.

License

MIT. See LICENSE.

About

Elixir direct port of open-spaced-repetition py-fsrs

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •