Jeremy

Forum Replies Created

Viewing 15 posts - 976 through 990 (of 1,522 total)
  • Author
    Posts
  • in reply to: Randomly get item from certain conditions #6550
    Jeremy
    Keymaster

    Hi,

    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

    in reply to: resize Media Recorder Elements #6543
    Jeremy
    Keymaster

    Hi,

    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

    in reply to: Safari saving results problems #6542
    Jeremy
    Keymaster

    Hi 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

    in reply to: failed to upload recordings #6539
    Jeremy
    Keymaster

    Hi,

    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

    in reply to: Recording keypress with a timer #6536
    Jeremy
    Keymaster

    Hi,

    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

    in reply to: resize Media Recorder Elements #6534
    Jeremy
    Keymaster

    Hi,

    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

    in reply to: repeating commmands #6532
    Jeremy
    Keymaster

    Hi,

    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

    in reply to: Embedding HTML #6531
    Jeremy
    Keymaster

    Did 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

    in reply to: Embedding HTML #6525
    Jeremy
    Keymaster

    Hello 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,
    Jeremy

    in reply to: repeating commmands #6523
    Jeremy
    Keymaster

    If 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

    in reply to: repeating commmands #6521
    Jeremy
    Keymaster

    Hi,

    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

    in reply to: hide cursor and select by pointing #6517
    Jeremy
    Keymaster

    Hey 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

    in reply to: Enlarging Feedback Text #6513
    Jeremy
    Keymaster

    Hello 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

    in reply to: Pseudoranomization #6511
    Jeremy
    Keymaster

    Hi 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

    in reply to: timing accuracy #6509
    Jeremy
    Keymaster

    Hi,

    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

Viewing 15 posts - 976 through 990 (of 1,522 total)