open-spaced-repetition / py-fsrs

Python Package for FSRS
https://pypi.org/project/fsrs/
MIT License
145 stars 21 forks source link

Cards are moved to Review too quickly #63

Open geomags3 opened 1 month ago

geomags3 commented 1 month ago

Hi,

Thanks so much for the great algorithm and implementation—it's really cool!

I’d like to use it in my app, but I’ve noticed an issue. It moves new cards to "Review" and increases the Due time too quickly. When I compared it to my Anki app with the same settings, the results were quite different:

image

Anki app:

  1. Added a new card
  2. Again (<1m), Hard (<6m), Good (<10m), Easy ( 7d) -> Again
  3. Again (<1m), Hard (<6m), Good (<10m), Easy ( 2d) -> Hard
  4. Again (<1m), Hard (<6m), Good (<10m), Easy ( 2d) -> Good
  5. Again (<1m), Hard (<10m), Good (<1d), Easy ( 2d) -> Hard
  6. Again (<1m), Hard (<10m), Good (<1d), Easy ( 2d) -> Easy
  7. Moved to Review

py-fsrs script

test_w = (
    0.5614,
    1.2546,
    3.5878,
    7.9731,
    5.1043,
    1.1303,
    0.8230,
    0.0465,
    1.6290,
    0.1350,
    1.0045,
    2.1320,
    0.0839,
    0.3204,
    1.3547,
    0.2190,
    2.7849,
    0.4891,  # not used in the Anki app
    0.6468,  # not used in the Anki app
)

f = FSRS(w=test_w)
card = Card()
now = datetime.now(timezone.utc)

ratings = (
    Rating.Again,
    Rating.Hard,
    Rating.Good,
    Rating.Hard,
    Rating.Easy,
)

for rating in ratings:
    card, _ = f.review_card(card, rating, now)
    print(f"Rating: `{Rating(rating).name}` -> State: `{State(card.state).name}`,\t+{card.due - now}  Due: {card.due}, Difficulty: {card.difficulty}, Reps: {card.reps}, Lapses: {card.lapses}")
Rating: `Again` -> State: `Learning`,   +0:01:00  Due: 2024-09-20 19:09:43.358569+00:00, Difficulty: 5.1043, Reps: 1, Lapses: 0
Rating: `Hard` -> State: `Learning`,    +0:10:00  Due: 2024-09-20 19:18:43.358569+00:00, Difficulty: 5.698180550000001, Reps: 2, Lapses: 0
Rating: `Good` -> State: `Review`,  +1 day, 0:00:00  Due: 2024-09-21 19:08:43.358569+00:00, Difficulty: 5.479715154425001, Reps: 3, Lapses: 0
Rating: `Hard` -> State: `Review`,  +1 day, 0:00:00  Due: 2024-09-21 19:08:43.358569+00:00, Difficulty: 6.056138899744239, Reps: 4, Lapses: 0
Rating: `Easy` -> State: `Review`,  +3 days, 0:00:00  Due: 2024-09-23 19:08:43.358569+00:00, Difficulty: 5.036297940906132, Reps: 5, Lapses: 0
joshdavham commented 1 month ago

Hi Nikita

The behavior you're seeing in Anki is likely due to the Learning steps that you have set in your deck options. Currently this implementation does not support learning/relearning steps the way Anki does.

We will be adding more scheduler options in the future however. Would the ability to configure learning steps be something you'd like to see in a future version?

geomags3 commented 1 month ago

Hi Josh

Thank you for the quick response.

Yes, I'd love to be able to configure learning steps in the future. But for the time being, can I tweak these steps in the library?

I see there are only two places with hardcoded "minutes" in the code:

and schedule method:

        self.again.due = now + timedelta(minutes=5)
        if hard_interval > 0:
            self.hard.due = now + timedelta(days=hard_interval)
        else:
            self.hard.due = now + timedelta(minutes=10)

Can I set self.again.due to now + timedelta(minutes=1), and 10 mins for self.hard.due, or is it not that simple?

joshdavham commented 1 month ago

Could you be a bit more specific? Which lines exactly are you hoping to change?