Forum Replies Created
-
AuthorPosts
-
JeremyKeymasterHi,
The
pickfunction only accepts IBEX-style predicates as an argument (eg.randomize("label")) butfeaturesis a 10-ary array, so passing it topickdirectly won’t workYou can create a (sub)sequence from it though, using IBEX’s
seqfunction:seq(...features)So you could do that:
featuresSeq = seq(...features) Sequence("WelcomeConsent", "counter", "demographics", "instructions1", "exercise", "startofexp", pick(featuresSeq,500),"break", pick(featuresSeq,500),"break", pick(featuresSeq,500), SendResults(), "Bye");Jeremy
November 1, 2022 at 12:43 pm in reply to: Media recordings not uploading to server after crash #9659
JeremyKeymasterHi Val,
So just to make sure we’re on the same page, you don’t even get a zip file for the practice items?
I just took a test run of the practice+B1 items, and the two corresponding POST requests were responsed with
uploads/f9c2be0d-3a62-5b8d-cdd3-12477feb343e.zip(practice) anduploads/8ee6d91a-d111-d194-0528-341f049e8478.zip(B1); are you saying you don’t see those two zip files in the uploads subfolder on your server?Jeremy
JeremyKeymasterHi Jet,
I checked the database and the good news is, all submissions seem to have 57 rows each, so the mostly empty results file you get does not mean that there was a problem during data collection, but only during the download process
The farm has been slow again for the past few hours, but it looks like it’s doing a little better now. Let me know if you still have trouble accessing your results file, and if you do, I will generate one for you
Jeremy
JeremyKeymasterHi,
When I try your code with the table you posted above (adding a “Sentence” column) I do get both “Long” and “Short” trials included in the experimental sequence. Do you have a link to your experiment so I can help troubleshoot?
Jeremy
JeremyKeymasterHi Jeff,
If you know in advance that you want 10 trials to use column 2 (let’s call it “Joke”) and 10 to use column 3 (let’s call it “NonJoke”) you can simply generate an array of 20 entries, half
truehalffalse, shuffle that array and scan it withinTemplate:Sequence( rshuffle("trial-joke","trial-non-joke") ) var jokings = [...new Array(20)].map((v,i)=>i<10); fisherYates(jokings); var joking; Template( row => newTrial( "trial-" + ((joking=jokings.pop()) ? "joke" : "non-joke") , newText( "prompt" , ( joking ? row.Joke : row.NonJoke ) ).print() // ... ) .log( "joking" , joking ) )Jeremy
JeremyKeymasterHello,
Are you still experiencing this issue? I just took a partial test run, and the upload requests were responded with a zip filename, which signals that the PHP script ran successfully. However, I can’t check your server to see if the zip file did end up in the upload folder
Jeremy
JeremyKeymasterHi,
If you are not familiar with the way (PC)Ibex offers control over the sequence of trials, I recommend reading the PCIbex documentation on labels and the original IBEX manual
In your case, all you need to do to get 1+2 is properly label the trials so you can reference them appropriately in predicates (
randomize) in theSequencecommand:Template( row => newTrial( row.Condition+"_Set"+row.Set , // etc. Sequence( randomize(startsWith("Short")) , randomize(startsWith("Long")) )Mixing fillers in is more complex if you have a single set of fillers that should be distributed across the “Short” and “Long” trials. If you know in advance how many filler trials you’ll have (say, 40) you could use the custom
pickfunction to randomly pick half (20) of those trials and mix them in with the “Short” trials, and mix the other half in with the “Long” trials:fillers = randomize("Filler") // assuming all your filler trials are labeled "Filler" Sequence( rshuffle( startsWith("Short") , pick(fillers,20) ), rshuffle( startsWith("Long") , pick(fillers,20) ) )Jeremy
-
This reply was modified 2 years, 12 months ago by
Jeremy. Reason: added missing closing parentheses
JeremyKeymasterHi Laia,
Place the code you have after the first
waitincallbackinstead:newTrial("location", newText("Where do you live?").print().cssContainer({"margin":"1em"}) , defaultScale.radio().labelsPosition("right").log() , newButton("go") , newScale("us", 'California', 'New York'), newScale("uk", 'England', 'Scotland') , newScale("country", "US", "UK").print().cssContainer({"margin":"1em"}) .callback( getButton("go").remove(), getScale("uk").remove().test.selected().success(self.unselect()), getScale("us").remove().test.selected().success(self.unselect()) , self.test.selected("US") .success( getScale("us").print().wait(),getButton("go").print() ) .failure( getScale("uk").print().wait(),getButton("go").print() ) ) , getButton("go").wait() )Jeremy
October 28, 2022 at 4:25 pm in reply to: Randomizing trials, with 1/5 of trials followed by a comprehension question #9641
JeremyKeymasterHi,
Some elements are missing from the pieces of code you posted (how
color_order_label,leftColor,centerColor,rightColorandgetImageEmotionare defined, where/whethercreateColorGroupis called elsewhere) but if I understand your question correctly, you should be able to do something like this:function createColorGroup(int) { var bugba = ["blue", "green", "black", "bugba"]; var gbuba = ["green", "blue", "black", "gbuba"]; var bagbu = ["black", "green", "blue", "bagbu"]; var gbabu = ["green", "black", "blue", "gbabu"]; var babug = ["black", "blue", "green", "babug"]; var bubag = ["blue", "black", "green", "bubag"]; var groups = [bugba, gbuba, bagbu, gbabu, babug, bubag]; return groups[int]; } color_group = createColorGroup(Math.round(6*Math.random())) leftColor = color_group[0] centerColor = color_group[1] rightColor = color_group[2] color_order_label = color_group[3] Template( "emoMusicGroupedPracticeV2.csv" , row => newTrial("PracticeEmoMusic", newAudio(row.audiofile).center().print().wait() , newText("Q", "<p>Whose face matches the music?</p>").center().css("font-size", "1.5em").print() , newSelector("eugenies").once().frame("dashed 0px white") , defaultImage.cssContainer({border:"solid 2px black","background-color":"white"}) , newImage(String(getImageEmotion(row.leftImage)), leftColor+row.leftImage), newImage("calmImage", centerColor + "calmnolabel.jpg"), newImage(String(getImageEmotion(row.rightImage)), rightColor+row.rightImage) , newCanvas("labels", 600, 200) .add("center at 18%", "middle at 50%", getImage(String(getImageEmotion(row.leftImage)))) .add("center at 50%", "middle at 50%", getImage("calmImage")) .add("center at 82%", "middle at 50%", getImage(String(getImageEmotion(row.rightImage)))) .color("yellow") .cssContainer("border", "solid 2px black") .center() .print() // etc. ) .log("id", getVar("subjID")) .log("color_group", color_order_label) )Jeremy
JeremyKeymasterHello,
Thank you for your messages. The farm was having issues handling traffic yesterday and crashed earlier today. I have restarted the servers and it is now running normally again
Apologies for the inconvenience,
JeremyOctober 27, 2022 at 12:31 pm in reply to: Picture resources not printed during experimentation #9633
JeremyKeymasterHello,
Do you still experience the problem today? Everything runs smoothly when I open your demonstration links
Best,
Jeremy
JeremyKeymasterHello Jinyoung,
As you found out, the problem with the command
disableis that it doesn’t prevent the participant from playing the audio again by simply pressing the spacebar (which is something I should fix). Another problem is there’s nocallbackcommand on the Audio element that you could use afterwaitto execute some commands after later playbacksSo one solution is to use another element’s
callbackcommand to execute some code that will run in parallel to the main script, which still needs to be runningwaiton the Selector element:newAudio("audio", variable.audio).center().print().wait(), newTimer("callback",1).callback( getAudio("audio").wait().remove() ).start()This way, if the participant plays the Audio element again, it will simply disappear from the page
Now, another problem with your script is you print a Canvas element at the center of the page that you scale to fit the page’s dimensions, which results in that Canvas element covering the other elements already on the page, notably the Audio element, which you can no longer click because clicks now target the Canvas element on top of it instead. You should probably rethink the way you display the different elements (eg. by printing everything, including the texts and the Audio element inside the Canvas element) but if you want to keep things how they currently are, a straightforward solution is to make the clicks on the Canvas element “transparent”:
newCanvas("canvas", 1800, 1000) .add(200, 380, getImage("nrc") ) .add(1000, 380, getImage("rrc") ) .scaling("page") .print("center at 50vw", "middle at 50vh") .cssContainer("pointer-events", "none")Jeremy
JeremyKeymasterHi Laia,
The code you posted in your message works perfectly well (except for the missing
"after"practice1) but the code in your project has additional commands. In particular, it has this:defaultText.cssContainer({"margin-top":"1em", "margin-bottom":"1em"}).print(). This will silently add.print()right next to anynewTextcommand, which is why you see both sentence1 and sentence2 appear below each other as soon as they are created. Just remove.print():defaultText.cssContainer({"margin-top":"1em", "margin-bottom":"1em"})The audios are not all played in the same order: I just had a test run where the first trial played audio2 then audio1, and the second trial played audio1 then audio2. Granted, there are only three trials, so it’s not unlikely that some test runs will play all three pairs of audios in the same order, just by chance
Jeremy
JeremyKeymasterHi Laia,
This line
newVar("tag1").global().set(getScale("input_tag1"))will set the Var element to the last selected value, so you won’t exactly get what you want indeed: if the participant checks “oi” and later on also checks “fa”, then the Var element’s value will be “fa” and you won’t detect that “oi” is still checkedBecause the Scale element only detects the most recent selection, you’ll need to use a workaround:
newTrial("pretest", newScale("input_tag1", "eh", "no", "oi", "fa") .checkbox().log().vertical().print(), newButton("go", "Endavant").print().wait(), newVar("tag1").global().set( ()=>document.querySelector("input[value='oi']").checked ) ) newTrial("exp", getVar("tag1").test.is(true).success( newText("instrus1", "You selected 'oi'!.") .print(), newButton("go", "Endavant") .print() .wait() ) )Jeremy
JeremyKeymasterHi Laia,
Your first trial (“pretest”) shows a Scale element, immediately sets the Var element “tag1” to the currently selected value on the scale (ie. no value, since the participant hasn’t had time to make a choice yet) then prints the “go” button and wait for a click before moving on to the next trial
You second trial (“exp”) actually contains a fatal error, so it won’t be run, but if it were, it would check that the value of that Var element corresponds to the value of the variable
oi, which is not only undefined (as far as I can tell) but most importantly not declared: the script does not know whatoirefers to and crashes at that point, never creating the second trial nor executing any of the code that comes after that (ie. it doesn’t create the “end” trial either)So you’ll want to switch the order of the last two lines of your first trial and add double quotes around
oiin the second trial:newTrial("pretest", newScale("input_tag1", "eh", "no", "oi", "fa") .checkbox().log().vertical().print(), newButton("go", "Endavant") .print() .wait(), newVar("tag1").global().set(getScale("input_tag1")) ) newTrial("exp", getVar("tag1").test.is("oi").success( newText("instrus1", "You selected 'oi'!.") .print(), newButton("go", "Endavant") .print() .wait() ) )If by “selecting at least oi” you mean selecting “oi” or “fa”, you can add a disjunct to your test:
getVar("tag1").test.is("oi").or( getVar("tag1").test.is("fa") ).success(Jeremy
-
This reply was modified 2 years, 12 months ago by
-
AuthorPosts