コロナ禍における学習保証の話と、GIGAスクール構想の話とが相まって、オンライン学習がいろいろ騒がれていたが、そのそもそものきっかけであった「3月休校」から気づけば1年が経ってしまった。文科省の動画配信「学校の情報環境整備に関する説明会」で、担当課長が強い語気でこのスライドを出した件からも10ヶ月。もうすぐ、GIGAスクール構想の予算措置の期限である年度末を迎える。
前回の記事から半年以上経過し、勤務する自治体はChromebook + Google Workspace for Educationの採用が決まり、デバイスの配備とアカウントの発行も終わった。本格利用は新年度からだが、担当する学年の生徒には先んじて3月中にアカウントを利用させたいと思っているし、なんなら担当している生徒会執行部役員の文書作成作業はすでにGoogle WorkspaceとGoogle Classroomに移行した。もっとも、一人1アカウント環境がない中でも、私は授業でそれなりに活用してきた。
授業での用途としては、Slidesを利用した協働学習が挙げられるが、それ以上に利用頻度が高いのがGoogle Formsで、選択式の単元チェックテストのみならず、記述式の英単語テストも行っている。新年度からは授業の帯活動の単語テストをForms運用に切り替えようと思っている。その準備のために単語テストを40種類作成するのだが、それが面倒だなと思っていた折に、ICT支援員さんが「GASを書くと簡単になるらしい」と私にささやき、そこから1ヶ月ほど、GASを書くことにハマっている。
今回は、Google Apps Scriptを使ってGoogle Formsを動かしてみた試行錯誤のなかで判明した、GAS+Formsの組み合わせで「出来ないこと」を記録しておこうと思う。とても長くなったので、結論から急ぎたい方は、目次を開いて当該箇所をご覧いただきたい。
前段①:そもそもGASってなんだ
まずはこのツイートをみて欲しい。
私はすごいものを開発してしまった…
①スプレッドシートに英単語とその意味を入力
②問題数・選択肢の数を指定これだけで、Googleフォームでテストを自動作成できる。
もちろん誤答選択肢、解答、フィードバックも自動作成。英語教育に革命を起こせそう… pic.twitter.com/KZDjFvLVno
— 福田泰裕🏫高校数学教師&ブロガー📝月4万PV (@fukuyasu1203) February 22, 2021
高校の数学の先生が、Google SpreadsheetとGoogle Apps Scriptを使って、スプレッドシートに作成した英単語と意味のリストから、選択式問題を任意の問題数分取り出して自動でGoogle Formsを作れるツールを開発し、バズった。本来であれば、SpreadsheetとFomsは別サービスなので、それこそブラウザのタブまたはウィンドウを2つ用意して、コピペを繰り返しながら問題を作成したり、あるいは手動で設定をいじる必要がある。しかし、Google Workspaceで提供されているサービス間を連携させることができるプログラミング言語が存在する。それがGoogle Apps Scriptである。これをGASと呼ぶ。
基本的は構文は、ブラウザ上で動的な処理を行う際に広く用いられるJavascriptとほぼ同じ構文だが、GASで書いたプログラムはGoogleのサービスが置かれているサーバー側で挙動するサーバーサイド言語である。Office系のツールを動かす、とくにエクセルでの処理を自動化してくれるものとして広く用いられている言語に、Visual Basic for Application、通称VBAがあり、私自身前職時代にはVBAを使っていくつかの業務ツールの開発をしてきた。VBAはPC上で動くプログラムだが、GASはサーバー側で動くものである。
私自身、GASという言葉自体を認知したのは2020年の夏ごろで、かなーり前からGoogle系のOfficeツールを活用してきたにもかかわらず、GASというものがあるのを知ったのは相当遅かったし、普段の業務で使う必要性がなかった。ところが、2021年の2月冒頭のこと、ICT支援員さんとGoogle系サービスの教育利用について雑談をしていたところ、こんな話をICT支援員さんがなさった。
他の学校でもGoogle Formsの研修をしたんですが、どうにも難しい、という反応をされまして。あのUIで難しいとなるとこちらもどうしようもないのですが、もうそれだったらGASでFormをさらに簡単に生成できるツールを開発した方がいいと思っていろいろ試しているんです。
ん? GASでFormが作れるだと?
その雑談の中で、GASがJavascriptライクに書けるので簡単だということを聞いたのだが、Javascriptは書いたことがなかった(C++を大学の授業で、PHPをインターンで、VBAを前職時代で、という経歴)のでちょっと尻込みしたものの、とりあえずどんなことができそうなのかとググってみたら、各種サービスの呼び出しが思ったより簡単そうだということがわかり、早速Spreadsheetからスクリプトエディタを起動して、見様見真似でFormを生成するツールを作成してみたら、できてしまった。
前段②:何を作ろうとしたのか
早く本題である「できないこと」を書けよ、と思うかもしれないが、まぁ少し待って欲しい。「できないこと」を書く上では、やろうとしていることを記載した方がいい。現段階で、次年度からの利用において作ろうとしているのは2つのプログラムであるが、どちらも「英単語クエスト」という取り組みに用いるものだ。
「英単語クエスト」とは、現在紙ベースで行っている授業冒頭の5分の英単語テストだ。あらかじめ、640単語のリストを生徒たちに渡しており、16単語で1ステージとして40ステージ分の問題を用意している。1ステージあたり1面と2面があって、1面は英単語を見て日本語を書き込む方、2面は日本語を見て英語を書き込む方、としている。1面も2面も、満点を取らないと次の面・ステージに進めない。それが、RPGのクエストみたいなものだと思って「英単語クエスト」と名付けた。
しかしこの取り組みが大変なのは、生徒一人ひとりによって進捗がまるで違う点であり、またそのために紙の量が膨大になるという点である。教員である私も、そして生徒も「あれ、いまどのステージだっけ」とわからなくなる。採点は私ではなく交換採点にしているが、自分自身で満点をつけちゃうというチート行為は今のところ発見されていないが、交換採点の相手がテキトーに採点してしまうということは生じてきている。この、進捗管理のしにくさと、採点の不正確性を、どうにかFormsで解消できないか。
そんな折、3学期からFormsの短答式テキストボックスを使った不規則変化動詞チェックテストを運用し、ことのほか生徒たちがQWERTY配列のソフトウェアキーボードの入力に難を抱えておらず、またChromeの設定でスペルチェック機能を外せば修正サジェスチョンが出ないことも判明し、「わざわざ紙で単語テストをしなくてもいいかもしれない」という境地に至った。そこで新年度からの「英単語クエスト」を、全面オンラインに移行することを決断した。ここで、2つの要素がネックになった。
- 40ステージ分の英単語テストを生成するのがめんどくさい。自動化したい。
- 自分の進捗を確認して自己申告制でテストを受けるステージのフォームを選択していくのではなく、自分のログイン情報をもとに、次に受けるステージを自動で表示してくれる機能を作りたい。
そこへきて、ICT支援員さんの「GASが簡単らしい」というささやきによって、私のプログラミング熱に火がついてしまった。GASをつかってFormsを自動生成できることを知ったすぐ後から、①記述式単語テスト40ステージ分自動生成の開発に着手。するとその翌週にICT支援員さんが次なるささやきを私にもたらした。
GASって、プロジェクトのなかにHTMLを組み入れて、Webアプリみたいに動的なWebページを作ることができるらしいんです。
なぬ。動的Webページを作れるだと。
最初にそれを聞いた時には、おそらくGoogle Cloud Platformで仮想サーバーを立ち上げる必要があるんだろうと想像したら、なんとそんなこともなく動的Webページが作れることが判明した。SpreadsheetをDBがわりにしてWebアプリを開発できるとしたら、
②ログイン情報によって次に受ける英単語テストを自動表示する
も作成できるかもしれないと思って開発に着手。そしてつい先週、一番のネックになるであろう、ログイン情報を取得してログインIDを検索キーにしてSpreadsheet上にある別情報を表示する、というWeb Appの開発に成功した。
ところが、この「①記述式単語テスト40ステージ分自動生成」のプログラム作成において、そしてこの1のコードを流用して作成した別のプログラム
「③一つの問題に対して1つの正解選択肢と3つの不正解選択肢のフォーム生成」
のプログラム作成において、GASでは実装できなかった機能があった。それらはFormの自動生成後に、作成したフォームをブラウザで開いて自力で(=GUIで)設定をいじらないといけない。ここがなんとも不便である。
さて、お待たせしました。次からいよいよ本題です。
できなかったこと1:短答式テキストボックスへの正解の設定
プログラム①:短答式テキストボックスでの英単語テスト作成でつまづいたポイントがこの「テキストボックスへの正解の設定」だった。まず、プログラム③:選択式フォームの自動生成プログラムでのコードを見ていただこう。
var item = form.addMultipleChoiceItem(); item .setTitle(array[i][2]) .setHelpText(array[i][3]) .setPoints(array[i][1]) .setChoices([ item.createChoice(array[i][4],true), item.createChoice(array[i][5]), item.createChoice(array[i][6]), item.createChoice(array[i][7]) ]);
そもそもだがGoogle Formsにはクイズ機能があって、正解するとポイントが得られる、最終的に自動採点して、間違えた問題の正解を表示したり、問題の解説を表示したりする機能がある。組織管理されたChromebookを用いると、クイズ実施中は他のタブを開けなくなるモードもあるなど、便利である。
GUIでは、一問ずつ正解を設定していくのだが、GASでコードを書くと、上記のように選択式の設問(上記コードでのMultipleChoiceItemは、複数選択肢のなかで1つだけしか選べない「ラジオボタン」形式)の選択肢作成を意味するcreateChoice()
において、引数の2つ目をtrue
に設定すると、その選択肢を正解として扱うことができる。
では、今度はプログラム①で書いたコードの中で、短答式テキストボックスを挿入している部分のコードを見てもらおう。
form.addTextItem() .setTitle( ("00"+ array[i][0] ).slice(-3) + ':' + array[i][3]) .setPoints(1);
このaddTextItem()
においては、その後ろに設問文にあたるタイトル設定 setTitle()
と、得点設定にあたるsetPoints()
が記載できている。そうすると、正解テキストを設定できるsetAnswer()
のようなものがあってもおかしくないと思う。
だが、この短答式テキストボックスに正解を設定する機能が、GASのライブラリをくまなく探しても見当たらない。自分が見落としているだけだろうと思ったので英語でも情報を検索したが、同じようなことを考えている人がどこぞのWeb掲示板で質問をしており、その返答として「機能として無い、改善要望はあがっている」と答えているのを見た。
そうすると私は、640単語・1フォームあたり16単語・40個のフォームの、その全てに対して、いちいち正解を手動で適用していかなければいけない。まぁまだ、フォームの生成と設問文の設定、ならびに得点の設定まではしてくれるので、その手間が省ける分いいのだが、ここも自動化できたら相当楽になる気がしてならない。
できなかったこと2:選択肢式設問での選択肢ランダマイズ
さてこちらは今日のこと。あさっての授業でFormを使ったチェックテストを行うためにテストを作成せねばと思っていたのだが、1問あたり選択肢を4つ用意して1つだけ正解を選ぶ形式の設問を30問用意する予定だったので、プログラムでやっちまえ、と思った。それで書いたプログラムが、③:選択式フォームの自動生成である。コードを再掲する。
var item = form.addMultipleChoiceItem(); item .setTitle(array[i][2]) .setHelpText(array[i][3]) .setPoints(array[i][1]) .setChoices([ item.createChoice(array[i][4],true), item.createChoice(array[i][5]), item.createChoice(array[i][6]), item.createChoice(array[i][7]) ]);
もとにしたSpreadsheetの表では、カラム(列)を以下のように設定した。
[0]問題番号|[1]得点|[2]問題文|[3]日本語訳|[4]正解選択肢|[5]不正解選択肢① …
ちなみに不正解選択肢は①〜③まである。それから、問題文は英語で、一部に穴あきがあるものだ。たとえば「 I have ( ) apple. – 私はりんごを1つ持っている」の英語部分が問題文、日本語部分が日本語訳である。これの答えは an だが、正解を正解選択肢に入れている。
で、コード上ではこれらをそれぞれ設定している。注目してもらいたいのは7行目。ここで書かれているcreateChoice()
は、選択肢を生成するものだが、これが並んでいる順に選択肢が上から生成されていく。つまり、このままだと1番目が正解に設定されているので、全ての問題が1番目が正解になる仕様になっている。
FormのGUI画面では、この選択肢をランダムにする設定ができる。私は、作成時の管理のしやすさや結果表示の見やすさの観点から、選択肢の並び順に意味がある場合を除いて、1番上を正解に設定し、選択肢を並べ替える設定にしている。ところが、この選択肢ランダマイズをするsetChoicesRandom()
といった具合のものが、レファレンスを探しても見当たらない。というか、そもそもGASにおいてはその設定が無い。
となると、選択肢ランダマイズをするためのロジックを書くことが必要で、試しに冒頭で紹介した数学の先生のコードを拝見してみたところ、すぐには理解しきれなかった(ただ読めてないだけ)が、乱数を用いて選択肢の順番をランダムに配置する処理が行われていた。ロジック生成の苦労が思いやられる。だがこのランダム処理は、フォームの作成時点でランダマイズされているだけで、フォームを開くたびにランダマイズされる処理では無い。となると、私が望む【フォームを開くたびにランダマイズされる】というのはGASでは実装できないようだ。仕方がないので、30問全部を1つずつ設定していった。
1つ回避方法があるとすれば、あらかじめテンプレとなるフォームを生成し、1問だけ「選択肢をランダムにする」設定を仕掛けておき、そのフォームをコピーして、設問をDuplicate=コピーして生成していくというのがあるが、それもそれでめんどくさい。
できなかったこと3:番外編・セクション内での設問ランダマイズ
さてこの3つ目は、別にGASだろうとそうでなかろうと関係ない、単なるForm全体の仕様に関わるところだが、一応書いておく。
Google Formsでは、セクションという機能を使って、ページを分けることができる。長いアンケートも、ページネーションができるというわけだ。一方、Google Formsには、設問をランダムに表示する機能があるので、英単語テストをする時にはランダムに出題された方が学習に効果が出る場合もある。そしてその設問ランダマイズは、GASでコード記載ができる。簡単だ。フォームを作成するcreateForm()
のうしろに、setShuffleQuestions(true)
を書き加えるだけだ。
ところが、この設問ランダマイズ、セクションごとにランダマイズをするかしないかを選択できない。もちろん、セクションで区切られた部分をまたいでまで設問をランダムにはしない。だが、例えばセクション1では学年・クラス・出席番号を聞き、セクション2で問題を解くとしよう。そのとき、セクション2だけをランダマイズすることはできず、全体をランダマイズ設定すると、セクション1が例えば「出席番号・クラス・学年」という設問順になる。
そもそも、ログインユーザーのメールアドレスを収集する設定にしていれば個人特定ができるから意味がないじゃないか、と言われるかもしれない。その通りである。しかし念のために一応学年・クラス・番号は聴取したい。しかしそこまでランダムになると、なんか気持ち悪いというのも正直なところである。
できなかったこと4:クイズ設定時の、結果即時FB設定
さて、Form生成時に、Form自体をクイズにする設定は非常に簡単である。
var form = FormApp .create('タイトル') .setIsQuiz(true) .setRequireLogin(true) .setCollectEmail(true)
この5行だけで、タイトル付きでFormを生成し、クイズ設定をかけ、ログインを要する設定をかけ、メールアドレス収集をする設定をつけている。なお、同一組織のメンバーが回答する際は、ユーザーはわざわざメールアドレスを入力する必要はない。
ところで、このクイズ機能においては、得点の設定および正解の設定ができるので、自動採点ができるわけだが、その結果は「すぐに表示」と「後から送信」の2つのオプションがある。また、すぐに結果を表示する場合には、「合計点」「正解した問題」「不正解だった問題」のそれぞれについて、表示/非表示を選択できる。
が、この結果表示のタイミングと、表示のオプションについては、GASからいじれない。なのでForm生成後にFormを開いて、設定ボタンを押してそれぞれの設定をいじらなければならない。このあたりがGASから自動で設定できたら楽なのにな、と思っているのは私だけではないはずだろう。
こんなに長く書くつもりがなかったのに、いつの間にかすごい文字数になってしまった。だが、もしかすると誰かが検索でこの記事にたどり着くかもしれない。日本語って、その話者数でいったらそんなに多くないはずの言語だが、日本語だけで様々な情報を収集することができる点ではとても恵まれている。しかし、どうにも今回、私が「やりたかったのにできなかったこと」については、日本語の情報に当たることができなかった。きっと誰かがつまづいていると思うので、その助けになればいいな、と思っている。