夏の自由研究ブログ連載2022の1本目です。
長女の勉強を見ていて、英単語の暗記に苦労していたのでFlutterで学習アプリを作りました。
英語はフォニックスで学ぶといいよ、とか最近言われたりします。確かに自分の経験から見ても、ある程度単語を覚えてくると、だいたい音節の区切りが見えてきて、「この発音だと母音の形式はだいたいこれかな?」「子音はこれかな?」とか選択肢が見えてきて、その組み合わせで考えていけるので、徐々に少ない労力でたくさんの単語を覚えていけます。
しかし、小学生の英語だと、まず覚えている単語が少なく、音節やフォニックスといった規則性を見つけ出すのは困難のようです。そのため、単語のスペルを覚える労力はO(n)というか、勘も働かずにほんと力技になってしまいます。あと、勘が働かないのはもう1つ問題があって、間違ったスペルを書いても「間違った」という感触がないため、間違ったスペルを何度もノートに書いて練習してしまっても気付きにくいという問題がありました。
あとは子供の性格や学習スタイルの個性もあると思いますが、うちの子はPCのキーボードにはそれほど抵抗がないのと、文字をたくさん書くのはストレスのようなので、PCで目と耳を使って学習、なおかつスペルのミスをなるべく間違えた瞬間にフィードバックしてあげるようなものがあれば良いかな、と思いました。
で、良いスマホアプリとかないかな、と思って探したのですが、今使っている英語の教材の進度に合わせた単語の選択ができるものとかがなくて、自分で作ることにしました。
作ったアプリ
Flutterで作りました。Flutterは案件でモバイルアプリを作ったりもして、生産性の高さは実感していました。あと、スペルとかを声で言ってくれるようなアプリが作りたかったので、当初はmacOSのsayコマンドをサブプロセス実行するようなものとして作りました。そのため、デスクトップアプリにしたかったというのもあります。
まあ、Text To SpeechはブラウザのAPIも後からあるのに気づいたし、最終的にはsayコマンドを実行するのはやめてFlutterのライブラリのflutter_ttsにしたので、声を出すだけならFlutter出なくても良かったというのは気付きましたが、基本的なところは1晩で作れたので技術選択は悪くはなかったかと思います。
ソースコードはこちらにアップしてます。
基本的には問題の答えをキーボードでタイプしていくだけですが、間違ったらタイプできないようにして、間違ったスペルを覚えないようにしています。ちなみに一文字でもタイプミスすると不正解になって、正解するまでは問題が出続けるというスパルタン仕様です。
間違ったらスペルを声で教えてくれる、間違った箇所を色付けするようにしたあたりが工夫ポイントです。Text To Speechエンジンに「baseball
」というテキストを渡せば「ベースボール」と読んでくれますが、「b a s e b a l l
」と間にスペースを挟むとスペルの読み上げになりますね。今のところ試したエンジンはみんなこうなってくれました。
最初はローカルのJSONファイルを手修正してましたが、問題編集機能もつけてみました。
今後やりたいこと
英単語を自動で音節(syllable)に分けてあげて、その単位で単語を分けて表示してあげると、勘が働きにくい部分をアプリとしてサポートしやすくなるんじゃないかと思ったのですが、本格的に音節分割するには何かしらの辞書データが必要そうなので、ちょっと手間が大変そうでした。簡易的なロジックは調べればいくつか出るので、そこはやってもいいかなと思っています。
あとは間違った回数の履歴をもとに出てくる単語の数を調整とかしたらいいかな、と思いつつ、学習曲線とかをアルゴリズムに落とし込むのは結構面倒ですね、と思ってまだやってません。いつかやりたい。
Flutterの落とし穴
最終的にはビルドしたものをそのまま子供のPC(intel mac)にインストールしたので問題はないのですが、今後のARM macだとDeveloper Programに入らないとインストール面倒そうだな、ということでFlutter Webにしようかなと少し思ったのですが、Flutter WebにするにはNamed Routeにしないとページ遷移できません。で、Named Routeの場合はページ間で状態を渡すには、riverpodとかのステート管理ライブラリが何か必要となります。
今回はスピード重視でNavigator.pushReplacement()
でコンストラクタ渡しで状態を渡すように最初に作ってしまったため、ウェブ化はできませんでした。
あと、当初はText To Speechのライブラリとしてtext_to_speechを使おうとしたのですが、Flutter 3でビルドが通らなかったり、依存ライブラリの互換性対応はなかなか難しいですね。人気があって更新が頻繁なライブラリを選ぶしかなさげ。
まとめ
新型コロナは社会的にいろいろ大きな影響を与えましたが、リモートワークで子供の勉強を見る機会は増えました。フューチャーは今のところリモートをやめようという話はないですし、その点は良かったなと思っています。子供の得意な勉強法は姉妹であっても全然違うし、「こうすればOK」と1つのやり方だけすれば良いということもなく、無理やり特定のやり方を押し付けると学習効率が上がらないばかりか、勉強嫌いになってしまう恐れがあります。
今回は子供の勉強の様子をじっくり観察できたので、子供にあわせた学習アプリを作れました。Flutterはすばやくデスクトップアプリが作れて良いですね。他の科目もいくつか「ここさえクリアできれば」というポイントがいくつかあるので、また色々作ってあげようと思っています。次はsolid.jsでも使ってみようかな? sveltekitでもいいかも? それか、Swiftでネイティブで作るか。