Flutter间隔重复学习插件spaced_repetition的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter间隔重复学习插件spaced_repetition的使用

简介

本文档介绍了如何在Flutter项目中使用spaced_repetition插件。该插件基于SM-2算法实现,用于优化学习过程中的间隔重复。

关键概念

SM-2是一种简单的间隔重复算法。它根据今天记忆信息的难易程度来计算下次复习的天数。

输入参数

算法需要四个输入参数:

  • 质量(quality):一个从0到5的整数,表示今天记忆信息的难易程度。
  • 重复次数(repetitions):信息被复习的次数。
  • 之前的容易因子(previous ease factor):一个大于等于1.3的浮点数。
  • 之前的间隔(previous interval):上一次复习与下一次复习之间的天数。

输出结果

算法返回三个输出参数:

  • 间隔(interval):下次复习之前需要等待的天数。
  • 重复次数(repetitions):信息被复习的总次数。
  • 容易因子(ease factor):一个大于等于1.3的浮点数,用于计算下次复习的间隔。

步骤

  1. 如果**质量(quality)**大于或等于3,表示正确回答:

    • 如果**重复次数(repetitions)为0(第一次复习),设置间隔(interval)**为1天。
    • 如果**重复次数(repetitions)为1(第二次复习),设置间隔(interval)**为6天。
    • 如果重复次数(repetitions)大于1(后续复习),设置间隔(interval)之前的间隔(previous interval)* 之前的容易因子(previous ease factor)
    • 将**间隔(interval)**向上取整。
    • 将**重复次数(repetitions)**加1。
    • 设置容易因子(ease factor)之前的容易因子(previous ease factor)+ (0.1 - (5 - 质量) * (0.08 + (5 - 质量) * 0.02))
  2. 如果**质量(quality)**小于3,表示错误回答:

    • 将**重复次数(repetitions)**设为0。
    • 将**间隔(interval)**设为1。
    • 容易因子(ease factor)设为之前的容易因子(previous ease factor)(无变化)。
  3. 如果**容易因子(ease factor)小于1.3,则将容易因子(ease factor)**设为1.3。

示例代码

以下是一个完整的Flutter示例,演示了如何使用spaced_repetition插件。

import 'package:flutter/material.dart';
import 'package:sm2/main.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  final sm = Sm();

  [@override](/user/override)
  Widget build(BuildContext context) {
    // 计算间隔、重复次数和容易因子
    SmResponse smResponse = sm.calc(
      quality: 0,
      repetitions: 0,
      previousInterval: 0,
      previousEaseFactor: 2.5
    );

    return Scaffold(
      appBar: AppBar(
        title: Text('间隔重复学习'),
        centerTitle: true,
      ),
      body: Container(
        padding: const EdgeInsets.all(10.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("重复次数: ${smResponse.repetitions}"),
            Text("间隔: ${smResponse.interval}"),
            Text("容易因子: ${smResponse.easeFactor}")
          ],
        ),
      ),
    );
  }
}

更多关于Flutter间隔重复学习插件spaced_repetition的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter间隔重复学习插件spaced_repetition的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用spaced_repetition插件的示例代码。spaced_repetition插件通常用于实现间隔重复算法(如SuperMemo算法),以优化学习和记忆过程。虽然Flutter社区可能没有直接名为spaced_repetition的官方插件,但我们可以模拟一个间隔重复学习系统的基本功能。

首先,你需要创建一个Flutter项目。如果你还没有Flutter环境,请先安装并配置好Flutter SDK。

1. 添加依赖

虽然没有一个直接名为spaced_repetition的Flutter插件,但我们可以使用一些基本的Flutter和Dart功能来实现间隔重复算法。首先,在pubspec.yaml文件中添加必要的依赖(如SQLite或其他数据库插件来存储学习数据,但这里为了简化,我们直接使用内存存储)。

dependencies:
  flutter:
    sdk: flutter

2. 创建数据模型

创建一个简单的数据模型来表示学习卡片。

class Flashcard {
  String question;
  String answer;
  DateTime lastReviewed;
  int easeFactor; // 表示学习难度,影响下次复习间隔

  Flashcard({required this.question, required this.answer, this.lastReviewed = DateTime.now(), this.easeFactor = 280});
}

3. 实现间隔重复算法

使用SuperMemo 2算法来计算下次复习的时间间隔。

import 'dart:math';

double calculateInterval(int easeFactor, double lastInterval) {
  double gradient = 2.5; // SuperMemo 2算法的梯度参数
  double newInterval = lastInterval * easeFactor / (easeFactor - (gradient * (easeFactor - min(easeFactor, 280) / 280.0)));
  return max(1, newInterval); // 最小间隔为1天
}

4. 管理卡片

创建一个管理器类来管理学习卡片。

import 'package:flutter/material.dart';
import 'dart:convert';
import 'dart:typed_data';

class FlashcardManager {
  List<Flashcard> cards = [];

  void addCard(Flashcard card) {
    cards.add(card);
  }

  List<Flashcard> getCardsDueToday() {
    DateTime now = DateTime.now();
    return cards.where((card) => card.lastReviewed.add(Duration(days: card.easeFactor / 365.0)).isBefore(now) || card.lastReviewed.add(Duration(days: 1)).isAtSameMomentAs(now)).toList();
  }

  void reviewCard(Flashcard card, int rating) {
    DateTime now = DateTime.now();
    card.lastReviewed = now;
    card.easeFactor = min(280, card.easeFactor - (20 * (280 - card.easeFactor) / 280.0) + (rating - 3) * 40); // 根据用户评分调整easeFactor
    double lastInterval = (now.difference(card.lastReviewed).inDays).toDouble();
    card.lastReviewed = now.subtract(Duration(days: lastInterval)); // 回退到上次复习时间以便计算新的间隔
    card.lastReviewed = card.lastReviewed.add(Duration(days: calculateInterval(card.easeFactor, lastInterval).toInt()));
  }
}

5. 创建用户界面

创建一个简单的用户界面来展示和复习卡片。

import 'package:flutter/material.dart';
import 'flashcard_manager.dart';
import 'flashcard.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Spaced Repetition App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  FlashcardManager manager = FlashcardManager();

  @override
  void initState() {
    super.initState();
    // 添加一些示例卡片
    manager.addCard(Flashcard(question: 'What is Flutter?', answer: 'Flutter is a UI toolkit for building natively compiled applications for mobile, web, and desktop from a single codebase.'));
    manager.addCard(Flashcard(question: 'Who created Flutter?', answer: 'Flutter was created by Google.'));
  }

  @override
  Widget build(BuildContext context) {
    List<Flashcard> dueCards = manager.getCardsDueToday();

    return Scaffold(
      appBar: AppBar(
        title: Text('Spaced Repetition App'),
      ),
      body: dueCards.isEmpty
          ? Center(child: Text('No cards due today.'))
          : ListView.builder(
              itemCount: dueCards.length,
              itemBuilder: (context, index) {
                Flashcard card = dueCards[index];
                return Card(
                  child: ListTile(
                    title: Text(card.question),
                    subtitle: ElevatedButton(
                      child: Text('Show Answer'),
                      onPressed: () {
                        showDialog(
                          context: context,
                          builder: (context) => AlertDialog(
                            title: Text('Answer'),
                            content: Text(card.answer),
                            actions: <Widget>[
                              TextButton(
                                child: Text('Rate Card'),
                                onPressed: () {
                                  int rating = int.parse(showCupertinoDialog(
                                    context: context,
                                    builder: (context) => CupertinoAlertDialog(
                                      title: Text('Rate your confidence'),
                                      content: Text('How well did you remember this card?'),
                                      actions: <Widget>[
                                        CupertinoDialogAction(
                                          isDefaultAction: true,
                                          child: Text('1 - Poorly'),
                                          onPressed: () {
                                            Navigator.of(context).pop(1);
                                          },
                                        ),
                                        CupertinoDialogAction(
                                          child: Text('2'),
                                          onPressed: () {
                                            Navigator.of(context).pop(2);
                                          },
                                        ),
                                        CupertinoDialogAction(
                                          child: Text('3 - Adequately'),
                                          onPressed: () {
                                            Navigator.of(context).pop(3);
                                          },
                                        ),
                                        CupertinoDialogAction(
                                          child: Text('4'),
                                          onPressed: () {
                                            Navigator.of(context).pop(4);
                                          },
                                        ),
                                        CupertinoDialogAction(
                                          child: Text('5 - Perfectly'),
                                          onPressed: () {
                                            Navigator.of(context).pop(5);
                                          },
                                        ),
                                      ],
                                    ),
                                  ).then((value) {
                                    manager.reviewCard(card, value!);
                                    Navigator.of(context).pop();
                                    setState(() {});
                                  });
                                },
                              ),
                              TextButton(
                                child: Text('Cancel'),
                                onPressed: () => Navigator.of(context).pop(),
                              ),
                            ],
                          ),
                        );
                      },
                    ),
                  ),
                );
              },
            ),
    );
  }
}

总结

以上代码展示了如何使用Flutter创建一个简单的间隔重复学习应用。虽然这不是一个完整的插件实现,但它提供了一个基础框架,你可以根据需求进一步扩展和优化。例如,你可以添加持久化存储、更复杂的用户界面、统计和报告功能等。

回到顶部