■ 小問ごとに空欄数が異なる穴埋め問題の採点方法

 使う場面

 右の例1のように,小問ごとに空欄数が異なる穴埋め問題に対して,JavaScript関数を作って採点したいとき.
 全部の問題を1つのボタンで採点する方式

 実際に使っている見本
 ../kou3/integral_7.htm
例1
(解説や問題文がここに入る)
問1
  a = , b = , c =
(解説や問題文がここに入る)
問2
  a =
(解説や問題文がここに入る)
問3
  a = , b =

 利用可能な型版使用方法
別添ファイル について)

1. 全般的な注意

(1) 別添ファイルtext_box1.zip は,textbox_1.htm という教材の型版本体のHTMLファイルと次に解説するKR情報用の画像ファイル3個を zip 形式で圧縮したもので,ファイルサイズは 3.99KB です.このファイルをコンピュータに保存して,+Lhaca ( http://park8.wakwak.com/~app/Lhaca/ )などで解凍していただくと,フォルダ内に4個のファイルができます.その後は,zip ファイルは削除していただいても構いません.textbox_1.htm と3個の画像ファイルは,同一フォルダ内にある限り他の場所に移動しても構いません.この型版のファイルと画像ファイルを,あなたが問題作成作業に使用するフォルダに移動し,型版のファイルに名前を付けて保存すれば,各々別の教材になります.

(2) このファイルは簡単なHTMLファイルで,教材にはなりますが,学習状況の管理(個人ごとの学習時間や学習の進捗状況の管理)はできません.

(3)
 各小問ごとに採点し,KR情報を画像で表示する方式の型版は→こちら

 ◇次の2つの型版は画面上で文字を書き換えるもので, document.all という書式を使いますので,
ブラウザ依存 ( Internet Explorer のみ対応 )です.そこで Internet Explorer 以外のブラウザで読み
込まれたときに外へ逃がす工夫が必要となります


 一括で採点し,KR情報を文字で表示する方式の型版は→こちら
 各小問ごとに採点し,KR情報を文字で表示する方式の型版は→こちら

(4) この型版は画面のレイアウトには関係なしに動きます.実際に教材を作るときは,表を組んで右側に解説図を描くなど様々なレイアウトにして使います.ホームページ作成ソフトで加工するとき,この型版の要素のうち順序や name を変更するとエラーとなるのは<form></form>,<input ...>,KR情報用の画像だけです.(後から追加するときもこれらと同一のnameを使用すると,後出優先となり先に登場する方は無視されます.)
 ただし,ホームページ作成ソフトでは,表の<tr>や<td>をまたいで<form>が配置されているとエラーと見なして,勝手に書き換えてしまうことがありますので,教材の加工にホームページ作成ソフトを使用するときは1つの<td></td>の中で<form></form>が完結するようにしてください.

2. KR情報(正しいか間違っているかを示すもの)について

 正答・誤答情報の画像を別のものにするには
画像ファイルのうち,neutral.gif というファイルは,透明白紙の画像です.問題に着手する前やリセットしたときには,各問題の採点にはこれが見えています(つまり,場所だけは確保していますが何も見えていません).o1003.gif というファイルは24ドット×24ドットのイラスト画像で,正答に対して示しのように見えます.x1003.gif というファイルは,誤答に対して示す画像で,のように見えます.教材や学習者の年齢に応じて別の画像を使用されるときは,text_box1.htm ファイルのソースをメモ帳などで開いて,先頭付近にある kr[1].src の画像ファイル名を正答を表わす別のファイル名,kr[2].src の画像ファイル名を誤答を表わす別のファイル名に書き換えてください.
 そのとき,このtext_box.htm ファイルの<BODY>では24ドット×24ドットで表示していますので,元のファイルと縦横のサイズが異なる場合,形が変ります.(元のファイルを24ドット×24ドットで作成するか,または<BODY>中の<img src="neutral.gif" width="24" height="24" border="0" name="kekka00">の部分を原寸に合わせて変更される方が無難です.特に,原画が文字を含む場合や線画を含む場合に縦横サイズを変更して表示すると,明確な情報が伝わらないことがあります.)
3. 問題を追加・削除するには

(1) 解答の追加・削除

 解答の配列を右図1のように定めた場合,問1の解答(の組)は配列 ans[0] で与えられ,問1の2番の解答は ans[0][1] すなわち 8 となります.
 問題数を増やすとき,例えば第4問を追加するには,ans[3] = new Array(); とし,その中での解答の順にArray() の中に書き並べます.

 [重要]
 ・ 他のプログラミング言語と同様に javascript も配列は0番から始まりますので,配列番号0, 1, 2 には1番,2番,3番が対応します.したがって,4番目は配列番号3が対応します
 ・ 右の図1 ans[1] のように配列要素の個数が1個になる場合, ans[1] = new Array(6); とすると,ans[1]を配列要素の個数が6個と定義する書式と同じになり,意図したものと違うものができます.このように要素数が1個になるときは,右の例のように文字列を表わす記号として引用符(シングルまたはダブルクォート)で囲んでください.
 . 右の図2のように解答に0という数字を含む場合,単なる未記入(空欄)でも,これを数値に変換すると0となって正答と一致しますので,0を答とするときはクォーテーションマークで囲んで '0' としてください.配列は,同種の要素を並べたものなので,その場合,同一配列 ans[2] の他の要素も文字列にしてください.
・ 数学以外の教科では,解答は文字列となることが多くなります.英語で this ような単語,社会で 東京 のような語句を正答とするときは各々 "this" "東京" のように引用符で囲んだ文字列を解答とします.

(2) <BODY>側で命名されている入力欄の参照

 右図2のように空欄の値を参照するための配列を定めた場合,問1に入力される値(の組)は doc[0] で与えられ,問1の2番の値は, document.q0.t01.value すなわち doc[0][1].value で与えられます.

[重要]
 この配列は,<BODY></BODY>において定義される画面上の要素(document)を参照(読み出し)しているので,<BODY></BODY>が読み込まれる前にこの配列が読み込まれるとエラーが起こります.

 もし,<HEAD></HEAD>に直接記述すれば,右図3のように<BODY></BODY>が読み込まれる前にこの配列が読み込まれ,エラーとなります.

 関数は定義されただけでは実行されず,何らかのイベントによって実際に呼び出されたときに実行されるので,このような空欄の値を参照する配列は,図4のように関数の中で定義するとエラーが起こりません.(関数はその定義のときに実行されるのでなく,何かのイベントによって実際に呼び出されたときに実行されます.このときには,<BODY>の各documentは読み込まれており,参照可能となっています.)

 このように関数の中で(ローカルに)定義されたデータは,他の関数からは読み出せないので,採点用とやり直し用の2つの関数からテキストボックスの配列を参照したい場合,図5のように1つ作って他方にコピー・貼り付けするとよい.

 <BODY></BODY>の読込み後に画面上の要素(document)を参照するのは問題ないので,</BODY>の後</HTML>の前に<script language="javascript"></script>または<script type="text/javascript"></script>の中に図1のdoc配列定義を置くとグローバルに定義でき,どの関数からも共通に利用できます.(このページの筆者は,その書き方は使用していません.)

(3) <BODY>側で命名されているKR情報の表示
 上の(2)とほぼ同様ですが,画像をKR情報に使うときは,画像の name を用いて
document.name.src = "代入する画像ファイル名";
とします.そこで図6のようにKR情報の配列(二次元)を定義しておき,各小問について初めから終りまで結果を表示します.
図1
ans = new Array();
ans[0] = new Array(7,8,9);
ans[1] = new Array('6');
ans[2] = new Array('0','1');

※ 他のプログラミング言語の場合と同様に,配列要素の番号は0番から始まる.上の例のような3個の要素を持つ配列では要素番号は0番から2番までとなり,ans[3]という要素はないことに注意.
図2
doc = new Array();
doc[0] = new Array(document.q0.t00, document.q0.t01, document.q0.t02);
doc[1] = new Array(document.q1.t10);
doc[2] = new Array(document.q2.t20,document.q2.t21);

図3
図4
図5
function saiten()
{doc = new Array();
doc[0] = new Array(document.q0.t00, . . .);
doc[1] = new Array(document.q1.t10);
doc[2] = new Array(document.q2.t20,. . . );

}
function renew()
{doc = new Array();
doc[0] = new Array(document.q0.t00, . . . );
doc[1] = new Array(document.q1.t10);
doc[2] = new Array(document.q2.t20, . . );

}
図6
zu = new Array();
zu[0] = new Array(document.kekka00, document.kekka01, document.kekka02);
zu[1] = new Array(document.kekka10);
zu[2] = new Array(document.kekka20,document.kekka21);

for(qnum = 0; qnum < ans.length;qnum++)
 {for(kk = 0; kk < doc[qnum].length; kk++)
  {if(doc[qnum][kk].value == ans[qnum][kk])
   zu[qnum][kk].src = kr[1].src;
  else
   zu[qnum][kk].src = kr[2].src;
  }
 }
2. 二次元配列の要素の個数

 右図7のように解答の二次元配列を定めたとき,ans は配列で,その要素は ans[0] , ans[1] , ans[2] の3個です.この要素数3は, ans.length によって返されるのでソースコード作成者は3と記入する必要はなく,問題の追加削除に応じてシステムが自動的に計算するようにしておくと,追加削除にときにメンテしやすくなります.
 したがって,右のような小問3題をまとめて全部採点する場合,
  for(qnum = 0; qnum < ans.length; qnum++)
   {for(kk = 0; kk < ans[qnum].length; kk++)
      小問中の空欄1個ずつの処理
   }
とすることにより,小問1から最後まで,各小問の初めから終りまで照合できます.

3. 照合の単位・・ただし,これは作者の意見

 対面授業や実力試験においては,右図8のような解答欄について,

,

は,3個1組で1つの数字を表わし,一部分が合っていても答案として評価できない考えるのが普通です.しかし,web教材においては,「読者が5秒間も戸惑う場面を作れば,そばにアシスタントがいない限り,常に投げてしまう誘惑にさらされている」と考えるべきです.そこで,学問的にどうであれ,読者が少しでも「達成感,成功感を励ましとして進んでいけるように」単純に窓ごとに採点し,直せばよい場所だけを示す方がよいと考えられます.この観点からは,窓の数だけ採点を並べるのがよいと考えられます.(右の図8では,7個のKR情報を出すのがweb向きだと考えられます.)(※右に続く→)
図7
ans = new Array();
ans[0] = new Array(7,8,9);
ans[1] = new Array('6');
ans[2] = new Array('0','1');


図8

x= , ,




(※→続き)
 英語の並べ替え問題,歴史の時代順に並べる問題など,通常は「1組の解答が全部合っていなければ正答とは見なせない」と思われる問題は数多くあります.これらの問題の採点単位(どのかたまりを正解とするかということ)も同様に,単純に機械的に窓ごとに行うのが,プログラムが簡単になるだけでなく,「教育効果」も上がると考えられます.
 
3. 空欄の初期化

 ファイルを読み込んだときテキストボックスは初期設定の空欄で表示されますが,再読込したとき,学校などで次の読者が読んだときに前の読者の入力したものが必ずしも消えているとは限りませんので,テキストボックスを初期化する関数を作り<BODY onLoad= > によりファイル読込み時に,すべて初期化します.
図9
function renew()
{
doc = new Array();
doc[0] = new Array(document.q0.t00, ...);
doc[1] = ...;
doc[2] = ..;

zu = new Array();
zu[0] = new Array(document.kekka00, ...);
zu[1] = ...;
zu[2] = ...;

for(qnum = 0; qnum < ans.length;qnum++)
 {for(kk = 0; kk < doc[qnum].length; kk++)
   {doc[qnum][kk].value = "";
   zu[qnum][kk].src = kr[0].src;
   }
 }
}

function renew_all()
{for(qnum = 0; qnum < ans.length; qnum++)
renew(qnum);
}
4. <BODY>側の入力欄の追加・削除

 入力欄を追加削除するには,<BODY>側でも入力欄とKR情報表示欄を追加・削除する必要があります.
 右図10の例では,青で示したものが入力欄で,赤で示したものがKR情報表示欄(画像)です.

 右の例のように<form name="q0"></form>の中に<input type="text" name="t00">があるとき,この入力欄の値は外の採点関数や初期化関数からは
document.q0.t00.value で参照できます.

 実際には,別の<form>の中にあれば, t00 というような名前は何度使っても区別できるようですが,型版ではすべて変えています.(t00, t01, t02 , t10, .., t20,.. など)

 value=""は初期設定で空欄(何も書いてない状態)にすることを,size="1" は入力欄の横幅を1とすることを表わしています.もし文字数の多い解答を予定されるときは,このsizeを,size="5" などと大きくします.(ただし,このsizeは入力欄の見える横幅で,size="1" でも実際の入力可能文字数の限界とは別になっています.

 数字を書き込む問題で,漢字変換モードをONにしておくと,1バイト文字でも2バイト文字でも記入できるようになるので,解答の照合が煩わしくなります.そこで,そこには数字しか入らないということが分かっているときは,style="ime-mode:disabled;" としておくと漢字変換モードになるのを防ぐことができます.

 KR情報を表わす画像の方は,<form>と無関係に画像として固有のnameを付けます.1つの頁には同じ名前が再度登場しないようにします.(重複すれば後者優先となります.)右図では document.kekka00.src でこの画像のソーズを張り換えています.
(実際には<form>の中の画像は document.q0.kekka00.src のように参照することもできます.この参照方法では,異なる<form>の中に同一nameがあっても使えます.)

 <img src..>のwidthとheightは画像の原寸と一致している方が無難です.原寸と表示サイズとが異なっても表示はできますが,原画に文字や線が描かれているとき,表示サイズを変更すると,明瞭に見えません.正答,誤答,未回答が一つの場所に入るので,これらの原画は同じサイズで作成しておきます.
図10
<form name="q0">
<input type="text" name="t00" value="" size="1" style="ime-mode:disabled;"> ...  <img src="neutral.gif" width="24" height="24" border="0" name="kekka00">

</form>

○===メニューに戻る