■ 空欄書き込み問題で「全角半角」「大文字小文字」「スペース」に対応するには

○ 使用したい場面

  右の例1のような空欄書き込み問題を文字列照合の方法で採点したいとき,

(1) 答案を全角文字(2バイト文字,日本語漢字)で書かれたらどうするか.
(2) 答案を英語大文字で書かれたらどうするか.
(3) ワープロやメールで文字間にスペースを入れるくせのある回答者にどう対応するか.

以上3項目について対応方法を考える.

【要点】
(1) 入力欄の漢字変換モードを止めておく.
(2) アルファベットの大文字は組み込みメソッドのtoLowerCase()で小文字に変換する.
(3) 余分なスペースはユーザ定義関数で取り除く.
例1
次の空欄を埋めなさい.
2x - 3=5 のとき
左辺の - 3 を右辺に移項すると
__________
したがって
__________x=

○ 考え方

(1) 「全角文字も正答にする」という考え方と「全角文字は誤答にする」という考え方があり得る.
 今の子どもたちは情報機器に接する機会が多いが,全角文字(2バイトの日本語漢字,かな,数字)と半角文字(1バイト文字)の区別がつかない生徒も多い.このため「答が合っているのになぜ誤答になるのか」などと抗議を受けることがある.
 全角文字も正答にする方法(正答の候補は増やさなくてはならない),全角文字が入力されたら半角文字に変換する方法も考えられるが,ここでは全角文字は書き込めないようにすることで,この問題を単純に回避することを考える.
○ Javascript ソースコード(主なポイント)
(1) <input type="text" value="" size="15" name="t00" style="ime-mode:disabled;">

のように ime-mode属性の値を disabled にすると,そのテキストボックスを書き込むときに漢字変換モードが外される.

※この値 disabled は1文字でも違うと働かない.ある出版社のあるマニュアルには disable となっているがミスプリントと考えられる.
※この方法でパソコンからの入力には対応できるが,ゲーム機の Play.... から回答された答案では,入力はすべて全角文字となっており全問誤答となっている・・・ゲーム機でWeb教材に回答することは想定外
(2) 文字列オブジェクトにおいてアルファベットの大文字を小文字に,小文字を大文字に変換するには,それぞれ toLowerCase() , toUpperCase() が使える.
 これはオブジェクトのメソッドとして定義されているので,例えば str1 が文字列オブジェクトであるとき,ドットでつないで
   str1.toLowerCase()
   str1.toUpperCase()
などとする.(LowerCaseが小文字,UpperCaseが大文字)

※「熱ものに懲りてなますを吹く」

 昔,A社製マシン上のB社製OS上のCという言語でプログラムを作ったとき,toUpperCase()という関数は,「小文字を大文字に変換する」ものであるはずが,元が大文字でもさらに変換していたようで使えばマシンがダウンしてしまった.
 現在,A社製マシン上のB社製OS上のDという言語でプログラムを作っているので,この関数(メソッド)はあまり使いたくないが何度かテストしてみると大丈夫なようなので使う.
(2)
入力された文字列を採点する前に加工しておく

txt_pos = new Array(document.q0.t00, document.q0.t01);

// 入力欄の数だけ繰り返す
for(var qnum = 0; qnum < txt_pos.length; qnum++)
{var work = txt_pos[qnum].value;
work = work.toLowerCase(); // 大文字は小文字に変換
・・・
txt_pos[qnum].value = work; //表示も変えておく
}

(3) 余分なスペースを取り除く trim() という風な組み込みメソッドが見つからなかったのでユーザ定義関数を作る.
 右の通り.
 (2)(3)により,幾つかの答案について,変換前と変換後の対応は次のように対応する.( _ は半角スペース)
変換前 変換後
(2) 2X=5+3 2x=5+3
(3) 2x_=_5+3 2x=5+3
(2)(3) 2_X_=_8 2x=8


(*) なお,この問題では1番目の空欄について,幾つかの表記が正答の許容範囲として考えられるので,これらを列挙し,「1つでも一致すれば正答とする」.

 許容範囲として次のものが考えられる.(単純な文字列で採点する限りすべて列挙しておく必要がある.)
'2x=5+3'
'2x=3+5'
'2x=5+3=8'
'2x=3+5=8'
'2x=8'


 2番目の空欄に入るものは1つだけなので1つ書く.これで1つだけ照合される.
 ただし, ans_set[1] = new Array(4);と書いてはいけない.
ans_set[1] = new Array('4');と書かなければならない.
 配列の定義においてかっこ内に複数個の値を書くと,定義と同時に初期化できるが,かっこ内に1個の数を書くと配列要素数の指定になるので2番目の空欄の解答配列は要素数4個で値はまだ書かれていないという解釈になる.
(3)
文字列を引数に入れて渡すと半角スペースを取り除いた文字列を返す関数

function trim_sp(str1)
{var tmp_str = ''; //清書用の文字列を貯めていくもの
for(var local_kk = 0; local_kk < str1.length; local_kk++)
{var ch1 = str1.charAt(local_kk); //前からlocal_kk番目の文字を ch1 とする
if(ch1 != ' ') // ch1が半角スペースでなければ清書用文字列に追加する
tmp_str += ch1;
}
return tmp_str; //全部転記できたら戻り値として返す
}

function saiten0()
{txt_pos = new Array(document.q0.t00, document.q0.t01);
kr_pos = new Array('kr00', 'kr01');
ans_set = new Array();
ans_set[0] = new Array('2x=5+3', '2x=3+5', '2x=3+5=8', '2x=3+5=8','2x=8');
ans_set[1] = new Array('4');


for(var qnum = 0; qnum < txt_pos.length; qnum++)
{var work = txt_pos[qnum].value;
work = work.toLowerCase();
work = trim_sp(work);
txt_pos[qnum].value = work;
}

for(var qnum = 0; qnum < ans_set.length; qnum++)
{var correct_flag = 0; //各問題を採点する前にcorrect_falgを0(=誤答)としておく
for(var subnum = 0; subnum < ans_set[qnum].length; subnum++)
{if(txt_pos[qnum].value == ans_set[qnum][subnum])
correct_flag = 1;//1つでも一致すれば correct_flagを1(=正答)にする
}
if(correct_flag == 1) //correct_flagが1(=正答)になっていれば正答としてKR情報を返す
document.getElementById(kr_pos[qnum]).innerHTML = '<span style="color:#ff0000;background-color:#ffff00;">○</span>';
else
document.getElementById(kr_pos[qnum]).innerHTML = '<span style="color:#000000;background-color:#cccccc;">×</span>';
}
}
○ 作動チェック
Internet Explorer 7.0 ・・・点検日 2009.08.01・・・OK
Firefox 3.5 ・・・点検日 2009.08.01・・・OK
○ 実際に使っているページ
../math/qu_2_1.htm
○===ソースコード・メモに戻る
○===メニューに戻る