Jeremy

Forum Replies Created

Viewing 15 posts - 271 through 285 (of 1,522 total)
  • Author
    Posts
  • in reply to: Randomization by feature and by item #9660
    Jeremy
    Keymaster

    Hi,

    The pick function only accepts IBEX-style predicates as an argument (eg. randomize("label")) but features is a 10-ary array, so passing it to pick directly won’t work

    You can create a (sub)sequence from it though, using IBEX’s seq function: seq(...features)

    So you could do that:

    featuresSeq = seq(...features)
    Sequence("WelcomeConsent",
        "counter",
        "demographics",   
        "instructions1",
        "exercise",
        "startofexp",
        pick(featuresSeq,500),"break",
        pick(featuresSeq,500),"break",
        pick(featuresSeq,500),
        SendResults(),
        "Bye");

    Jeremy

    in reply to: Media recordings not uploading to server after crash #9659
    Jeremy
    Keymaster

    Hi Val,

    So just to make sure we’re on the same page, you don’t even get a zip file for the practice items?

    I just took a test run of the practice+B1 items, and the two corresponding POST requests were responsed with uploads/f9c2be0d-3a62-5b8d-cdd3-12477feb343e.zip (practice) and uploads/8ee6d91a-d111-d194-0528-341f049e8478.zip (B1); are you saying you don’t see those two zip files in the uploads subfolder on your server?

    Jeremy

    in reply to: Problems downloading data #9657
    Jeremy
    Keymaster

    Hi Jet,

    I checked the database and the good news is, all submissions seem to have 57 rows each, so the mostly empty results file you get does not mean that there was a problem during data collection, but only during the download process

    The farm has been slow again for the past few hours, but it looks like it’s doing a little better now. Let me know if you still have trouble accessing your results file, and if you do, I will generate one for you

    Jeremy

    in reply to: Pick out items after randomization #9656
    Jeremy
    Keymaster

    Hi,

    When I try your code with the table you posted above (adding a “Sentence” column) I do get both “Long” and “Short” trials included in the experimental sequence. Do you have a link to your experiment so I can help troubleshoot?

    Jeremy

    in reply to: Randomization question #9650
    Jeremy
    Keymaster

    Hi Jeff,

    If you know in advance that you want 10 trials to use column 2 (let’s call it “Joke”) and 10 to use column 3 (let’s call it “NonJoke”) you can simply generate an array of 20 entries, half true half false, shuffle that array and scan it within Template:

    Sequence( rshuffle("trial-joke","trial-non-joke") ) 
    
    var jokings = [...new Array(20)].map((v,i)=>i<10);
    fisherYates(jokings);
    
    var joking;
    Template( row =>
      newTrial( "trial-" + ((joking=jokings.pop()) ? "joke" : "non-joke") ,
        newText( "prompt" , ( joking ? row.Joke : row.NonJoke ) ).print()
        // ...
      )
      .log( "joking" , joking )
    )

    Jeremy

    in reply to: Media recordings not uploading to server after crash #9649
    Jeremy
    Keymaster

    Hello,

    Are you still experiencing this issue? I just took a partial test run, and the upload requests were responded with a zip filename, which signals that the PHP script ran successfully. However, I can’t check your server to see if the zip file did end up in the upload folder

    Jeremy

    in reply to: Pick out items after randomization #9648
    Jeremy
    Keymaster

    Hi,

    If you are not familiar with the way (PC)Ibex offers control over the sequence of trials, I recommend reading the PCIbex documentation on labels and the original IBEX manual

    In your case, all you need to do to get 1+2 is properly label the trials so you can reference them appropriately in predicates (randomize) in the Sequence command:

    Template( row =>
      newTrial( row.Condition+"_Set"+row.Set ,
        // etc.
    
    Sequence( randomize(startsWith("Short")) , randomize(startsWith("Long")) )

    Mixing fillers in is more complex if you have a single set of fillers that should be distributed across the “Short” and “Long” trials. If you know in advance how many filler trials you’ll have (say, 40) you could use the custom pick function to randomly pick half (20) of those trials and mix them in with the “Short” trials, and mix the other half in with the “Long” trials:

    fillers = randomize("Filler") // assuming all your filler trials are labeled "Filler"
    
    Sequence(
      rshuffle( startsWith("Short") , pick(fillers,20) ),
      rshuffle( startsWith("Long")  , pick(fillers,20) )
    )

    Jeremy

    • This reply was modified 2 years, 8 months ago by Jeremy. Reason: added missing closing parentheses
    in reply to: Updating checkbox scale conditionally #9642
    Jeremy
    Keymaster

    Hi Laia,

    Place the code you have after the first wait in callback instead:

    newTrial("location",
        newText("Where do you live?").print().cssContainer({"margin":"1em"})
        ,
        defaultScale.radio().labelsPosition("right").log()
        ,
        newButton("go")
        ,
        newScale("us", 'California', 'New York'),
        newScale("uk", 'England', 'Scotland')
        ,
        newScale("country", "US", "UK").print().cssContainer({"margin":"1em"})
            .callback( 
                getButton("go").remove(),
                getScale("uk").remove().test.selected().success(self.unselect()),
                getScale("us").remove().test.selected().success(self.unselect())
                ,
                self.test.selected("US")
                .success( getScale("us").print().wait(),getButton("go").print() ) 
                .failure( getScale("uk").print().wait(),getButton("go").print() ) 
            )
        ,
        getButton("go").wait()
    )

    Jeremy

    Jeremy
    Keymaster

    Hi,

    Some elements are missing from the pieces of code you posted (how color_order_label, leftColor, centerColor, rightColor and getImageEmotion are defined, where/whether createColorGroup is called elsewhere) but if I understand your question correctly, you should be able to do something like this:

    function createColorGroup(int) {
        var bugba = ["blue", "green", "black", "bugba"];
        var gbuba = ["green", "blue", "black", "gbuba"];
        var bagbu = ["black", "green", "blue", "bagbu"];
        var gbabu = ["green", "black", "blue", "gbabu"];
        var babug = ["black", "blue", "green", "babug"];
        var bubag = ["blue", "black", "green", "bubag"];
        
        var groups = [bugba, gbuba, bagbu, gbabu, babug, bubag];
        
        return groups[int]; 
    }
    color_group = createColorGroup(Math.round(6*Math.random()))
    leftColor = color_group[0]
    centerColor = color_group[1]
    rightColor = color_group[2]
    color_order_label = color_group[3]
    
    Template( "emoMusicGroupedPracticeV2.csv" ,
      row => newTrial("PracticeEmoMusic",
        newAudio(row.audiofile).center().print().wait() 
        ,
        newText("Q", "<p>Whose face matches the music?</p>").center().css("font-size", "1.5em").print()
        ,
        newSelector("eugenies").once().frame("dashed 0px white")
        ,
        defaultImage.cssContainer({border:"solid 2px black","background-color":"white"})
        ,
        newImage(String(getImageEmotion(row.leftImage)), leftColor+row.leftImage),
        newImage("calmImage", centerColor + "calmnolabel.jpg"),
        newImage(String(getImageEmotion(row.rightImage)), rightColor+row.rightImage)
        ,
        newCanvas("labels", 600, 200)
          .add("center at 18%", "middle at 50%", getImage(String(getImageEmotion(row.leftImage))))
          .add("center at 50%", "middle at 50%", getImage("calmImage"))
          .add("center at 82%", "middle at 50%", getImage(String(getImageEmotion(row.rightImage))))
          .color("yellow")
          .cssContainer("border", "solid 2px black")
          .center()
          .print()
        // etc.
      )
      .log("id", getVar("subjID"))
      .log("color_group", color_order_label)
    )

    Jeremy

    in reply to: Experiment farm not loading #9634
    Jeremy
    Keymaster

    Hello,

    Thank you for your messages. The farm was having issues handling traffic yesterday and crashed earlier today. I have restarted the servers and it is now running normally again

    Apologies for the inconvenience,
    Jeremy

    in reply to: Picture resources not printed during experimentation #9633
    Jeremy
    Keymaster

    Hello,

    Do you still experience the problem today? Everything runs smoothly when I open your demonstration links

    Best,
    Jeremy

    in reply to: Audio replay only once #9627
    Jeremy
    Keymaster

    Hello Jinyoung,

    As you found out, the problem with the command disable is that it doesn’t prevent the participant from playing the audio again by simply pressing the spacebar (which is something I should fix). Another problem is there’s no callback command on the Audio element that you could use after wait to execute some commands after later playbacks

    So one solution is to use another element’s callback command to execute some code that will run in parallel to the main script, which still needs to be running wait on the Selector element:

    newAudio("audio", variable.audio).center().print().wait(),
    newTimer("callback",1).callback( getAudio("audio").wait().remove() ).start()

    This way, if the participant plays the Audio element again, it will simply disappear from the page

    Now, another problem with your script is you print a Canvas element at the center of the page that you scale to fit the page’s dimensions, which results in that Canvas element covering the other elements already on the page, notably the Audio element, which you can no longer click because clicks now target the Canvas element on top of it instead. You should probably rethink the way you display the different elements (eg. by printing everything, including the texts and the Audio element inside the Canvas element) but if you want to keep things how they currently are, a straightforward solution is to make the clicks on the Canvas element “transparent”:

    newCanvas("canvas", 1800, 1000)
        .add(200, 380, getImage("nrc") )
        .add(1000, 380, getImage("rrc") )
        .scaling("page")
        .print("center at 50vw", "middle at 50vh")
        .cssContainer("pointer-events", "none")

    Jeremy

    in reply to: Shuffling audio and text elements consistently #9624
    Jeremy
    Keymaster

    Hi Laia,

    The code you posted in your message works perfectly well (except for the missing " after "practice1) but the code in your project has additional commands. In particular, it has this: defaultText.cssContainer({"margin-top":"1em", "margin-bottom":"1em"}).print(). This will silently add .print() right next to any newText command, which is why you see both sentence1 and sentence2 appear below each other as soon as they are created. Just remove .print(): defaultText.cssContainer({"margin-top":"1em", "margin-bottom":"1em"})

    The audios are not all played in the same order: I just had a test run where the first trial played audio2 then audio1, and the second trial played audio1 then audio2. Granted, there are only three trials, so it’s not unlikely that some test runs will play all three pairs of audios in the same order, just by chance

    Jeremy

    in reply to: Conditionals/display logic #9623
    Jeremy
    Keymaster

    Hi Laia,

    This line newVar("tag1").global().set(getScale("input_tag1")) will set the Var element to the last selected value, so you won’t exactly get what you want indeed: if the participant checks “oi” and later on also checks “fa”, then the Var element’s value will be “fa” and you won’t detect that “oi” is still checked

    Because the Scale element only detects the most recent selection, you’ll need to use a workaround:

    newTrial("pretest",
        newScale("input_tag1", "eh", "no", "oi", "fa") .checkbox().log().vertical().print(),
        newButton("go", "Endavant").print().wait(),
        newVar("tag1").global().set( ()=>document.querySelector("input[value='oi']").checked )
    )
    
    newTrial("exp",
        getVar("tag1").test.is(true).success(
            newText("instrus1", "You selected 'oi'!.") .print(),
            newButton("go", "Endavant") .print() .wait()
        )
    )

    Jeremy

    in reply to: Conditionals/display logic #9620
    Jeremy
    Keymaster

    Hi Laia,

    Your first trial (“pretest”) shows a Scale element, immediately sets the Var element “tag1” to the currently selected value on the scale (ie. no value, since the participant hasn’t had time to make a choice yet) then prints the “go” button and wait for a click before moving on to the next trial

    You second trial (“exp”) actually contains a fatal error, so it won’t be run, but if it were, it would check that the value of that Var element corresponds to the value of the variable oi, which is not only undefined (as far as I can tell) but most importantly not declared: the script does not know what oi refers to and crashes at that point, never creating the second trial nor executing any of the code that comes after that (ie. it doesn’t create the “end” trial either)

    So you’ll want to switch the order of the last two lines of your first trial and add double quotes around oi in the second trial:

    newTrial("pretest",
        newScale("input_tag1", "eh", "no", "oi", "fa") .checkbox().log().vertical().print(),
        newButton("go", "Endavant") .print() .wait(),
        newVar("tag1").global().set(getScale("input_tag1"))
    )
    
    newTrial("exp",
        getVar("tag1").test.is("oi").success(
            newText("instrus1", "You selected 'oi'!.") .print(),
            newButton("go", "Endavant") .print() .wait()
        )
    )

    If by “selecting at least oi” you mean selecting “oi” or “fa”, you can add a disjunct to your test:

    getVar("tag1").test.is("oi").or( getVar("tag1").test.is("fa") ).success(

    Jeremy

Viewing 15 posts - 271 through 285 (of 1,522 total)