Jeremy

Forum Replies Created

Viewing 15 posts - 1,246 through 1,260 (of 1,522 total)
  • Author
    Posts
  • in reply to: Questionnaire with questions on the same page #5607
    Jeremy
    Keymaster

    Hello Andrea,

    You would need to use the same method that I used in this message above:

    var test;
    newTrial("WBSI",
        ...wbsiQuestions.map( (v,i) => {
            if (i==0) test = getScale("Rating-"+i).test.selected();
            else test = test.and( getScale("Rating-"+i).test.selected() );
            return question(i,v);
        })
        ,
        newButton("next", "Next")
            .print()
            .wait( test )
    )
    in reply to: DashedSentence in a PennController trial #5605
    Jeremy
    Keymaster

    Hi Max,

    One solution to control text wrapping would be to manually insert linebreaks in the text, which was (one of) the original goal(s) when I posted this code.

    Assuming you will always name your element SampleItem across all your trials, another solution would be to add something like this to a file PennController.css in Aesthetics:

    .SampleItem {
      max-width: 40vw;
    }

    Or you could modify the code of the function to directly play with the Text element’s aesthetics there:

            [ newText(name,showWord(words)).css("max-width","40vw").print() ], 

    Jeremy

    in reply to: Questionnaire with questions on the same page #5601
    Jeremy
    Keymaster

    Hi Daniela,

    Not sure what’s happening with Chrome, but use this to sort names instead:

    names = names.sort(v=>1-2*(Math.random()>=0.5));

    I don’t think using multiple functions is the way to go: the idea is to handle the multiple lines within a single function, defining multiple of them sort of defeats the purpose. One option would be to revise the content of newTrial like this:

    newCanvas("screen", "100vw", "100vh")
        .add( 0 , 0 , newCanvas("names-1", "30%", "100%") )
        .add( "center at 50%" , 0 , newCanvas("names-2", "30%", "100%") )
        .add( "right at 100%" , 0 , newCanvas("names-3", "30%", "100%") )
        .print( "center at 50vw" , "middle at 50vh" )
    ,
    ...names.map( (r,i) => {
        test = test || newFunction(v=>true).test.is(true);
        test = test.and( getScale(r.name+'-scale-'+r.presented).test.selected() );
        return newText(r.name+": ")
            .after(
                newScale(r.name+'-scale-'+r.presented, 5)
                    .log()
                    .print()
            )
            .print( "2em" , parseInt(3+(i%3)*3)+"em" , getCanvas("names-"+parseInt(1+i/3)) );
    })
    ,
    newButton("Send")
        .print( "center at 50%" , "bottom at 95%" , getCanvas("screen") )
        .wait( test )

    Notice the i variable in the map function, that lets us keep track of the index of the name we are parsing. I use it to determine in which of 3 Canvas elements, laid out as columns on a full-page Canvas, I will add the name. I also use it to calculate an appropriate Y coordinate. In this example, I use i%3 because I want columns of 3 names, but of course this is something to adjust to your needs (eg. i%17).

    Hope this helps, let me know if you have questions

    Jeremy

    in reply to: Catch Trials #5598
    Jeremy
    Keymaster

    Hi Nickolas,

    You can replace this bit of code from the documentation:

    new DynamicElement(
        "Message",
        { html: "<p>Pause</p>", transfer: 1000 },
        true
    )

    with this:

    new DynamicElement(
        "PennController",
        newTrial(
            newButton("Hello world").print().wait()
        ),
        true
    )

    You can code the newTrial as you would any regular PennController trial

    Jeremy

    in reply to: Questionnaire with questions on the same page #5597
    Jeremy
    Keymaster

    Hi Philipp,

    1) You can always assign a label as the first argument of newTrial, so you could replace the line return newTrial( with return newTrial( "label" ,

    2) Yes, you can use newText("my text").print() inside the same newTrial command, either just before ...names.map( r => { or just before newButton("Send")

    3) Do you mean rearrange the table? In that case it wouldn’t make sense to use the Template command, as you would only have one row—use the method from this post instead, which is a cleaner way of creating a single trial

    Jeremy

    in reply to: Multiple trial repetition #5593
    Jeremy
    Keymaster

    By Ibex Farm, do you mean the PCIbex Farm at https://expt.pcibex.net or the original Ibex Farm at https://spellout.net/ibexfarm? PennController comes pre-installed on the former, but not on the latter

    In any case, it won’t hurt to install/update to the latest version of PennController. On either farm, just follow the instructions on this page and your project will import PennController 1.8

    Jeremy

    in reply to: Multiple trial repetition #5591
    Jeremy
    Keymaster

    Which version of PennController are you using? There was a bug until 1.7 where Canvas elements wouldn’t properly get removed from the page

    Jeremy

    in reply to: image/audio/video file type #5589
    Jeremy
    Keymaster

    Hi,

    It basically boils down to what browser your participant is using. You can get a list of video format support here: https://www.w3schools.com/html/html5_video.asp
    Audio: https://www.w3schools.com/html/html5_audio.asp

    Most image formats are supported, including the common formats: PNG, JPG, GIF, BMP. I don’t think you can straightforwardly use a vector image with the Image element though.

    Jeremy

    in reply to: Using if statements during a trial #5587
    Jeremy
    Keymaster

    Hi Max,

    As you say, the remove commands applies to the element it attaches to, so just attach it to the elements you want to remove:

    getButton("FTButton2")
        .print()
        .wait()
        .remove(),
    getText("FullText").remove(),
    getText("CompQ")
        .print(),
    getButton("CQButton")
        .print()
        .wait()
        .remove(),
    getText("CompQ").remove()

    Jeremy

    in reply to: basic installation #5585
    Jeremy
    Keymaster

    You should double-check that you really have no extra file, especially no files ending with upper-case extensions, like image.PNG in Resources

    Jeremy

    in reply to: basic installation #5582
    Jeremy
    Keymaster

    Hi,

    Are you running a local installation, or are you running your experiment on the (PC)Ibex Farm?

    You can try to open the web console to check for any error message: https://kb.mailster.co/how-can-i-open-the-browsers-console/

    Jeremy

    in reply to: Using if statements during a trial #5580
    Jeremy
    Keymaster

    Hi Max,

    I’m sorry, I went too fast when posting my answer, here is a revised version of the code:

    newTrial( "experiment" ,
        newText ("FullText", row.FullText),
        newButton("FTButton1","Proceed to next Trial"),
        newButton("FTButton2","Proceed to Comprehension Question"),
        newText("CompQ",row.CompQ),
        newButton("CQButton","Placeholder, just click to answer"),
        getText("FullText").print(),
        ( row.CompYN=="Y" ? [
            getButton("FTButton2")
                .print()
                .wait()
                .remove("FTButton2","FullText"),
            getText("CompQ")
                .print(),
            getButton("CQButton")
                .print()
                .wait()
                .remove("CompQ","CQButton")
        ] : [
            getButton("FTButton1")
                .print()
                .wait()
                .remove("FTButton1","FullText")       
        ] )
    ) //closes newTrial

    Besides the lack of double-quotes around Y, the problem was that each comma-separated block of commands represents an object, but the ( test ? success : failure ) structure allows only one object in success and failure. There technically were three objects in the success part of the original code, so the first two were ignored. The solution I just proposed is to package the three objects into a single array: because newTrial treats commands packaged in an array the same way as direct series of commands, you still get the intended result.

    Jeremy

    in reply to: Catch Trials #5578
    Jeremy
    Keymaster

    Hi,

    There are a couple functions you might be interested in looking up, like sepWith or randomizeNoMoreThan, but both require specific labeling.

    The way I understand your case, you have one block of undifferentiated trials in which you want to inject some other trials at regular intervals. This is definitely something you can do by coding your own function, the way I did for randomizeNoMoreThan above, once you’ve determined how frequently you want the catch trials to appear, and whether you want to re-use the same catch trial each time, or pre-generate multiple catch trials

    Another method would be to modify the running order. PennController uses this method in a few cases, but hopefully that shouldn’t create any conflicts

    Jeremy

    in reply to: Multiple trial repetition #5576
    Jeremy
    Keymaster

    Hi Farzaneh,

    Unfortunately IBEX only supports static sequences of trials: the sequence of trials is computed at the very beginning of the experiment and proceeds linearly.

    The only solution for implementing any loop of this kind at the moment is to create a single trial which will take care of executing some code in a loop. So you will have to make your two practice trials fit a single PennController trial, and run their code as part of a callback. Here is a possible implementation:

    const launch = (audio,image1,image2,image3,image4) => [
        clear()
        ,
        newAudio(audio).play().wait()
        ,
        newSelector("select").log()
        ,
        newCanvas("images", 1270 , 610)
            .add( 260,   0, newImage(image1).size(270,270).css("border","solid 1px black").selector("select") )
            .add( 730,   0, newImage(image2).size(270,270).css("border","solid 1px black").selector("select") )
            .add( 260, 320, newImage(image3).size(270,270).css("border","solid 1px black").selector("select") )
            .add( 730, 320, newImage(image4).size(270,270).css("border","solid 1px black").selector("select") )
            .print()
        ,
        getSelector("select").wait().disable()
        ,
        newTimer(250).start().wait()
        ,
        getSelector("select").enable()
        ,
        clear()
    ]
    
    newTrial(
        newButton("Start").print().wait().remove()
        ,
        newButton("launch").callback(
            ...launch("p1_aud_hp_sr.mp3","Bunny.png","Mouse.png","Cat.png","Dog.png")
            ,
            ...launch("p2_aud_hp_sr.mp3","Goose.png","Horse.png","Bear.png","Cat.png")
            ,
            getButton("Restart").print(),
            getButton("Proceed").print()
        )
        .click()
        ,
        newButton("Restart").callback( getButton("launch").click() ),
        newButton("Proceed").wait()
    )

    Jeremy

    in reply to: Using if statements during a trial #5572
    Jeremy
    Keymaster

    Hello Max,

    TLDR: this is the (or rather, one) correct syntax

    newTrial( "experiment" ,
        newText ("FullText", row.FullText),
        newButton("FTButton1","Proceed to next Trial"),
        newButton("FTButton2","Proceed to Comprehension Question"),
        newText("CompQ",row.CompQ),
        newButton("CQButton","Placeholder, just click to answer"),
        getText("FullText").print(),
        ( row.CompYN==Y ?
            getButton("FTButton2")
                .print()
                .wait()
                .remove("FTButton2","FullText"),
            getText("CompQ")
                .print(),
            getButton("CQButton")
                .print()
                .wait()
                .remove("CompQ","CQButton")
        :
            getButton("FTButton1")
                .print()
                .wait()
                .remove("FTButton1","FullText")       
        )
    ) //closes newTrial

    You cannot inject if statements this way into a PennController trial, because the sequence of commands that you pass to newTrial really are arguments that you pass to a function, and javascript does not allow you to insert if statements in this kind of environment. What you can do, however, is use the so-called inline ternary conditional operator, which uses this syntax: ( test ? success : failure )

    Note that the condition will be evaluated at the very beginning of your experiment, which is fine in your case because you are testing the value of a column from your table. If you wanted to test a value that is manipulated upon runtime however, say some input from your participant, you would need to use a PennController test command, to ensure that the test is performed only after input.

    Jeremy

Viewing 15 posts - 1,246 through 1,260 (of 1,522 total)