PennController for IBEX › Forums › Support › Branching Structure for filtering participants
- This topic has 8 replies, 2 voices, and was last updated 1 year, 2 months ago by AY-Osaka.
-
AuthorPosts
-
June 19, 2023 at 9:46 pm #10694AY-OsakaParticipant
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
June 20, 2023 at 7:56 am #10697JeremyKeymasterHi 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
June 22, 2023 at 6:09 pm #10700AY-OsakaParticipantThank you so much for writing up a code for me!
This is really helpful!June 23, 2023 at 12:23 am #10701AY-OsakaParticipantHi, 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")) );
June 23, 2023 at 7:31 am #10703JeremyKeymasterHi 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 yourwait
command only comes later). As a matter of fact, there is notest
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 thedefaultScale
commands fromHeader
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
June 24, 2023 at 7:32 am #10708AY-OsakaParticipantThis is amazing!
Thank you so so much for your assistance!!Best,
AY
July 4, 2023 at 8:02 am #10725AY-OsakaParticipantHi, 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() )
July 10, 2023 at 11:31 am #10733JeremyKeymasterHi,
I think there’s a bug with calling
SendResults
from withinHeader
(also you wouldn’t need any Timer or callback there anyway). One alternative would be to create aSendResults
and a final trials specifically for the too-many-errors scenario, placed after the regular ones and only accessed from thatfailure
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<l3) // the value should be below 3 .failure( jump("errorSend") , getVar("error_count").set(0) , end() ) )
Jeremy
July 12, 2023 at 10:09 am #10740AY-OsakaParticipantThank you very much for your answer!
Yes, the jump-command is just what I wanted! -
AuthorPosts
- You must be logged in to reply to this topic.