Forum Replies Created
-
AuthorPosts
-
Jeremy
KeymasterWhen I edit a copy of your project and remove the
www.
prefix from the URL the zip file loads fine. Would you mind removing it from your own project so I can see whether there really is a problem specific to your project/account?Jeremy
Jeremy
KeymasterActually it’s not because of an absence of a
www
prefix that my code is not working for you: one should not use awww
prefix in that URL (the reason it results in a timeout is probably due to there being no DNS record for it—and your university probably has its reasons for that)Where do you host your experiment? If it’s on the PCIbex Farm, would you mind sharing its demonstration link with me?
NB: here’s the link to try out my code https://farm.pcibex.net/r/xcQKxQ/
Jeremy
Jeremy
KeymasterHi Sam,
The ERR_CONNECTION_TIMED_OUT tells it as it is: trying to access https://www.hjpatt-136.umd.edu/Web_Experiments/Slevc/spr/sprAudio.zip results in a timeout (try clicking the link yourself)
This works for me (on the PCIbex Farm):
PreloadZip("https://hjpatt-136.umd.edu/Web_Experiments/Slevc/spr/sprAudio.zip") newTrial( newButton("Hello World").print().wait() ) newTrial( newAudio("Am53-ACEC.mp3").print().wait() )
Jeremy
Jeremy
KeymasterHi,
I am not sure where you saw such a use of
getVar(...).value
, but it’s a method you use to inject native JavaScript in your code. In your case, you’re accessing the value of the Var element before the trial has even started. This guide should bring insights into this issue.The proper PennController way of accomplishing what you’re trying to do is:
newTrial( // Initialize variable newVar("audFile","None").set( "variable is changed" ), newText( "This now says 'variable is changed':" ) .after( newText().text(getVar("audFile")) ) .print() , newTimer(3000).start().wait(), clear() , // Print letter to be typed newText("letter", "Now please press A") .css("font-size", "24pt") .log() .print() , // Get keypress newKey("keypress", "as") .log() .wait() .test.pressed( "A" ) .success( getVar("audFile").set("correct"), newText( "Correct!" ).print(), newTimer(1000).start().wait() ) .failure( getVar("audFile").set("wrong"), newText( "Wrong!" ).print(), newTimer(1000).start().wait() ) , // Print the final value of the variable newText( "This should say either 'Correct!' or 'Wrong!' and it does:") .after( newText().text(getVar("audFile")) ) .print() , newTimer(1000).start().wait() )
If your Var element is trial-wise, which I take to mean local (ie. non-global) then you don’t need to use the
global
commandJeremy
Jeremy
Keymaster1) You can use
.setOption("preloadDelay", 5000)
on the closing parenthesis ofnewTrial
2) These two tricks (
._element.resource.status
and 1 above) are actually pretty advanced, albeit concise. This is because it didn’t occur to me to make those things customizable. If you’re interested, you can take a look at PennController’s source code and try to hack it out 😉Jeremy
Jeremy
KeymasterHi Doug,
PennController should already report when a resource fails to preload in the results file: look for lines with “_PreloadFailed_” in them, they also report the name of the resource
You could run a Function element at the beginning of your trial and end it prematurely if the resource’s status is not “ready”:
newFunction( ()=>getAudio("file.wav")._element.resource.status ) .test.is("ready") .failure( end() )
replace
"myAudio"
with the name of your Audio elementLet me know if you have questions
Jeremy
Jeremy
KeymasterDear Ana-Maria,
First, make sure that your PennController file is not version 1.9: there is a bug in that version where the post-shuffle order reported in the results file is inaccurate
Once you get the order properly reported in the results file, it’s easy to retrieve which key was pressed: say the picture that was chosen was
picture2
andpicture2
is third in the reported order, then the key that was pressed wasX
If you want to additionally report the filename of each picture in the results file, you can use
newTrial().log
Here is a basic code that illustrates those ideas:
Template( row => newTrial( newSelector("pictures") , defaultImage .size("10vw","10vw") .selector("pictures") , newCanvas("container", "80vw","80vh") .color("lightgray") .add("center at 25%","middle at 25%",newImage("picture1",row.picture1)) .add("center at 75%","middle at 25%",newImage("picture2",row.picture2)) .add("center at 25%","middle at 75%",newImage("picture3",row.picture3)) .add("center at 75%","middle at 75%",newImage("picture4",row.picture4)) .print("center at 50vw","middle at 50vh") , getSelector("pictures") .log() .shuffle() .keys("E","I","X","M") .wait() ) .log("picture1", row.picture1) .log("picture2", row.picture2) .log("picture3", row.picture3) .log("picture4", row.picture4) )
You can try it out here: https://farm.pcibex.net/r/RONttQ/
Here’s a result line that was generated for the first trial:
1618581521,c12c0535fba1b8e2ff8e0a39d068826c,PennController,0,0,Item-1,NULL,Selector,pictures,Selection,picture2,1618581519920,bear.png,cat.png,chicken.png,deer.png,picture4;picture1;picture2;picture3
As you can see, I chose
picture2
and if I look up the order, I see thatpicture2
ended up occupying the third position after the shuffle: this means that I chose the bottom-left picture by pressingX
. Additionally, I see thatpicture2
wascat.png
(note that the order of the filenames in the result line are not shuffled)You can automatize those associations in R, for example
Let me know if you have questions
Jeremy
Jeremy
KeymasterHi,
You can have all your HTML files in your project, but only reference the filenames of the ones you want to show for each group in a CSV file.
By default, PennController relies on Ibex’s internal counter which gets incremented whenever a participant finishes the experiment. The
Template
command will use that counter to select the rows corresponding to a specific group, in a cycling way. If you have one table with 4 groups (say A-D) and another one with 3 groups (say A-C), then the groups will match for the counter’s values0
,1
and2
, but when the counter reaches the value3
then it will move on to group D for the first table and go back to group A for the second table, and so on.Here is a project that illustrates these two points: https://farm.pcibex.net/r/ZzqAbG/
Jeremy
Jeremy
KeymasterHi Anna,
Thanks for pointing this out, I’ll make sure to edit the text next time I update the farm
Jeremy
Jeremy
KeymasterHi Zara,
Did you go back to the previous version of PennController.js on the project that you shared in your previous message? Because when I open it I still see the old version.
I am still unable to reproduce the issue, but at least one thing that I hoped would have changed with the new PennControlelr.js file is that, even when you see a preloading message, the error message “Uncaught (in promise) TypeError: this.resource.object is null” should have disappeared. Do you still see this message even after replacing the file PennController.js from your project’s Modules folder?
I don’t think this problem has something to do with the software you use for audio compression. I think it might have something to do with the browser’s caching of the zip/audio files. I don’t think it’s related to the server on which the zip file is hosted in any direct way, but it could be that using a different server forces your browser to not use its cache and reload the files instead, which (if my guess is right) would make the problem disappear at least the first time you take the experiment after switching to a different server
Jeremy
April 12, 2021 at 11:50 am in reply to: self-paced reading with image element in the middle of the sentence #6857Jeremy
KeymasterHi Sarah,
Yes, simply stack these two commands on your Image element:
.css('transform','translateY(-50%)') .cssContainer('height','1em')
The
css
command will move the element up by 50% of its size, effectively aligning its vertical midpoint with what used to be its top border. ThecssContainer
command will make it occupy only 1em (the height of a standard character) without actually diminishing the image’s height.If you look at the code of
myDash
, you’ll see that it creates a Text element named “container” and, inaddToDash
, you’ll see that every element is printed into it. So just dogetText("container").remove()
to take it off the screen (or.hidden()
if you still want a blank space where it used to be)Jeremy
Jeremy
KeymasterHi Zara,
I am sorry you are experiencing issues with PennController’s resource-preloading system. We received a note about this issue once before, and were unfortunately unable to identify the cause of the problem. I was able to replicate the issue with your project once after reloading it a few times, and was never able to reproduce it after that despite reloading it tens of times. The elusiveness of this bug just makes it harder to troubleshoot
I am not sure the issue is related to manually-typed vs table-fed filenames, it could be that the problem never occurred for manually-typed filenames by chance. It certainly has something to do with zip files though. I have an idea of what is happening, although I am not quite sure how/why it’s happening. In the meantime, would you mind downloading this PennController.js file and replacing the one from your project’s Modules folder with this one? I tried it with a copy of your project and it seemed to work OK, but if you give it a try, please do a few test runs and let me know if you notice any issues
Best,
JeremyJeremy
KeymasterOh, I see, then you could have disabled the Key element after the timeout has elapsed, but it’s great if the workaround did the job
Jeremy
Jeremy
KeymasterHi Elise,
I’m confused, why can’t you use
.log("all")
?In any case, yes, the bug has been fixed in newer releases of PennController. Here is a minimal adaptation of the Stroop Task template which gives 2s to press the
F
orJ
key and will log whether/which key was pressed: https://farm.pcibex.net/r/CNZftL/Jeremy
Jeremy
KeymasterHi Iris,
I am not aware of anyone implementing the Corsi task in PCIbex, but it sounds like a fun challenge! It would, however, definitely require injecting some JavaScript, I don’t think there would be an efficient way of coding such a task using PennController commands only (it would result in a very lengthy and redundant code). Maybe the smartest things to do would be to create a new PennController element type, but that would mean making decision as to how you use the element, how/where/whether one defines the demonstration sequence, whether you can shuffle the blocks, should it stop at the first wrong click/tap or should it be lenient (or should that be a parameter? if so, how?), etc.
In the meantime, I came up with a toy example here, where I heavily rely on the PennController Function and Var elements to execute JavaScript functions, accessing the internal structure of the elements: https://farm.pcibex.net/r/kiegoB/
It’s not perfect, but at least it’s very customizable once you make sense of all the JavaScript code
Let me know if you have questions
Jeremy
-
AuthorPosts