open-spaced-repetition / dart-fsrs

Dart Package for FSRS
MIT License
16 stars 8 forks source link

Question: don't update cards params after answer Again #18

Closed F0XBAN closed 1 month ago

F0XBAN commented 1 month ago

Hello! First of all, thanks for this package! I have a question about updating card parameters after pressing the "Again" button several times after creating a card. Using this site, I see that with any response, the card's parameters are updated: photo_2024-09-09_12-43-31 But in the package, the parameters are only updated after the first "Again" response. If I press "Again" again, the parameters are not updated: image_2024-09-09_12-41-57

I don't have a clear understanding of how this algorithm should work.

Is it correct that the card parameters (stability and difficulty) are not updated as they currently are, or should the parameters be updated for any answer option, as shown on the example site?

Using flow: create new card (_card = fsrs.Card();), press 4 times "Again" button

My code for check params:

import 'package:flutter/material.dart';
import 'package:fsrs/fsrs.dart' as fsrs;

class TestFsrsScreen extends StatefulWidget {
  const TestFsrsScreen({super.key});

  @override
  State<TestFsrsScreen> createState() => _TestFsrsScreenState();
}

class _TestFsrsScreenState extends State<TestFsrsScreen> {
  final fsrs.FSRS _fsrs = fsrs.FSRS();
  final List<fsrs.Card> _cardsHistory = [];
  late fsrs.Card _card;

  @override
  void initState() {
    super.initState();
    _card = fsrs.Card();
    _cardsHistory.add(_card);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Padding(padding: const EdgeInsets.all(8), child: Center(
        child: Column(
          children: [
            Expanded(child: ListView.separated(
              separatorBuilder: (context, index) => const Divider(height: 2),
                itemCount: _cardsHistory.length,
                itemBuilder: (context, index) {
                  var card = _cardsHistory[index];
                  return Text('$index) ${card.toString()}');
                }
            )),
            Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
                ElevatedButton(
                    onPressed: () => answer(fsrs.Rating.again),
                    child: const Text('Again')),
                ElevatedButton(
                    onPressed: () => answer(fsrs.Rating.hard),
                    child: const Text('Hard')),
                ElevatedButton(
                    onPressed: () => answer(fsrs.Rating.good),
                    child: const Text('Good')),
                ElevatedButton(
                    onPressed: () => answer(fsrs.Rating.easy),
                    child: const Text('Easy')),
              ElevatedButton(onPressed: () => reset(), child: const Text('reset')),
              ]),
            ],
        ),
      ),),
    );
  }

  void answer(fsrs.Rating rating) {
    var schedulingCards = _fsrs.repeat(_card, _card.due);
    var newCardState = schedulingCards[rating]!.card;
    _cardsHistory.add(newCardState);
    _card = newCardState;
    setState(() { });
  }

  void reset() {
    _cardsHistory.clear();
    _card = fsrs.Card();
    setState(() { });
  }
}
ishiko732 commented 1 month ago

Because daft-fsrs is currently using FSRS v4.5, it has not addressed short-term scheduling issues; ts-fsrs is now using FSRS v5.

F0XBAN commented 1 month ago

Because daft-fsrs is currently using FSRS v4.5, it has not addressed short-term scheduling issues; ts-fsrs is now using FSRS v5.

That is, this is correct behavior from the point of view of correct learning?

ishiko732 commented 1 month ago

That is, this is correct behavior from the point of view of correct learning?

Yes, in FSRS v4.5, during the learning steps, D,S is only updated during state transitions from New to Learning or from Review to Relearning.