Jeremy

Forum Replies Created

Viewing 15 posts - 166 through 180 (of 1,522 total)
  • Author
    Posts
  • in reply to: Experiment with video stimuli goes blank after 4 trials #10397
    Jeremy
    Keymaster

    Hi again,

    I was able to test your experiment on a better connection. It does look like the browser starts fetching (partial) data from four videos from your server, but after that all requests stall. Because this doesn’t happen across all experiments on the farm, the issue must lie at least partly in how your server is configured to respond to the requests for video files that the farm sends it

    Unfortunately, I cannot tell what server configuration controls that behavior, but I strongly encourage you to explore the zip file method, which will fetch all the video files from a single request to your server, and see if the problem persists

    Jeremy

    in reply to: Feedback based on slider scale selection #10396
    Jeremy
    Keymaster

    Hello,

    This is because, in the absence of a selection, the choices array is empty, so the code in the Function element will crash when trying to reference the value of “the last choice” (presupposition failure: there is no choice to start with). What you can do to address the crash is return a dummy array in the absence of choices

    Regarding the specific feedback messages, you can handle them in two separate tests in wait, just like you tried to do: one that tests whether the Scale was interacted with, and one that checks the value on the Scale. The former will fail in the absence of a selection, so the latter just won’t matter (but won’t crash because of the dummy array; and we’ll make it succeed so as to not print its own feedback message in the absence of a choice)

    Now, because you want to provide different feedback depending on which test fails, neither should be the main test in the wait command and to which ands are appended, otherwise you’ll get inappropriate feedback. Instead, create a dummy main test which is always true, but conjoin to it (using and) a test on the Scale element (place the “select a value” feedback message in that test’s failure command) as well as a test on the Function element (place the “choose the right side instead” feedback message there). This way, the conjunction of all three tests will fail in either scenario (no choice, or invalid choice). You can place what’s common to both scenarios in the main test’s failure command to avoid redundancy:

    newButton("Next")
        .center()
        .print()
        .wait(
            newVar("dummy",1).test.is(1).and( // conjoin the test on the Scale
                getScale("Conclusion").test.selected()
                    .failure( getText("False").text("Select a value on the scale first") )
            ).and( // conjoin the test on the Function
                // We use the dummy array [-1,100] so that the second entry (index 1, ie value 100) is greater than 49
                newFunction( ()=>{const c=getScale("Conclusion")._element.choices; return (c[c.length-1]||[-1,100])[1]>=49;}).test.is(true)
                    .failure( getText("False").text("No, one would rather use the right-hand side of the scale.") )
            )
            .failure( // This runs when the conjunction of all three tests fails
                // All this is common to the no-choice and the low-value scenarios
                getText("False").hidden()
                ,
                newTimer("wait3", 100).start().wait()
                ,
                getText("False").visible()
                ,
                newTimer("wait4", 2000).start().wait()
                ,
                getText("False").hidden()
            )
        )
    ,
    // The code below is executed when the script moves past the wait command, ie when the test succeeds
    getText("Correct")
        .hidden()
    ,
    newTimer("wait1", 100)
        .start()
        .wait()
    ,
    getText("Correct").visible()
    ,
    newTimer("wait2", 4000)
        .start()
        .wait()

    Jeremy

    in reply to: Experiment with video stimuli goes blank after 4 trials #10394
    Jeremy
    Keymaster

    Hi,

    Unfortunately I cannot efficiently troubleshoot your study right now, because my connection is extremely slow and downloading even a single video takes forever (so I keep hitting the “resources preloading” page before every single trial)

    Did you check that every single URL in your CSV file points to a valid file? Does the problem persist if you consolidate your video files in a single zip archive?

    Jeremy

    in reply to: inserting getEyetracker start and stop into the code #10387
    Jeremy
    Keymaster

    No, add the print command on the Image elements at the point where you want the corresponding Image element to be printed, ie. on where you used to have your newImage commands (they would be printed there too because you used to have print on defaultImage)

    The error messages you see are telling me that you’ve added the four newImage commands below newCanvas in addition to the newImage commands you already have below in your script, thus resulting in two copies with the same name of each Image element. You should not create and, importantly, not print the Image elements at the beginning of the trial: you want to print them at different time points during the trial, so the print commands should go on the newImage commands that already are further down in your script

    Jeremy

    in reply to: inserting getEyetracker start and stop into the code #10385
    Jeremy
    Keymaster

    There seems to be a bug with printing to a Canvas element in a default command. So take out the print from the defaultImage command (defaultImage.size(1280,720)) and add the print command to each Image element instead:

    newImage("image0", row.Static_image1).print(0,0,getCanvas("imageContainer")),
    // ...
    newImage("image1", row.action_image).print(0,0,getCanvas("imageContainer")),
    // and so on

    Jeremy

    in reply to: inserting getEyetracker start and stop into the code #10380
    Jeremy
    Keymaster

    I’m not sure I understand your question, but your current setup, with one image on the page at a time, will work as long as you use the Canvas element method I suggest

    The log file you see in your server is indeed mine, which is the one I link to in my previous message, to demonstrate that your setup is functional with that method

    Jeremy

    in reply to: inserting getEyetracker start and stop into the code #10377
    Jeremy
    Keymaster

    Hi,

    Your experiment crashes when it reaches the first trial labeled “eyetracking” because you’re adding Image elements to the eye tracker that are not on the page. In fact, all the elements you add will be mutually exclusively be printed on the page, which is not the kind of setup that the EyeTracker was designed to handle: the elements are supposed to be placed on the page together, at different locations, and the eye tracker tracks which one you are looking at a given time point

    Now, you are using a hack to track the (X,Y) coordinates on top, which is what you are interested in, so you should just add one element that will persist on the page, in which you will successively print your four images: that’s a Canvas element

    At the beginning of your trial, create that element, and make the Image elements automatically print on it:

    newCanvas("imageContainer", 1280, 720)
    ,
    defaultImage.size(1280,720).print(0,0,getCanvas("imageContainer"))

    Then before starting the tracker, just print the Canvas element and then add it to the tracker instead of the Image elements:

    getEyeTracker("tracker")
        .calibrate(5)
        .log()
    ,
    getCanvas("imageContainer").print("center at 50vw", "middle at 50vh")
    ,
    getEyeTracker("tracker")
        .add( getCanvas("imageContainer") )
        .start()

    Once you do that, you do get eye tracking data at your server, e.g. here from my test run

    Jeremy

    in reply to: Feedback based on slider scale selection #10373
    Jeremy
    Keymaster

    Hello,

    You’ll need to use a Function element:

    newFunction( ()=>{const c=getScale("Conclusion")._element.choices; return c[c.length-1][1]>=49;}).test.is(true).success( newText("Yay!").print() )

    Jeremy

    Jeremy
    Keymaster

    Hi Chloris,

    Should pause_1 always appear after block_1 regardless of where block_1 ends up, or should it always appear after the first block to run, regardless of whether that’s block_1, block_2 or block_3? Assuming you mean the latter, you can achieve it like this:

    var blocks = [randomize("block_1"),randomize("block_2"),randomize("block_3")];
    fisherYates(blocks);
    
    Sequence("consent", blocks[0], "pause_1", block[1], "pause_2", blocks[2], "send", "completion")

    Jeremy

    in reply to: Unable to randomize fillers and experimental items #10370
    Jeremy
    Keymaster

    Hi,

    Did you mean to write row.Question!==undefined && row.QUESTION instead? Because the error you should get should be about table not being defined

    You can use hasOwnProperty to check that an object has an attribute: ...(row.hasOwnProperty("Question") && table.QUESTION ? [

    and also further down: .log("list", (row.hasOwnProperty("LIST")?"filler":row.LIST))

    Jeremy

    in reply to: Troubleshooting #10369
    Jeremy
    Keymaster

    Hi Yev,

    Do you still experience the issue? When I open your link now, I only see the “loading” message for ~1s and then it moves on to the preloading screen, and after some time moves on to the consent form and the rest of the experiment, which runs smoothly

    Jeremy

    in reply to: inserting getEyetracker start and stop into the code #10368
    Jeremy
    Keymaster

    Hi,

    Do you have a link to your study, so I can troubleshoot it? Also, did you make sure you properly set your PHP script and reference the right URL in EyeTrackerURL?

    Jeremy

    in reply to: Using .before/.after on Canvas #9988
    Jeremy
    Keymaster

    If you are willing to add as many pieces as words, adding whole new Text elements would seem too much. Could you just add a space character in the code, like this?

    newText("subject", row.subject+" "),
    newText("verb", row.verb+" "),
    newText("word", row.word+" "),
    newText("ending", row.ending)

    Jeremy

    in reply to: Using .before/.after on Canvas #9984
    Jeremy
    Keymaster

    Hello,

    You can use .before and .after on any element, including Canvas elements themselves or Text elements that you print on a Canvas element. For example, you can do that:

    newText("subject", "I "),
    newText("verb", "print "),
    newText("word", "words "),
    newText("ending", "on a line")
    ,
    getText("subject").after(getText("verb").after(getText("word").after(getText("ending")))).print()

    Or alternative you could print the next Text elements inside the first one, making sure they all appear as a horizontal sequence (css command):

    newText("subject", "I ").css("display", "flex").print(),
    newText("verb", "print ").print(getText("subject")),
    newText("word", "words ").print(getText("subject")),
    newText("ending", "on a line").print(getText("subject"))

    Jeremy

    in reply to: click button and file attachment #9981
    Jeremy
    Keymaster

    Hello,

    In a PennController trial, you could do that:

    newTrial(
      newText("<a href='https://getsamplefiles.com/download/zip/sample-1.zip' target='_blank'>Click here to download a zip file</a>").print()
      ,
      newButton("Next").print().wait()
    )

    In an Ibex Message controller, you could do that:

    var items = [
    
      ["intro", "Message", {html:
        "<div>\
          <p><h1>hello</h1></p>\
          <p><strong>world</strong></p>\
          <p><a href='https://getsamplefiles.com/download/zip/sample-1.zip' target='_blank'>Click here to download a zip file</a></p>\
        </div>"
      }]
      
    ];
    
Viewing 15 posts - 166 through 180 (of 1,522 total)