- JavaScrip is immediate, PennController is delayed
- Conditional statements
The scripts in your projects are
PennController commands, on the other hand, were specifically designed to take effect upon runtime, one command after the other, one trial after the other.
newTrial command embedded in a
Template command to keep track of the running order of the trial will not have the desired outcome. A better solution is to use a Var element, which was designed to handle runtime execution:
@Sequence( randomize("creation") , randomize("runtime") ) @ @// Will print the *creation* order %order = 0 @Template( row => @ newTrial( "creation" , % order++ // Executed immediately % , % newText("Creation Trial #"+order).print() @ , @ newButton("Next").print().wait() @ ) @) @ @// Will print the *running* order @Template( row => @ newTrial( "runtime" , ~ newVar("order",0).global().set(v=>v+1) // Executed upon runtime ~ , ~ newText("Runtime Trial #") ~ .after( newText("").text(getVar("order")) ) ~ .print() @ , @ newButton("Next").print().wait() @ ) @)
newX commands are evaluated at the beginning of your experiment, thus creating elements in memory long before their containing trials are executed. For example, the immediate evaluation of
newText explains why we needed to pass the Var element to the
text command in the example above. The same is true of the
Template commands: all the trials are created at the beginning of the experiment, regardless of when (and whether) they are executed upon runtime (again, this is why
order in the example above is incremented immediately).
For exampe, using
newImage in a
test command will always create an Image element, regardless of whether you end up printing it upon runtime. Let’s say you have a table in which you reference image filenames in a column for a subset of rows only. The following code will only run the Image element’s
@Template( row => @ newTrial( @ newText("Please answer the question below").print() @ , % newVar( row.Image ) % .testNot.is("") % .success( newImage(row.Image).print() ) @ , @ newText( row.Question ).print() @ , @ newTextInput("answer","").log().print().wait() @ ) @)
if statements in a
newTrial command. Not only will their execution not be delayed, it would also be syntactically inappropriate: ultimately,
if statements, you can use
test commands as already illustrated above, and illustrated here again:
newFunction( () => __counter_value_from_server__ % 2 ) .test.is(0) .success( newImage("test.png").print() ) .failure( newImage("filler.png").print() )
@newText("Please answer the question below").print() @, $...( row.Image != "" ? [ $ newImage(row.Image).print() $] :  )
This will include the
newImage command in the code and evaluate it only when
row.Image is a not an empty string.
- Passing a function to a Var element’s
$newVar("RT").set( v=>Date.now() ) @, @newKey("FJ").log().wait() @, $getVar("RT").set( v=>Date.now()-v )
- As a Function element:
$newFunction("timestampMultipleOfThree", () => Date.now() % 3 ) @, @newText("missed", "Bad luck, try again!") @ .color("red") @ .bold() @, @newButton("myButton", "Click me") @ .print() @ .wait( $ getFunction("timestampMultipleOfThree") $ .testNot.is() $ .success( getText("missed").remove() ) $ .failure( getText("missed").print() ) @ ) ```
- For immediate evaluation
$var randomWord = ["hello","world","bye","earth","howdy","planet"].sort(v=>Math.random()-Math.random()); @ @Template( "table.csv" , row => @ newTrial( @ defaultText.center() @ , @ newText("How similar are these two words?").print() @ , @ newText( row.Word + " -- " ) $ .after( newText(randomWord.pop()) ) @ .print() @ , @ newScale(7) @ .before( newText("Nothing alike") ) @ .after( newText("Basically identical") ) @ .center() @ .print() @ .wait() @ ) @)
In this example, we assume a 6-row table listing words in a column named Word. We want to randomly pair each of those words with a word taken form another list of 6 words.
randomWord will contain a randomized array of 6 words. The 6 trials are then generated cycling through the table’s rows, and on each cycle,
randomWord.pop() extracts the current last word from the array.
randomWord no longer contains words, it is an empty array.