根据用户输入动态添加试验进行实验?

时间:2016-07-21 20:54:27

标签: javascript jspsych

我目前正在使用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,可能会出现美学问题。此代码要求您在与主HTML文件相同的目录中包含jspsych文件夹。

<!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>

1 个答案:

答案 0 :(得分:0)

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

该库的6.0版将添加insert timelines onto the end of the experiment的功能,这将开辟解决此问题的新方法。此功能在GitHub存储库的主分支上可用,但该分支不稳定。

相关问题