Reply To: Logging Results for Multiple Attempts

PennController for IBEX Forums Support Logging Results for Multiple Attempts Reply To: Logging Results for Multiple Attempts

#6000
Jeremy
Keymaster

Hi Anna,

There is, but things are getting a little messy. You’ll need to execute some plain javascript code just before repeating the calls to truly randomize their order. This is precisely what the newFunction element is for. Here’s a possible implementation:

newTrial("flapTest",
    newFunction("init", function(){ 
        this.progress = -1; 
        this.indices = [... new Array(8)].map((v,i)=>i).sort(v=>Math.random()-0.5);
    }).call()
    ,
    newFunction("getNextIndex", function(){
        this.progress++;
        if (this.progress>=this.indices.length) return "stop";
        return this.indices[this.progress];
    })
    ,
    newButton("carryOn").log()
    ,
    newButton("launch").callback(
        newVar("whichIndex").set( getFunction("getNextIndex").call() )
        .test.is(0).success( ...launch("1", "adequateT.mp3", "<p>Correct!</p>", "<p>Incorrect.</p>", "a flap") )
        .test.is(1).success( ...launch("2", "bitterT.mp3", "<p>Correct!</p>", "<p>Incorrect.</p>", "a flap") )
        .test.is(2).success( ...launch("3", "daddyT.mp3", "<p>Correct!</p>", "<p>Incorrect.</p>", "a flap") )
        .test.is(3).success( ...launch("4", "mottoT.mp3", "<p>Correct!</p>", "<p>Incorrect.</p>", "a flap") )
        .test.is(4).success( ...launch("5", "italicsT.mp3", "<p>Incorrect.</p>", "<p>Correct!</p>", "not a flap") )
        .test.is(5).success( ...launch("6", "planetaryT.mp3", "<p>Incorrect.</p>", "<p>Correct!</p>", "not a flap") )
        .test.is(6).success( ...launch("7", "producingT.mp3", "<p>Incorrect.</p>", "<p>Correct!</p>", "not a flap") )
        .test.is(7).success( ...launch("8", "traditionT.mp3", "<p>Incorrect.</p>", "<p>Correct!</p>", "not a flap") )
        .test.is("stop").success( getButton("carryOn").click() )
        .testNot.is("stop").success( getButton("launch").click() )
    ).click()
    ,
    getButton("carryOn").wait()
    ,
    newText("evaluation", "Your number of correct answers: ").after(newText("").text(getVar("FlapScore")))
        .print()
    ,
    getVar("FlapScore")
        .test.is(v=>v>=5)
        .success(
            newText("<p>Good job! When you're ready, press the button below to proceed.</p>").print(), 
            newButton("Continue").print().wait()
        )
        .failure(
            newText("nope1", "<p>Given your score, we would like you to take the quiz again. Press the button below to proceed.</p>").print(),
            newButton("toNext1", "Continue").print().wait(), 
            getFunction("init").call(),
            getText("nope1").remove(), 
            getButton("toNext1").remove(), 
            getText("evaluation").remove(), 
            getButton("launch").click(),
            getButton("carryOn").wait()
        )
)

The init function is what takes care of randomly ordering the indices, and (re)setting the pointer (this.progress) to the first index in the random list (this.indices). The getNextIndex function, which is called whenever the launch button is clicked (manually or by simulation) will increment the pointer and return the next index in the list. By assigning that value to a Var element, we can test it and run the corresponding launch sequence. If the indices have been exhausted, the value is "stop", in which case we simulate a click on carryOn, otherwise we simulate a new click on launch which will run the next sequence from the randomized list of indices.

Note the line getFunction("init").call() just before repeating the training, so as to reinitialize the pointer and re-randomize the list of indices

Let me know if you have questions

Jeremy