我目前正在使用 JsPsych 创建一个行为实验,尤其是矩阵推理,因此用户可以根据逻辑模式从一组选项中进行选择。
我的问题是,如果用户在练习块后回答前两个试验时失败,我需要重复某些试验。假设前两个试验是为了练习目的,然后应用重复规则。
由于 JsPsych 的“时间线”是一个数组,它的元素(又名试验)是在整个实验开始时创建的,所以看起来我不能在实验开始后插入一个新的试验。
有没有办法根据用户输入强制执行某些试验?换句话说,如果用户选择了正确的选项,则进入下一个试验,如果他/她选择了错误的选项,则返回到某个先前的试验。
到目前为止我已经尝试过:
(基于 JsPsych 文档和来自 JsPsych Google Group 的帖子)
A) 使用 call-function 插件创建一个 var 并创建一个布尔标志,如果答案正确则为 True,否则为错误。然后,如果标志为假(即。experiment.push(another_trial)
),我会推动另一次试验。例子:
var decide_next = {
type: 'call-function',
func: myfunction,
}
function myfunction(response_flag){
if (response_flag == False){
experiment.push(survey);
}else{
//just continue as normal
}
}
var survey={
//Here goes the specified trial if the user fails
}
如前所述,由于时间线的生成方式,该解决方案完全失败。
B) 使用嵌套的时间线。这更像是一种蛮力方法,其中主时间线包含第一个问题,加上一个标志,所以如果标志获得特定值,我会推送一个特定的时间线。这个真的错了,所以我不会用毫无意义的代码来打扰你。
C) 使用条件时间线。几乎是另一种蛮力方法,但取得了更多成功。我已经使用此功能来显示不同的反馈屏幕,分别显示正确和错误的答案。例子:
//Conditional rules
var condition1 = false;
var condition2 = false;
var m_conditional1_1 = {
timeline: [m_wrong1],
conditional_function: function(data){
if(condition1 === false){
return true;
} else {
return false;
}
}
};
var m_conditional1_2 = {
timeline: [m_right1],
conditional_function: function(data){
if(condition1 === true){
return true;
} else {
return false;
}
}
};
var m_conditional2_1 = {
timeline: [m_wrong2],
conditional_function: function(data){
if(condition2 === false){
return true;
} else {
return false;
}
}
};
var m_conditional2_2 = {
timeline: [m_right2],
conditional_function: function(data){
if(condition2 === true){
return true;
} else {
return false;
}
}
};
// Feedback trials to display upon conditional trails's result
var m_wrong1 = {
type: "text",
text: "<div class = matrizlimit><div class= centered><div class='centered'><img src ='img/1A.png' /></div><br /><br /><div class='centered'><img src ='img/1B.png' </img></div><br /><br /><div class='matrizfeedback'>Eso no es correcto. <br />Para responder correctamente debe mirar de izquierda a derecha en la fila de arriba.<br /><br />"+
"Cuando usted mira la fila de arriba la estrella azul cambia a un circulo amarillo. <br />"+
"Esto quiere decir que cuando usted va de izquierda a derecha en la fila de abajo la estrella azul también deberia cambiar a un circulo amarillo.<br /><br />"+
"Para obtener la respuesta correcta yendo de arriba hacia abajo, usted debe mirar los cuadros de la columna izquierda. "+
"Cuando usted va de arriba hacia abajo en la primera columna los cuadros tienen la misma forma y el mismo color: estrellas azules. <br /><br />"+
"Esto quiere decir que cuando usted va de arriba hacia abajo en la columna derecha los cuadros también deberian tener la misma forma y el mismo color: circulo amarillo. "+
"Usted obtiene la misma respuesta yendo de izquierda a derecha y yendo de arriba hacia abajo.<br /><br /><br /><br />Presione una tecla para continuar<br /><br /><br /><br /></div>"
};
var m_right1 = {
type: "text",
text: "<div class = matrizlimit><div class= centered><div class='centered'><img src ='img/1A.png' /></div><br /><br /><div class='centered'><img src ='img/1B.png' </img></div><br /><br /><div class='matrizfeedback'>Eso es correcto.<br />Cuando usted va e izquierda a derecha en la fila de arriba la estrella azul cambia a un circulo amarillo. <br /><br />"+
"Esto quiere decir que cuando usted va de izquierda a derecha en la de abajo la estrella azul también deberia cambiar a un circulo amarillo. "+
"Cuando usted va de arriba hacia abajo en la primera columna los cuadros tienen la misma forma y el mismo color: estrellas azules. <br /><br />"+
"Esto quiere decir que cuando usted va de arriba hacia abajo en la segunda columna los cuadros también deben tener la misma forma y el mismo color: circulos amarillos. "+
"Usted obtiene la misma respuesta yendo de izquierda a derecha y yendo de arriba hacia abajo.<br /><br /><br /><br />Presione una tecla para continuar<br /><br /><br /><br /></div>"
};
var m_wrong2 = {
type: "text",
text: "<div class = matrizlimit><div class= centered><div class='centered'><img src ='img/2A.png' /></div><br /><br /><div class='centered'><img src ='img/2B.png' </img></div><br /><br /><div class='matrizfeedback'>Eso no es correcto. <br />Cuando usted mira los cuadros de izquierda a derecha, usted puede ver que ellos<br />"+
"están en el siguiente orden: círculo grande, círculo pequeño, círculo grande, círculo pequeño, círculo grande.<br /><br />"+
"El círculo pequeño va en el cuadro con un signo de interrogación porque es la opción que mantiene el orden: un círculo pequeño va luego de un círculo grande.<br />"+
"<br /><br /><br /><br />Presione una tecla para continuar<br /><br /><br /><br /></div>"
};
var m_right2 = {
type: "text",
text: "<div class = matrizlimit><div class= centered><div class='centered'><img src ='img/2A.png' /></div><br /><br /><div class='centered'><img src ='img/2B.png' </img></div><br /><br /><div class='matrizfeedback'>Eso es correcto.<br />Cuando usted mira los cuadros de izquierda a derecha, puede ver que ellos siguen este orden: "+
"círculo grande, círculo pequeño, círculo grande, círculo pequeño, círculo grande. <br /><br />"+
"El círculo pequeño va en el cuadro con un signo de interrogación porque es lo que mantiene el mismo orden que los anteriores.<br /><br />"+
"<br /><br /><br /><br />Presione una tecla para continuar<br /><br /><br /><br /></div>"
};
// The two practice trials, here I capture the chosen answer and give it to the conditional rules variables. Matriz_practice_1 is associated to m_right_1 and
// m_wrong_1, which are its possible feedback screens.
// The same goes for Matriz_practice_2, with m_right_2 and m_wrong_2
var matriz_practice_1={
type: "survey-multi-choice1",
timeline:[
{
questions: ["<div class = centerbox>"+
"<p class = justified>"+
"Mire la siguiente figura. Usted debe escoger cual de las opciones que se encuentran abajo va en el"+
"cuadro con un signo de interrogación. La respuesta correcta es aquella que encaja yendo de "+
"izquierda a derecha y yendo de arriba hacia abajo. Usted sólo debe mirar de izquierda a derecha y "+
"de arriba hacia abajo. No mire diagonalmente. ¿Cuál de las opciones que se encuentran abajo va en"+
" el cuadro con un signo de interrogación?"+
"</p><br /><br /></div>"+
"<div class= centered><div class='centered'><img src ='img/1A.png' /></div><br /><br /><div class='centered'><img src ='img/1B.png' </img></div>"],
data: {trialid: "P_MP_01"},
horizontal: true
},
],
options: [["Opcion1","Opcion2","Opcion3","Opcion4","Opcion5"]],
horizontal: true,
required: 'true',
on_finish: function(data){
var test = data.responses;
if(test =='{"Q0":"Opcion5"}'){
condition1 = true;
} else {
condition1 = false;
}
}
};
var matriz_practice_2={
type: "survey-multi-choice1",
timeline:[
{
questions: ["<div class = centerbox>"+
"<p class = justified>"+
"Éste es otro tipo de problema. Los cuadros solo van de izquierda a derecha. La respuesta correcta "+
"seguirá el mismo orden que usted ve en los cuadros. ¿Cuál de las opciones que se encuentran abajo va "+
"en el cuadro con un signo de interrogación?"+
"</p><br /><br /></div>"+
"<div class= centered><div class='centered'><img src ='img/2A.png' /></div><br /><br /><div class='centered'><img src ='img/2B.png' </img></div>"],
data: {trialid: "P_MP_02"},
horizontal: true
},
],
options: [["Opcion1","Opcion2","Opcion3","Opcion4","Opcion5"]],
horizontal: true,
required: 'true',
on_finish: function(data){
var test = data.responses;
if(test =='{"Q0":"Opcion4"}'){
condition2 = true;
} else {
condition2 = false;
}
}
};
这适用于简短的线性结构,因为在这种情况下,我只需要决定要显示哪个屏幕,但是如果需要,当尝试返回上一个试验时,此解决方案会失败。从这个解决方案中,我可以定义一组非常长的二进制条件来“模拟”用户失败时的重复试验。但这不能动态生成,所以基本上我不得不猜测用户有多少次无法正确回答,当实验要与 200 多名志愿者一起运行时,这不是一个选项。另外,如果将重复条件应用于超过 2 次试验,这种蛮力策略将增加复杂性,这实际上可能在未来发生。
我猜想对 JsPsych 的核心 javascript 文件进行深度修改可能会带来解决方案,但这超出了我目前的 javascript 技能和知识。
对此主题的帮助将不胜感激。
测试此代码的一些额外说明:
下面提供了实验代码的简短工作版本。由于这次忽略了 CSS,可能会出现美学问题。此代码要求您将 jspsych 文件夹与主 HTML 文件放在同一目录中。
<!doctype html>
<html>
<head>
<title>Condition Tester</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych-5.0.3/jspsych.js"></script>
<script src="jspsych-5.0.3/plugins/jspsych-survey-multi-choice.js"></script>
<script src="jspsych-5.0.3/plugins/jspsych-text.js"></script>
<script src="jspsych-5.0.3/plugins/jspsych-instructions.js"></script>
</head>
<body>
<div class="centered">
<script>
var condition1 = false;
var condition2 = false;
/* Texto Inicial */
var matrizexplanation={
type: "instructions",
pages: ["<div class = centerbox>"+
"<p class = center-block-text>"+
"A continuación, le presentaremos una serie de figuras, donde cada una muestra un patrón lógico.<br />"+
"Tendrá que elegir entre 5 alternativas para completar ese cada patrón."+
"</p></div>"],
allow_keys: false,
show_clickable_nav: true,
timing_post_trial: 50,
data:{trialid: "Instructions_Matriz"}
};
var matriz_practice_1={
type: "survey-multi-choice1",
timeline:[
{
questions: ["<div class = centerbox>"+
"<p class = justified>"+
"Mire la siguiente figura. Usted debe escoger cual de las opciones que se encuentran abajo va en el"+
"cuadro con un signo de interrogación. La respuesta correcta es aquella que encaja yendo de "+
"izquierda a derecha y yendo de arriba hacia abajo. Usted sólo debe mirar de izquierda a derecha y "+
"de arriba hacia abajo. No mire diagonalmente. ¿Cuál de las opciones que se encuentran abajo va en"+
" el cuadro con un signo de interrogación?"+
"</p><br /><br /></div>"+
"<div class= centered><div class='centered'><img src ='img/1A.png' /></div><br /><br /><div class='centered'><img src ='img/1B.png' </img></div>"],
data: {trialid: "P_MP_01"},
horizontal: true
},
],
options: [["Opcion1","Opcion2","Opcion3","Opcion4","Opcion5"]],
horizontal: true,
required: 'true',
on_finish: function(data){
var test = data.responses;
if(test =='{"Q0":"Opcion5"}'){
condition1 = true;
} else {
condition1 = false;
}
}
};
var matriz_practice_2={
type: "survey-multi-choice1",
timeline:[
{
questions: ["<div class = centerbox>"+
"<p class = justified>"+
"Éste es otro tipo de problema. Los cuadros solo van de izquierda a derecha. La respuesta correcta "+
"seguirá el mismo orden que usted ve en los cuadros. ¿Cuál de las opciones que se encuentran abajo va "+
"en el cuadro con un signo de interrogación?"+
"</p><br /><br /></div>"+
"<div class= centered><div class='centered'><img src ='img/2A.png' /></div><br /><br /><div class='centered'><img src ='img/2B.png' </img></div>"],
data: {trialid: "P_MP_02"},
horizontal: true
},
],
options: [["Opcion1","Opcion2","Opcion3","Opcion4","Opcion5"]],
horizontal: true,
required: 'true',
on_finish: function(data){
var test = data.responses;
if(test =='{"Q0":"Opcion4"}'){
condition2 = true;
} else {
condition2 = false;
}
}
};
var m_wrong1 = {
type: "text",
text: "<div class = matrizlimit><div class= centered><div class='centered'><img src ='img/1A.png' /></div><br /><br /><div class='centered'><img src ='img/1B.png' </img></div><br /><br /><div class='matrizfeedback'>Eso no es correcto. <br />Para responder correctamente debe mirar de izquierda a derecha en la fila de arriba.<br /><br />"+
"Cuando usted mira la fila de arriba la estrella azul cambia a un circulo amarillo. <br />"+
"Esto quiere decir que cuando usted va de izquierda a derecha en la fila de abajo la estrella azul también deberia cambiar a un circulo amarillo.<br /><br />"+
"Para obtener la respuesta correcta yendo de arriba hacia abajo, usted debe mirar los cuadros de la columna izquierda. "+
"Cuando usted va de arriba hacia abajo en la primera columna los cuadros tienen la misma forma y el mismo color: estrellas azules. <br /><br />"+
"Esto quiere decir que cuando usted va de arriba hacia abajo en la columna derecha los cuadros también deberian tener la misma forma y el mismo color: circulo amarillo. "+
"Usted obtiene la misma respuesta yendo de izquierda a derecha y yendo de arriba hacia abajo.<br /><br /><br /><br />Presione una tecla para continuar<br /><br /><br /><br /></div>"
};
var m_right1 = {
type: "text",
text: "<div class = matrizlimit><div class= centered><div class='centered'><img src ='img/1A.png' /></div><br /><br /><div class='centered'><img src ='img/1B.png' </img></div><br /><br /><div class='matrizfeedback'>Eso es correcto.<br />Cuando usted va e izquierda a derecha en la fila de arriba la estrella azul cambia a un circulo amarillo. <br /><br />"+
"Esto quiere decir que cuando usted va de izquierda a derecha en la de abajo la estrella azul también deberia cambiar a un circulo amarillo. "+
"Cuando usted va de arriba hacia abajo en la primera columna los cuadros tienen la misma forma y el mismo color: estrellas azules. <br /><br />"+
"Esto quiere decir que cuando usted va de arriba hacia abajo en la segunda columna los cuadros también deben tener la misma forma y el mismo color: circulos amarillos. "+
"Usted obtiene la misma respuesta yendo de izquierda a derecha y yendo de arriba hacia abajo.<br /><br /><br /><br />Presione una tecla para continuar<br /><br /><br /><br /></div>"
};
var m_wrong2 = {
type: "text",
text: "<div class = matrizlimit><div class= centered><div class='centered'><img src ='img/2A.png' /></div><br /><br /><div class='centered'><img src ='img/2B.png' </img></div><br /><br /><div class='matrizfeedback'>Eso no es correcto. <br />Cuando usted mira los cuadros de izquierda a derecha, usted puede ver que ellos<br />"+
"están en el siguiente orden: círculo grande, círculo pequeño, círculo grande, círculo pequeño, círculo grande.<br /><br />"+
"El círculo pequeño va en el cuadro con un signo de interrogación porque es la opción que mantiene el orden: un círculo pequeño va luego de un círculo grande.<br />"+
"<br /><br /><br /><br />Presione una tecla para continuar<br /><br /><br /><br /></div>"
};
var m_right2 = {
type: "text",
text: "<div class = matrizlimit><div class= centered><div class='centered'><img src ='img/2A.png' /></div><br /><br /><div class='centered'><img src ='img/2B.png' </img></div><br /><br /><div class='matrizfeedback'>Eso es correcto.<br />Cuando usted mira los cuadros de izquierda a derecha, puede ver que ellos siguen este orden: "+
"círculo grande, círculo pequeño, círculo grande, círculo pequeño, círculo grande. <br /><br />"+
"El círculo pequeño va en el cuadro con un signo de interrogación porque es lo que mantiene el mismo orden que los anteriores.<br /><br />"+
"<br /><br /><br /><br />Presione una tecla para continuar<br /><br /><br /><br /></div>"
};
var m_conditional1_1 = {
timeline: [m_wrong1],
conditional_function: function(data){
if(condition1 === false){
return true;
} else {
return false;
}
}
};
var m_conditional1_2 = {
timeline: [m_right1],
conditional_function: function(data){
if(condition1 === true){
return true;
} else {
return false;
}
}
};
var m_conditional2_1 = {
timeline: [m_wrong2],
conditional_function: function(data){
if(condition2 === false){
return true;
} else {
return false;
}
}
};
var m_conditional2_2 = {
timeline: [m_right2],
conditional_function: function(data){
if(condition2 === true){
return true;
} else {
return false;
}
}
};
var matrizstarter={
type: "instructions",
pages: ["<div class = centerbox>"+
"<p class = center-block-text>"+
"Ahora deberá seguir respondiendo, pero no recibirá avisos indicando <br />si su respuesta es correcta o incorrecta.<br /><br />"+
"</p></div>"],
allow_keys: false,
show_clickable_nav: true,
timing_post_trial: 50,
data:{trialid: "Instructions_Matriz"}
};
var matrices = {
//type: "survey-multi-choice",
type: "survey-multi-choice1",
timeline:[
/*{
questions: ["<div class='centered'><img src ='img/1A.png' /></div><br /><br /><div class='centered'><img src ='img/1B.png' </img></div>"],
data: {trialid: "MP_01"},
horizontal: true
//options: ["Opcion1","Opcion2","Opcion3","Opcion4","Opcion5"]
},
{
questions: ["<div class='centered'><img src ='img/2A.png' /></div><br /><br /><div class='centered'><img src ='img/2B.png' </img></div>"],
data: {trialid: "MP_02"}
//options: ["Opcion1","Opcion2","Opcion3","Opcion4","Opcion5"]
},*/
{
questions: ["<div class='centered'><img src ='img/3A.png' /></div><br /><br /><div class='centered'><img src ='img/3B.png' </img></div>"],
data: {trialid: "MP_03"}
//options: ["Opcion1","Opcion2","Opcion3","Opcion4","Opcion5"]
},
],
options: [["Opcion1","Opcion2","Opcion3","Opcion4","Opcion5"]],
horizontal: true,
required: 'true',
};
var experimento_matrices = [];
experimento_matrices.push(matrizexplanation);
experimento_matrices.push(matriz_practice_1);
experimento_matrices.push(m_conditional1_1);
experimento_matrices.push(m_conditional1_2);
experimento_matrices.push(matriz_practice_2);
experimento_matrices.push(m_conditional2_1);
experimento_matrices.push(m_conditional2_2);
experimento_matrices.push(matrizstarter);
experimento_matrices.push(matrices);
jsPsych.init({
timeline: experimento_matrices,
on_finish: function(){
jsPsych.data.localSave('second_battery_results.csv', 'csv');
},
on_trial_start: function(){
console.log("***************************",test);
},
default_iti: 0
});
</script>
</div>
</body>
</html>