Branching Structure for filtering participants

PennController for IBEX Forums Support Branching Structure for filtering participants

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #10694
    AY-Osaka
    Participant

    Hi, I am a beginner of PC Ibex, who wants to filter participants during the experiments depending on how many times they have made the wrong answers to the dummy items whose correct answer is uniquely identified.

    I am assuming that the following procedure would be necessary.

    1. Set a global variable at the beginning of the experiment, something like error_count, to 0.
    2. During the experiment, the value of the variable is incremented every time the participant makes a mistake.
    3. When the value of the variable is above the threshold (say, 3 times), the participant is invited to see a message telling that they made too many mistakes and are no longer allowed to continue the experiments. Then, the experiment is forced to be terminated.
    4. For those who have not made that many mistakes can successfully continue the experiment to the last.

    I am suspecting that there must be a sled in the forum or description in the manual, but I could not find one. If you know where to find the code that enables me to filter participants, please direct me to the description.

    Otherwise, do you mind showing me how to do this.

    Best,

    AY

    #10697
    Jeremy
    Keymaster

    Hi AY,

    Here’s a basic illustration of what you described:

    // This will be included at the beginning of every trial
    Header(
        newVar("error_count",0) // set the initial value to 0
            .global()           // make sure the Var element is global
            .test.is(v=>v<3)    // the value should be below 3
            .failure(           // if not, then block the script here
                newText("Sorry, too many mistakes. The end.").center().print()
                ,
                newButton().wait() // will wait forever
            )
        ,
        defaultScale.button().print().wait()
    )
    
    // 8 dummy trials
    newTrial( newScale("dummy", "Yes", "No").test.selected("Yes").failure(getVar("error_count").set(v=>v+1)) )
    newTrial( newScale("dummy", "Yes", "No").test.selected("Yes").failure(getVar("error_count").set(v=>v+1)) )
    newTrial( newScale("dummy", "Yes", "No").test.selected("Yes").failure(getVar("error_count").set(v=>v+1)) )
    newTrial( newScale("dummy", "Yes", "No").test.selected("Yes").failure(getVar("error_count").set(v=>v+1)) )
    newTrial( newScale("dummy", "Yes", "No").test.selected("Yes").failure(getVar("error_count").set(v=>v+1)) )
    newTrial( newScale("dummy", "Yes", "No").test.selected("Yes").failure(getVar("error_count").set(v=>v+1)) )
    newTrial( newScale("dummy", "Yes", "No").test.selected("Yes").failure(getVar("error_count").set(v=>v+1)) )
    newTrial( newScale("dummy", "Yes", "No").test.selected("Yes").failure(getVar("error_count").set(v=>v+1)) )
    

    Jeremy

    #10700
    AY-Osaka
    Participant

    Thank you so much for writing up a code for me!
    This is really helpful!

    #10701
    AY-Osaka
    Participant

    Hi, can I also continue asking a question.
    I have tried to incorporate your suggestion to the template for my filler items. And I prepared the following code, which does not seem to be the right answer unfortunately.

    Can you tell me how I fix this?

    Best,

    AY

    ——————————————————-

    Template(
        "filler.csv" //File containing the filler items, which has the column "correct_answer" to specify the true answer for the dummy element.
        , row => 
        newTrial(
            
            row.type 
            
            
            , newText("instruction", "Press the space key to continue.")
                    .center()
                    .print()
                    
         
            , newKey(" ")
                .wait()
                
            
            , getText("instruction")
                .remove()
            
    
        , newController("AcceptabilityJudgment",  {s : row.sentence
            , presentAsScale: true
            , as: [["1", "1"], ["2", "2"], ["3", "3"], ["4", "4"], ["5", "5"]]
            , showNumbers: false 
            , hasCorrect: Number(row.correct_answer) 
            , randomOrder: false
            , leftComment: "Grammatical"
            , rightComment: "Ungrammatical"
        }) 
            .test.selected(row.correct_answer).failure(getVar("error_count").set(v=>v+1)) // I added the test command here, but this does not seem to be the right solution... (without this command, the experiment is successfully implemented.
            .css("text-align", "center")
            .center()
            .print()
            .log()
            .wait()
        )
        .log("item", row.item)
        .log("cond", row.cond)
        .log("group", row.group)
        .log("id", getVar("ID"))
    );
    #10703
    Jeremy
    Keymaster

    Hi AY,

    There is no .test.selected command on the Controller element (and even if there were, you would be testing the selection before it even happened because your wait command only comes later). As a matter of fact, there is no test command on the Controller element whatsoever, because it’s a native-Ibex element. My suggestion is you use the Scale element, as in my example (note that you want to remove the defaultScale commands from Header if you use the code below):

    newText( row.sentence ).center().print()
    ,
    newScale("choice", 5)
      .button()
      .keys()
      .before( newText("Grammatical") )
      .after( newText("Ungrammatical") )
      .log()
      .center()
      .print()
      .wait()
      .test.selected( row.correct_answer ).failure(getVar("error_count").set(v=>v+1))
    

    You can play with the scale’s aesthetics by using CSS rules. See this post for a minimal example

    Jeremy

    #10708
    AY-Osaka
    Participant

    This is amazing!
    Thank you so so much for your assistance!!

    Best,

    AY

    #10725
    AY-Osaka
    Participant

    Hi, may I ask you another related question?

    (Everything you told me was perfect, and I am using them. But, I have another need)

    I want to collect the results even for those who cannot continue to the last.
    This is because I want to get the IP-address, so I can track and rule out such insincere participants in future tasks.

    To this end, I tried to write the following code by making a dummy timer that is intended to allow me to use the SendResults() function, but this does not work at all.
    Do you mind telling how to fix this?

    Thank you so much in advance for your help!

    AY

    Header(
        newVar("error_count",0) // set the initial value to 0
            .global()           // make sure the Var element is global
            .test.is(v=>v<3)    // the value should be below 3
            .failure(           // if not, then block the script here
                newTimer("timer1", 1)
                   .start()
                   .callback(
                       SendResults()
                   )
                   .wait()
                ,
                newText("Sorry, too many mistakes. The end.").center().print()
                ,
                newButton().wait() // will wait forever
            )
        ,
        defaultScale.button().print().wait()
    )
    
    • This reply was modified 1 year ago by AY-Osaka.
    • This reply was modified 1 year ago by AY-Osaka.
    • This reply was modified 1 year ago by AY-Osaka.
    #10733
    Jeremy
    Keymaster

    Hi,

    I think there’s a bug with calling SendResults from within Header (also you wouldn’t need any Timer or callback there anyway). One alternative would be to create a SendResults and a final trials specifically for the too-many-errors scenario, placed after the regular ones and only accessed from that failure command. Here’s a basic illustration of the idea, which you can adapt to your needs:

    Sequence( randomize("experiment"), "normalSend", "normalEnd", "errorSend", "errorEnd")
    
    SendResults("normalSend")
    newTrial("normalEnd", newText("Congrats, you did it!").print(), newButton().wait() )
    
    SendResults("errorSend")
    newTrial("errorEnd", newText("Sorry, too many mistakes. The end.").print(), newButton().wait() )
    
    Header(
        newVar("error_count",0) // set the initial value to 0
            .global()           // make sure the Var element is global
            .test.is(v=>v&ltl3)    // the value should be below 3
            .failure( jump("errorSend") , getVar("error_count").set(0) , end() )
    )

    Jeremy

    #10740
    AY-Osaka
    Participant

    Thank you very much for your answer!
    Yes, the jump-command is just what I wanted!

Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.