Forum Replies Created
-
AuthorPosts
-
Jeremy
KeymasterHi Dod,
PennController Var elements are not javascript variables (visit the link in my message above to read about differences between PennController and plain javascript)
The keyword
variable
has no meaning in plain javascript, and PennController defines no global object with that name. You will sometimes seevariable
in the scope ofTemplate
in some people’s code, but in your case it looks like you are usingrow
instead (as determined byrow =>
, which I assume comes withTemplate
in your code)You could try that instead:
const speakID = [...Array(4)].reduce(a=>a+alphanum.charAt(Math.floor(Math.random()*alphanum.length)),'') newTrial("speakID", newText("speakID", speakID).print() , newButton().print().wait() // to be deleted, just to double check that the code matches the audiofile ) .log("speakID", speakID) // ... newMediaRecorder(row.itemID+"_"+row.modality+"_"+speakID, "audio")
Jeremy
Jeremy
KeymasterHi Ana,
Are you trying to align
...
with the start of the SPR sentence? If so, since you use a mono-spaced font to display the SPR sentence, you can simply pass a string of the same length to the three-dot Text element and it will be the exact same size as the SPR sentence, so if you print it at the same coordinates, they will be perfectly aligned. The trick is to make that string start with...
and render all remaining (dummy) characters invisible, eg:// dots 1_1 newText("start1_1", "...<span style='visibility: hidden;'>"+ [...new Array(variable.context.length-3)].map(v=>'_').join('')+"</span>") .css({"font-size":"23px","font-family":"courier"}) .print("center at 50%", "middle at 50%") , // Keep the dots in place for about a second newTimer("start1_1_timer", 1000).start().wait() , // Remove the dots getText("start1_1").remove() , // context sentence newText ("read_ctxt","Lies bitte den ersten Satz und drücke die Leertaste um fortzufahren") .css({"font-size":"15px","font-family":"times new roman"}) .center() .color("red") .print("center at 50%", "middle at 46%") , // context sentence in SPR ...cumulative_ctxt(variable.context, "remove") , getText("read_ctxt").remove()
Jeremy
Jeremy
KeymasterHi Simone,
Your code seems perfectly fine to me (assuming you have 9 blocks of 108 test trials—if you have 9 blocks of 12 trials, you need to write
sepWithN("break", randomize("test"), 12)
). You could write your “break” trial like this, for example:newTrial("break", newVar("block_n", 0).global().set(v=>v+1) , newVar("text").set(getVar("block_n")).set(v=>"You've just finished block "+v+" of 9") , newText("prompt", "").text(getVar("text")).print() , newButton("Next").print().wait() )
Jeremy
Jeremy
KeymasterHi Jun,
You’ll have to edit DashedSentence.js in the Modules folder and replace the conditional on
"self-paced reading"
toward the top with a simpleif (this.mode == "self-paced reading") this.sprResults = [];
. Then replace thesafeBind
piece of code further down with this:this.safeBind($(document), 'keydown', function(e) { var time = new Date().getTime(); var code = e.keyCode; if (code == 37 || code == 39) { var word = t.currentWord; if (word > 0 && word <= t.stoppingPoint) t.sprResults.push([time,t.previousTime,word]); t.previousTime = time; if (code == 37){ if (code != t.lastKey) t.currentWord--; if (t.currentWord < t.stoppingPoint) t.blankWord(t.currentWord); if (t.currentWord - 1 >= 0) t.showWord(t.currentWord - 1); t.currentWord--; if (t.currentWord<0) t.currentWord = 0; } else if (code == 39){ if (t.currentWord>0 && code != t.lastKey) t.currentWord++; if (t.currentWord - 1 >= 0) t.blankWord(t.currentWord - 1); if (t.currentWord < t.stoppingPoint) t.showWord(t.currentWord); t.currentWord++; if (t.currentWord > t.stoppingPoint) { t.processSprResults(); t.finishedCallback(t.resultsLines); } } t.lastKey = code; return false; // *** } else { return true; } });
And the
processSprResults
piece of code toward the end of the script with this:processSprResults: function () { for (var i = 0; i < this.sprResults.length; ++i) { var n = this.sprResults[i][2]; this.resultsLines.push([ ["Word number", n], ["Word", csv_url_encode(this.words[n-1]||"")], ["Reading time", this.sprResults[i][0] - this.sprResults[i][1]], ["Newline?", (! this.display == "in place") && boolToInt(((n+1) < this.wordOSpans.length) && (this.wordOSpans[n].offset().top != this.wordOSpans[n+1].offset().top))], ["Sentence (or sentence MD5)", this.sentenceDesc] ]); } }
Jeremy
Jeremy
KeymasterHi Judith,
Apologies for the late reply. You can pass a function to the
callback
command of the MouseTracker element that takes thex,y
coordinates as arguments—you can then use the Y coordinate to either check that the cursor moved upwards by N pixels, or that it is above a certain line. Here is a simple trial illustrating how to update a Text element once the mouse has moved at least 50px north after clicking:newTrial( newButton("Start").print().wait().remove() , newVar("start_y", undefined) , newText("prompt", "Hello _____").print() , newMouseTracker("mouse") .callback( async (x,y) => { if (getVar("start_y").value === "stop") return; else if (getVar("start_y").value === undefined) await getVar("start_y").set(y)._runPromises(); else if (getVar("start_y").value - y > 50) { await getVar("start_y").set("stop")._runPromises(); await getText("prompt").text("Hello World")._runPromises(); } }) .start() , newButton("Finish").print().wait() , getMouseTracker("mouse").stop() )
Jeremy
Jeremy
KeymasterHi,
Apologies for the late reply. Do you mind sharing the link to your experiment and API gateway URL with me, here or at support@pcibex.net so I can proceed to some tests for troubleshooting? Thank you
EDIT: after an email exchange, it was determined that this was a case of Cross-Origin Resource Sharing (CORS) misconfiguration on the API gateway’s side that comes with the default configuration. It was fixed by opening the API gateway in the AWS console, visiting the CORS tab, and then clicking the “Clear” button: after that, the API allows the Lambda function to return the headers, including the CORS-relevant ones
Jeremy
-
This reply was modified 3 years, 2 months ago by
Jeremy. Reason: problem solved
Jeremy
KeymasterHi Loid,
My apologies for the late reply. You can make a font bigger by setting the CSS rule
font-size
that targets the relevant HTML nodesAssuming you are using the native-IBEX AcceptabilityJudgment controller, which is composed of the FlashSentence controller to render the
s
parameter and the Question controller to renderq
andas
, you can edit the file FlashSentence.css in your project’s Aesthetics folder to modify the font size of thes
parameter by adding:p.FlashSentence { font-size: 3em; }
To change the font size of the
q
andas
parameters, you can edit the file Question.css and add:p.question-text { font-size: 4em; } li.normal-answer { font-size: 2em; }
Note that those changes will affect any other item using the FlashSentence and/or the Question controller
Jeremy
Jeremy
KeymasterHi Yasmin,
My apologies for the late reply. What is the error you encounter when trying to use
read.pcibex
? That function should output a table whose columns are named after the comments lines1.655924e+12
is a visual representation of a number composed of 13 digits used by whatever software you are using to view it, but the internal representation of the number is effectively between1655924000000
and1655924999999
(depending on how the software decided to truncate/round the number in its exponent representation)Jeremy
Jeremy
KeymasterHello Daniela,
My apologies for the late reply. As far as I can tell, you don’t need to use any Var element in your code. You could do something like this instead:
// Top of your script const YES_KEY = 'F', NO_KEY = 'J'; // inside your trial newKey("rating", "FJ") .callback( getTimer("time_out1").stop() ) .log("all") , getTimer("time_out1").wait() // I added this here as it seems to make sense given the callback above , getKey("rating") .test.pressed( variable.match=='yes' ? YES_KEY : NO_KEY ) .success( newText ("match_text", variable.prac_correct) // print the CORRECT feedback response for this trial .css({"font-size":"20px","font-family":"times new roman"}) .print("20vw","40vh") ) .failure( newText ("mismatch_text", variable.prac_incorrect) // print INCORRECT feedback .css({"font-size":"20px","font-family":"times new roman"}) .color("red") .print("20vw","40vh") ) , newText("spacebar", "Press the spacebar to continue.") .css({"font-size":"15px","font-family":"times new roman"}) .italic() .center() .color("red") .print("20vw","50vh") , newKey("feedback", " ").wait()
Remember that you can always share your project’s demonstration link as a way to share your code and make troubleshooting easier
Jeremy
Jeremy
KeymasterYou don’t need to run server_conf.py: server.py has this line
execfile(SERVER_CONF_PY_FILE, CFG)
which takes care of running server_conf.py itselfAll you need to do, when things are configured properly, is visit the URL that points to server.py (eg.
https://my.domain.xyz/myxp/server.py?withsquare=0
) or to experiment.html (eg.https://my.domain.xyz/myxp/experiment.html
) — experiment.html itself invokes server.py on several occasions, effectively executing itTo reiterate my point, when running the experiment as a CGI application, you don’t need to run anything yourself: your webserver (if configured properly) will take care of running the script itself upon request (ie by visiting the experiment’s URL). Also, you don’t need to update the
PORT
variable in server_conf.py, since you are not running your experiment in stand-alone (toy) mode, as per the comments above thePORT
line:# The port the server will run on if running in stand-alone mode.
The “site can’t be reached” error is most likely unrelated to IBEX, but rather to some other configuration on the webserver or domain end, for example. Are you able to visit other resources served by your webserver? I’m afraid I can’t really help with that
EDIT: it just occurred to me that Chrome does say “This site can’t be reached” if you try to visit
localhost:3000
without spinning upserver.py
in stand-alone (toy) mode. Do you mean to run your experiment in stand-alone (toy) mode on your machine? If so, you do need to runserver.py
, but make sure theSERVER_MODE
variable in server_conf.py is set to"toy"
(and make sure you visit the same port that you set in server_conf.py, which is3000
by default)Jeremy
-
This reply was modified 3 years, 2 months ago by
Jeremy.
June 21, 2022 at 8:09 am in reply to: Randomization with no more than three items of same category in a row #8241Jeremy
KeymasterHi,
You need to include the category information in the trials’ labels, otherwise the various sequence functions will have no way of knowing which trial is from which category, and therefore you’ll have no hope of constraining their distribution
I wrote a function called
randomizeNoMoreThan
that does what you want. Once you’ve added a .js file defining the function to your project’s Modules folder, you can proceed to the following modifications:- replace
newTrial("experimental_items"
withnewTrial("experimental_items_"+row.Kategorie
- replace
critical = randomize("experimental_items");
withcritical = randomizeNoMoreThan(startsWith("experimental_items"), 3);
- replace all three occurrences of
rshuffle(pick(critical, 61))
withpick(critical, 61)
Since
pick
selects consecutive trials from a set (ie. the next 61 trials it picks follow the previous 61 trials it picked in the set stored in thecritical
variable) and since the set stored incritical
has been randomized usingrandomizedNoMoreThan
, you should get the desired behaviorJeremy
Jeremy
KeymasterHi,
You will get this error if you set
SERVER_MODE
to"cgi"
in server_conf.py but not actually run the experiment as CGI (which would involve visiting the URL of your experiment on a web server under, say, Apache) but instead run it in stand-alone mode usingpython server.py
. If you run your experiment on your machine (and not on a web server) then you are running it in “toy” mode, so setSERVER_MODE
to"toy"
Jeremy
Jeremy
KeymasterHi,
You cannot do that, because there is one recording per MediaRecorder element, and elements are created before the sequence of trials is run, they cannot be created on the fly
My suggestion is you give unique labels to your recording trials and use
jump
to run them again if needed, eg:Template( row => newTrial( "recorder-"+row.item , newMediaRecorder("mediarecorder-"+row.item, "audio").print().wait().log() , // Jump to this trial (= recorder-ITEM#) newButton("Again").print().callback( jump("recorder-"+row.item) , getButton("Next").click() ) , newButton("Next").print().wait() ) .log("item#", row.item) )
Jeremy
June 13, 2022 at 11:50 am in reply to: Modifying size of and distance between multiple choice buttons on a scale #8232Jeremy
KeymasterHi Eva,
Target the
label
nodes (clickable) instead of the parent.option
nodes:.PennController-Scale .option label { margin: 0em 1em; font-size: 24px; }
Jeremy
June 8, 2022 at 3:12 pm in reply to: Modifying size of and distance between multiple choice buttons on a scale #8229Jeremy
KeymasterHi,
You can add CSS rules to Aesthetics/global_main.css to control the visual rendering of your Scale element. See this post
Jeremy
-
This reply was modified 3 years, 2 months ago by
-
AuthorPosts