情報Iで出題される擬似言語 (以下 DNCL) を、ブロックを使って学ぶための環境 を実装しました。Web ブラウザ内で完結できるように、Vue + Vuetify -> Blockly -> Calcium (後述) -> Pyodide という構成になっています。全体像を下図に示します。
Blockly を埋め込む
Vue + Blockly とした理由
Lit をはじめ shadowDom
内では Blockly エディタを読み込むことができない ようです。
このため Vue についても、component 化はできないことがわかりました。本当はライブラリとして利用できるようにしたかったのですが...。App.vue などのトップレベル直下であれば Blockly.inject()
できます。ただこれも Vue のバージョンを上げた際に動作しないことがありました(2024/08/21 現在使っているのは v3.2.25)。
renderer に zelos
を指定すると Scratch 風になる
デフォルトの renderer では、パズルのピースのような形になります。これを Scratch に近づけることができます。
const workspace = Blockly.inject(document.querySelector('#div-blockly'), {
renderer: 'zelos',
...
})
Blockly.inject()
に上記を指定すると大分見た目が変わり、今の子どもたちにもなじみ深いブロックの形になると思います。
generator から DNCL, Calcium それぞれのコードを生成する
Blockly にはブロックで組み立てたプログラムを何らかの言語として生成するための generator が組み込まれています。JavaScript などのコードを生成することもできますが、やや不自然なコードになります。不自然というのは、普段のテキストプログラミングとは異なるお作法になる、という意味です。
generator は自分で追加することが可能です。今回は新たに2つ実装することになりました。1つは DNCL 向けの日本語表現を生成するものです。もう1つは Calcium で実行するための JSON 配列を出力します。
Calcium + Pyodide
Calcium とは
本プログラミング環境の内部で利用しているインタプリタです。入力として JSON 配列を受け取ることが特徴です。なぜ Calcium を使っているかというと、Blockly と相性が良いためです。Blockly はブロックをテキスト(コード)に変換するための環境と言えますが、実行環境は付属していません。Calcium は Python 上で動作し、行単位で実行することができます。Calcium の1行は1つのブロックと対応関係があり、generator から生成したコードをそのまま入力として利用可能です。
Pyodide を WebWorker
内で実行する
公式サイトを参考に実装し、プログラム自体が無限ループの時でも、ページごと固まらないようにしました。
外部ライブラリを micropip
で読み込む
Calcium インタプリタを読み込むためにはmicropip
モジュールを最初に import
しておく必要がありました。
const pyodide = await loadPyodide()
await pyodide.loadPackage(['micropip'])
pyodide.runPython(`import micropip
await micropip.install('calciumlang')
from calciumlang.runtime import Runtime
`)
最後に
Scratch から Python へ...
Scratch から次のステップへ進むための学習環境を目指して、DNCL でプログラムを表示できるようにしました。また、ブロックの中には日本語表現だけでなく Python の文法に則ったものもあります。これらは互いに等価なコードを出力するため、ブロックプログラミングからテキストプログラミングへ移行する際に比較しながら使えるのではないかと考えています。
こちらのページで、実際に試すことができます。また本環境はソースコードを公開しています。少しでも興味を持っていただけたら嬉しいです。