open-spaced-repetition / rs-fsrs

Rust-based Scheduler for FSRS
MIT License
22 stars 4 forks source link

Rust FSRS Refactor #1

Closed GraesonB closed 1 year ago

GraesonB commented 1 year ago

I'm using FSRS in my Tauri app, so I rewrote the rust library to be a little more readable and conventional. Since I'll be using this, I can continue to update and maintain this repo too if needed. This refactor still includes scheduling all possible ratings in order to ensure the easy interval > good interval > hard interval :-)

Here's how the refactored API works:

use chrono::Utc;
use fsrs::{FSRS, Card, Rating::Easy};

fn main() {
    // Init to default weights, if using custom weights FSRS::new(params: Parameters) can be used.
    let fsrs = FSRS::default();

    let card = Card::new();

    // fsrs.schedule returns a ScheduledCards struct that has a select_card method.
    let scheduled_cards = fsrs.schedule(card, Utc::now());
    let updated_card = scheduled_cards.select_card(Easy);

    println!("{}", updated_card.scheduled_days);
}

As a user of FSRS, this API is intuitive to me, however, it may not be intuitive to others. So please, let me know what you think. Interval and state tests are passing.

L-M-Sherlock commented 1 year ago

Thanks for your contribution! I will review the code.

L-M-Sherlock commented 1 year ago

I find that save_log() is never used/tested. Do you plan to store ReviewLog in your app? I think it is important, because FSRS is adaptive when the model could be trained by review logs. We are developing a lib for that: https://github.com/open-spaced-repetition/fsrs-optimizer-burn

GraesonB commented 1 year ago

Oh right, I forgot to include it in the code snippet there, but I absolutely plan on using it in my app. I do have some experience with deep learning/ sequence models, so I'd love to help out on that too.

When saving a log, do you save it before the review or after the review?

L-M-Sherlock commented 1 year ago

When saving a log, do you save it before the review or after the review?

After. Because we don't know the rating given by the user before the review.

GraesonB commented 1 year ago

Right okay, but the card state should be it's state before the review, correct? And all the other data in the log comes from after the rating is given?

L-M-Sherlock commented 1 year ago

Right okay, but the card state should be it's state before the review, correct? And all the other data in the log comes from after the rating is given?

Yeah. Revlog should record these information:

  1. rating: the user's feedback in current review (after)
  2. elapsed_days: how many days have elapsed since the last review (before)
  3. scheduled_days: how many days scheduled by current review (after)
  4. state: the state of card before current review (before)
  5. reviewed_date: when does current review happen (after)
GraesonB commented 1 year ago

Thank you, this is very helpful.

GraesonB commented 1 year ago

I've added review logs that can be accessed via the log field on the updated_card's struct

use chrono::Utc;
use fsrs::{FSRS, Card, Rating::Easy};

fn main() {
    let fsrs = FSRS::default();

    let card = Card::new();
    let scheduled_cards = fsrs.schedule(card, Utc::now());

    let updated_card = scheduled_cards.select_card(Easy);

    println!("{:?}", updated_card.log);
}

However, I was trying to write a test for logs using the python lib as the source of truth, but I'm not sure it's behaving as expected or not. I made an issue here: https://github.com/open-spaced-repetition/py-fsrs/issues/15

L-M-Sherlock commented 1 year ago

However, I was trying to write a test for logs using the python lib as the source of truth, but I'm not sure it's behaving as expected or not. I made an issue here:

I recommend using go-fsrs as the source of truth. Because, to my best knowledge, no app uses the python lib.

GraesonB commented 1 year ago

Added a log test to match the log outputs of the go-fsrs lib and it's passing :-)

GraesonB commented 1 year ago

Awesome, sounds good! Thanks :-)

AlexErrant commented 1 year ago

Sorry for being offtopic, but

I'm using FSRS in my Tauri app

@GraesonB is your app open source?

GraesonB commented 1 year ago

@AlexErrant At the moment I don't have plans to open source it, but if you have questions regarding development with Tauri/FSRS feel free to ask. My email is on my GH profile