実際の研究では、間違えた試行だけ後で繰り返し、全て正答するまで続けるということがよくあるが、PsychoPyのループはそういう繰り返しに対応していませんので、コードを使う必要があります(BuilderだけでできますがCodeコンポーネントが必要です。)
PsychoPyのForumで同様の質問があり、PsychoPy本の著者でもあるMichaelさんが答えていたものをもとにしています。
通常のループで1回終わった後、間違えた部分をやりなおすために、ループを二重にします。1回目に誤答したものだけ繰り返すため、誤答リストを用意します。課題は何でもいいですが、ここでは単純な例として、英語のwordとnonwordの判断としました。wordなら←、nonwordなら→を押します。正誤判定とフィードバックはループ内の別のルーチンを使っています実験刺激はrep_test.xlsxで定義しています。刺激設定で重要なのは各刺激に明示的な番号(stim_ID)をつけることです。これは誤答リストに入れるために必要で、各刺激で重複がなければ番号でも記号でも何でもかまいません。
外側のloop_wrongでは、繰り返し数を設定して順に実行(sequential)するだけで、条件ファイルの設定などは要りません。繰り返し回数は仮に5としてありますが、完全回答を必要とするならもっと大きくてもいいですし、逆に、3回間違えたらアウトにしようなどということもできますね。
それぞれのルーチンのコードコンポーネントは次のようにします(code_FBの各タブに下記のコードを記述)。
まずtestルーチンです。
「実験開始時」タブで誤答リストwrong_list
を初期化します。
wrong_list=[]
「Routine開始時」では、2巡目以降に誤答リストwrong_list
を見て処理を変えます。loop_wrong.thisN
はそのループにおける現在の繰り返し数で、0から始まります。2巡目以降で今の刺激誤答リストに無ければルーチンの継続を制御する変数continueRoutine
を偽にしてパスします。
if loop_wrong.thisN>0 and stim_ID not in wrong_list:
continueRoutine = False
次にfeedbackルーチンです。
「Routine開始時」に正誤判定とフィードバックを記述します。(フィードバックはなくてもかまいません。)
if loop_wrong.thisN>0 and stim_ID not in wrong_list:
continueRoutine = False
else:
if key_resp.corr:
msg = "OK"
msgColor = "green"
if stim_ID in wrong_list:
wrong_list.remove(stim_ID)
else:
msg = "NO!"
msgColor = "red"
if stim_ID not in wrong_list:
wrong_list.append(stim_ID)
2回目以降で、(Excelシートで指定した)stim_ID
変数がwrong_list
に入っていなければ処理をパスします。ループ初回実行時は必ず以下を実行します。wrong_list
に入っていれば、testルーチンで得られたキー反応の正誤を見てフィードバック文字の設定とwrong_list
変数への追加または削除を行っています。
「Routine終了時」では、 2巡目以降に誤答リストが空だったらループを終了するようにします。
if loop_wrong.thisN>0 and not wrong_list:
loop_tests.finished = True
loop_wrong.finished = True
結果にはパスされた試行も記録されてしまいます。自動的に計算された平均などをそのまま使うのではなく、一度は試行ごとの記録から計算し直したほうがいいかもしれません。
loop_testsはもともと試行を繰り返すものなので、その繰り返し数を1にしておいてさらに外側にループを設置するのは何か無駄なことをしているような気がしないでしょうか。実際、外側のループを使わなくても同じようなことはできますので、それをやってみたいと思います。(続く)