3

我目前正在使用 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&eacute;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&eacute;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&eacute;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&eacute;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&aacute;n en el siguiente orden: c&iacute;rculo grande, c&iacute;rculo peque&ntilde;o, c&iacute;rculo grande, c&iacute;rculo peque&ntilde;o, c&iacute;rculo grande.<br /><br />"+
                             "El c&iacute;rculo peque&ntilde;o va en el cuadro con un signo de interrogaci&oacute;n porque es la opci&oacute;n que mantiene el orden: un c&iacute;rculo peque&ntilde;o va luego de un c&iacute;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&iacute;rculo grande, c&iacute;rculo peque&ntilde;o, c&iacute;rculo grande, c&iacute;rculo peque&ntilde;o, c&iacute;rculo grande. <br /><br />"+
                             "El c&iacute;rculo peque&ntilde;o va en el cuadro con un signo de interrogaci&oacute;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&oacute;n. La respuesta correcta es aquella que encaja yendo de "+
                            "izquierda a derecha y yendo de arriba hacia abajo. Usted s&oacute;lo debe mirar de izquierda a derecha y "+
                            "de arriba hacia abajo. No mire diagonalmente. &iquest;Cu&aacute;l de las opciones que se encuentran abajo va en"+
                            " el cuadro con un signo de interrogaci&oacute;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>"+
                           "&Eacute;ste es otro tipo de problema. Los cuadros solo van de izquierda a derecha. La respuesta correcta "+
                            "seguir&aacute; el mismo orden que usted ve en los cuadros. &iquest;Cu&aacute;l de las opciones que se encuentran abajo va "+
                            "en el cuadro con un signo de interrogaci&oacute;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&oacute;n, le presentaremos una serie de figuras, donde cada una muestra un patr&oacute;n l&oacute;gico.<br />"+
                           "Tendr&aacute; que elegir entre 5 alternativas para completar ese cada patr&oacute;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&oacute;n. La respuesta correcta es aquella que encaja yendo de "+
                            "izquierda a derecha y yendo de arriba hacia abajo. Usted s&oacute;lo debe mirar de izquierda a derecha y "+
                            "de arriba hacia abajo. No mire diagonalmente. &iquest;Cu&aacute;l de las opciones que se encuentran abajo va en"+
                            " el cuadro con un signo de interrogaci&oacute;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>"+
                           "&Eacute;ste es otro tipo de problema. Los cuadros solo van de izquierda a derecha. La respuesta correcta "+
                            "seguir&aacute; el mismo orden que usted ve en los cuadros. &iquest;Cu&aacute;l de las opciones que se encuentran abajo va "+
                            "en el cuadro con un signo de interrogaci&oacute;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&eacute;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&eacute;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&eacute;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&eacute;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&aacute;n en el siguiente orden: c&iacute;rculo grande, c&iacute;rculo peque&ntilde;o, c&iacute;rculo grande, c&iacute;rculo peque&ntilde;o, c&iacute;rculo grande.<br /><br />"+
                             "El c&iacute;rculo peque&ntilde;o va en el cuadro con un signo de interrogaci&oacute;n porque es la opci&oacute;n que mantiene el orden: un c&iacute;rculo peque&ntilde;o va luego de un c&iacute;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&iacute;rculo grande, c&iacute;rculo peque&ntilde;o, c&iacute;rculo grande, c&iacute;rculo peque&ntilde;o, c&iacute;rculo grande. <br /><br />"+
                             "El c&iacute;rculo peque&ntilde;o va en el cuadro con un signo de interrogaci&oacute;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&aacute; seguir respondiendo, pero no recibir&aacute; 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>
4

1 回答 1

0

考虑到图书馆的当前状态,选项 C 是您最好的选择。包含时间线的数组在调用 jsPsych.init() 时会转换为内部的一组 TimelineNode 对象,并且在实验运行时无法修改。

该库的 6.0 版将添加在实验结束时插入时间线的功能,这将开辟解决此问题的新方法。此功能在 GitHub 存储库的主分支上可用,但该分支不稳定。

于 2016-08-09T19:43:42.300 回答