Forum Replies Created
-
AuthorPosts
-
Jeremy
KeymasterHi,
I moved this topic to the Support section of the forums.
I think what you are looking for is the rshuffle function:
Sequence( rshuffle("A","filler","B") ) Template( "Data.csv" , row => newTrial( row.Condition , // etc.
Jeremy
Jeremy
KeymasterHi,
You can code this manually:
newMediaRecorder("recorder","audio").log() , newButton("Record").print().wait().remove() , getMediaRecorder("recorder").record() , newButton("Stop").print().wait().remove() , getMediaRecorder("recorder").stop()
Jeremy
Jeremy
KeymasterHi Juliana,
When using the DashedSentence option with a Controller element, the EventTime column reports the exact same value for all the rows: it corresponds to when the Controller element was completed, so in the case of DashedSentence it corresponds to the end of the whole sentence.
PennController automatically sorts rows for each trial based on their EventTime column, but since they all have the same value for the Controller element, different browsers will default to different strategies.
If you need to retrieve the real event time for each word, you should use the extra Reading time column (3rd after EventTime, if I’m not mistaken) to calculate it. For example, because you have five chunks, the EventTime column for the last chunk is already accurate, but for the fourth chunk, you’d need to subtract the Reading time value from the fifth column, and for the third chunk, you’d need to also subtract the Reading time value from the fourth column, and so on.
Let me know if you have any questions
Jeremy
Jeremy
KeymasterHi,
The 200 code means that your server did respond to the upload request, but it failed to save a file. The PHP script from the guide page outputs the PermissionDeniedError message in three situations: there was no fileName parameter in the upload request, there was no valid upload file in the request, or the extension in the fileName parameter was not valid.
I suspect that what happened to your participants is that their file was just too big. I suggest that you increase the maximum post and upload file sizes.
Unless those uploads were asynchronous uploads (eg. UploadRecordings("label", "noblock")) your participants must have been prompted with a message containing a link to download an archive of their recordings. You could try to reach out to them to see if they saved it and can send it to you
I’m sorry for the inconvenience
Jeremy
Jeremy
KeymasterHi,
Key elements remain active until you explicitly disable them. By default, log will only report keypresses that validate a wait command on the Key element. In your case, you have no wait command on the “audioanswer” Key element, so you use log("last"). Because you end the trial by requiring that your participant press the spacebar, and because that key is also part of the “audioanswer” keys, the last keypress that was captured by your “audioanswer” Key element necessarily is a spacebar, which is reported as a space character in your results file (...,Key,audioanswer,PressedKey, ,1611166764724,...)
Here’s one solution to your problem:
newKey("audioanswer", "Y", " ") .log("last") .setVar("inputanswer") .callback( getTimer("time limit").stop() ) , getTimer("time limit") .wait() , getKey("audioanswer").disable()
Let me know if you have questions
Jeremy
Jeremy
KeymasterHi,
You can upload a file named global_z.css in your Aesthetics (css_includes) folder with the following code:
.PennController-MediaRecorder button { font-size: 1.5em; }
Unfortunately the ‘recording’ label does not have its own class name, but this should be specific enough to target it (add this to global_z.css too):
body > div:last-child { font-size: 0.75em; }
Jeremy
Jeremy
KeymasterHi,
I’m not entirely sure what “slide 13/15/17” mean in that context, because I don’t know how many trials your different Template commands generate. I don’t know what the “etc.” stands for either, since you only have three trials labeled questions, so I would expect that you only need three insertions.
Here I will be assuming that you have a total of 26 trials labeled experiment and that you want to randomly insert one of your three trials labeled questions after 12 experiment trials, another one after one other experiment trial and the last one after yet another experiment trial, and finally run the 12 remaining experiment trials. I will be using the pick function as suggested in my message above:
questions = randomize("questions") experiment = randomize("experiment") Sequence( "welcome", "SampleSlides", pick(experiment,12), pick(questions,1), // 13 pick(experiment,1), pick(questions,1), // 15 pick(experiment,1), pick(questions,1), // 17 pick(experiment,12), "final" )
By the way, you have two Sequence commands in your code: only one (the last one, I think) will be effective when running your experiment, so you better delete the second one (Sequence( randomize("questions") ))
Jeremy
Jeremy
KeymasterDid you remove the copy of your HTML file that you had previously uploaded to Scripts? Also make sure that the name of the file you uploaded to Resources is exactly test.html and not, for example, test.html.js or Test.html or test.htm.
There are a few problems with your trial: the command newHtml takes up to 2 arguments maximum, where the first is the name you want to give that element, and the second is the filename of the HTML document you want to include. In the code you posted, you are passing a third parameter, getHtml("test"), which is just a reference to that same element. Also, remember from the tutorial that you need to do things with elements, in particular you need to explicitly tell your script to print them where you want that to happen. Finally, you also want to hold script execution until your participant interacts with the page somehow, for example until they click on a button.
Here’s a possible implementation:
newTrial( newHtml("test", "test.html") .print() , newButton("Continue") .print() .wait() )
By the way, I see that your HTML document attempts to include an iframe that points to an external website. This is not recommended, as it can introduce security breaches, or simply not work at all (depending on how browsers handle cross-domain iframes).
Jeremy
Jeremy
KeymasterHello Dawson,
Thank you for pointing out the outdated reference on the documentation page, I will update it. On the PCIbex Farm, the folder chunk_includes appears as Resources, that’s where you should upload your HTML file
Best,
JeremyJeremy
KeymasterIf you only need to print one question per slide, and want to randomly order your slides, you could do something like this:
Sequence( randomize("mcq") ) newTrial( "mcq" , newText("Are you male or female?").print() , newScale("gender", "male", "female") .labelsPosition("right") .print() .wait() ) newTrial( "mcq" , newText("What is your favorite color?").print() , newScale("color", "blue", "purple") .labelsPosition("right") .print() .wait() ) newTrial( "mcq" , newText("Are you 20 or 25?").print() , newScale("age", "20", "25") .labelsPosition("right") .print() .wait() )
Now if your trial sequence is more complex and you want to randomly insert one of those trials inside at different points in your sequence, you’ll need something more sophisticated. For example, you could use the function pick from this thread, like this:
mcqs = randomize("mcq") Sequence( "intro" , pick(mcqs,1) , randomize("block1") , pick(mcqs,1) , randomize("block2") , pick(mcqs,1) , "end" )
Let me know if you have questions
Jeremy
Jeremy
KeymasterHi,
I think I would need more detail to help you with your issue. Do you need to display several lines of text (questions) vertically on the page, randomly ordered, and invite your participants to click on one those lines? If so, you could do something like this:
newTrial( newText("q1", "What's up?").print() , newText("q2", "How are you doing?").print() , newText("q3", "All good?").print() , newText("q4", "How's it going?").print() , newSelector("choice") .add( getText("q1") , getText("q2") , getText("q3") , getText("q4") ) .shuffle() .wait() )
Jeremy
Jeremy
KeymasterHey Peiyao,
There are a few things going on here, but the simplest solution is just to revert back to 1.8. Just type 1.8 in the branch field when syncing, following the instructions here
One problem with 1.9 is that I seem to have broken how selector.shuffle keeps track of the elements indices. Otherwise, I would have suggested this code (which should behave as expected in the next release of PennController):
newTrial( newButton("Start") .print("center at 50vw", "middle at 50vh") .wait() .remove() , newCanvas("container",600,600).print("center at 50vw","middle at 50vh") , newCanvas('red', 200,200).color('red').print(0, 0, getCanvas("container")), newCanvas('green', 200,200).color('green').print("right at 100%",0,getCanvas("container")), newCanvas('pink', 200,200).color('pink').print(0,"bottom at 100%",getCanvas("container")), newCanvas('blue', 200,200).color('blue').print("right at 100%","bottom at 100%",getCanvas("container")) , newFunction( ()=>{ $("body").css({ width: '100vw', height: '100vh', cursor: 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="), auto' }); setTimeout(()=>$("body").bind('mousemove', ()=>{ $('body').css('cursor','unset'); $('.PennController-container .PennController-Canvas').bind('mouseenter', e=>getSelector("response") .select(getCanvas(e.target.className.replace(/.*(blue|red|pink|green).*/,"$1")))._runPromises() ); }), 100); }).call() , newSelector("response") .add( getCanvas("red"),getCanvas("green"),getCanvas("pink"),getCanvas("blue") ) .shuffle() .log() .wait() )
Right now the only problem with this code is that you lose track of where each element is effectively displayed to your participant (you’ll see an order reported in the results file, but it’s just incorrect). If you don’t care about that piece of information, then definitely stay with 1.9 and use this code
Jeremy
Jeremy
KeymasterHello Lesley,
One solution is to use the css command:
.success( newText("Good job!").css("font-size","2em").print() ) .failure( newText("Nope!").css("font-size","2em").print() )
Jeremy
Jeremy
KeymasterHi Grace,
The Group column is automatically detected by PCIbex. The reasons I can see why it would fail to do so are either because the table has another column overriding it (eg. a column named List) or because your column’s name is not exactly Group. Make sure you don’t have an extra-character somewhere like a dot or a space character in the name of your column
Jeremy
Jeremy
KeymasterHi,
You can tell a MediaRecorder element to start recording any time once the trial has started. Just make sure you have stopped your MediaRecorder element by the end of the trial, otherwise you might run into conflicts and/or massive audio files which could easily fail to upload.
Let’s illustrate a situation where you start recording before starting audio playback. Say your MediaRecording starts recording at timestamp 1111, and your Audio element starts playback at timestamp 1234. By analyzing the recorded sample, you find a 450ms silence before your participant starts speaking. This means that your participant gave their audio response 1111+450-1234 = 327ms after the onset of your Audio stimulus. As you can see, the situation is very similar to the previous one, there’s no problem with it.
Best,
Jeremy -
AuthorPosts