PennController for IBEX › Forums › Support › Dot-memory test
- This topic has 3 replies, 2 voices, and was last updated 1 year, 6 months ago by Jeremy.
-
AuthorPosts
-
January 30, 2023 at 5:12 pm #9862AprilParticipant
Hi Jeremy,
I am working on creating a dot-memory test, and I believe I’ve made some progress, but I might totally be on the wrong track. Here is what I have so far: https://farm.pcibex.net/r/PMcWya/
I was able to create a 3×3 grid and manipulate the position of the dots (black squares) on the grid. The participants will be asked to remember the location of black squares and reproduce the pattern. I tried a couple of things with the Selector element, but I couldn’t make it work. Also, I will need to provide feedback for the participants as to whether the pattern they produced was a match or not. Is there a way to make this work on PCIbex? How should I proceed? I don’t have much experience with HTML or JavaScript, but if it is the only way to do it, I’ll do my best.
I truly appreciate any help you may provide!
Best,
EbruFebruary 3, 2023 at 9:18 am #9878JeremyKeymasterHi Ebru,
You could get there by using the Selector element, if you created one per cell, but the code would quickly become cumbersome. A more concise solution would be to use three Scale elements, one per row, that you set as checkboxes. Then you manipulate the aesthetics to make a checked option appear as a black square, and an unchecked option as a white square
The test part in
wait
is a little tricky, because up to PennController 2.0,.test.selected
does not behave as expected on a checkbox Scale. However, one can write some concise javascript code to test that the right boxes are (un)selectedHere’s the script:
Template("dotmemorization.csv", row => newTrial("dot-pattern", defaultScale.checkbox().center().log().print() , newScale("row1", " ", " ", " "),newScale("row2", " ", " ", " "),newScale("row3", " ", " ", " ") , getScale("row1").select(row.r1c1==1?0:-1).select(row.r1c2==1?1:-1).select(row.r1c3==1?2:-1), getScale("row2").select(row.r2c1==1?0:-1).select(row.r2c2==1?1:-1).select(row.r2c3==1?2:-1), getScale("row3").select(row.r3c1==1?0:-1).select(row.r3c2==1?1:-1).select(row.r3c3==1?2:-1) , newTimer(850).start().wait() , getScale("row1").unselect(0,"log").unselect(1,"log").unselect(2,"log").remove(), getScale("row2").unselect(0,"log").unselect(1,"log").unselect(2,"log").remove(), getScale("row3").unselect(0,"log").unselect(1,"log").unselect(2,"log").remove() , newText('inst', 'Now produce the pattern').css("margin-bottom","20px").print().center() , getScale("row1").print(),getScale("row2").print(),getScale("row3").print() , newButton("press") .print() .wait( newFunction( ()=>[...document.querySelectorAll(".PennController-Scale input")].map(c=>Number(c.checked)).join('') ) .test.is([row.r1c1,row.r1c2,row.r1c3,row.r2c1,row.r2c2,row.r2c3,row.r3c1,row.r3c2,row.r3c3].join('') ) .failure( newText("Try again!").print() ) ) .center() ) )
And here’s what to put in global_main.css to make the checkboxes appear as white and black boxes:
.PennController-row1 input, .PennController-row2 input, .PennController-row3 input { display: none; } .PennController-row1 input + label, .PennController-row2 input + label, .PennController-row3 input + label { display: inline-block; width: 40px; height: 40px; background-color: white; border: solid 1px grey; } .PennController-row1 input:checked + label, .PennController-row2 input:checked + label, .PennController-row3 input:checked + label { background-color: black; }
Jeremy
February 20, 2023 at 1:47 am #9940AprilParticipantHi Jeremy,
That works like a charm, THANK you!!
One quick follow-up question, if I may: How can I modify the code such that a new trial starts after a ‘failure’? This code does not let me pass to a new trial until the pattern is reproduced correctly. I’d still like to provide feedback for a wrong match (e.g., ‘Be careful next time), and continue with the next trial. I played with the position of some parentheses, but couldn’t make it work.
Thanks for your patience,
Best,
EbruFebruary 22, 2023 at 9:15 am #9948JeremyKeymasterHi Ebru,
When you place a
test
command inside await
command, the latter is only validated when the test succeeds. If you’d rather always validate thewait
command, just leave its parentheses blank (ie..wait()
) and move the test below it if you’d like to show some feedback once the participant clicks the button. The question then is how to move from printing the feedback to the next trial; for example, you could simply wait 2s:newButton("press") .center() .print() .wait() , newFunction( ()=>[...document.querySelectorAll(".PennController-Scale input")].map(c=>Number(c.checked)).join('') ) .test.is([row.r1c1,row.r1c2,row.r1c3,row.r2c1,row.r2c2,row.r2c3,row.r3c1,row.r3c2,row.r3c3].join('') ) .success( newText("Good job!").print() ) .failure( newText("Incorrect! Better luck next time").print() ) , newTimer(2000).start().wait()
Jeremy
-
AuthorPosts
- You must be logged in to reply to this topic.