including attention checks and break

PennController for IBEX Forums Support including attention checks and break

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • #5973
    kathy
    Participant

    Hi Jeremy,

    I have an experiment with 160 trial items (to be rated on a scale). I have currently included a break after half of the items (80) using the subsequence function / code: subsequence(repeat(randomize(“ListeW”), 80) , “break”).

    However, I would also like to include two attention checks (asking participants to choose a specific number on the scale), one in each half of the experiment. So one attention check should come after 40 items, and the other one after 120. Is there a way to code this without having to divide my .csv file and uploading two separate ones?

    The code for the attention check will be this:

    //////ATTENTIONCHECK
    PennController("attentionCheck",
        newText("attentionCheck", "Bitte wählen Sie auf der untenstehenden Skala fünfunddreißig aus!")
        .settings.center()
        .settings.bold()
        .settings.css("font-size", "30px")
        .print()
       
         ,
         
         newScale("slider","0", "1","2","3","4","5","6","7","8","9", "10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49", "50")
    .settings.center()
    .settings.size (1200)
    .settings.labelsPosition("bottom")
    .print()
    .settings.log()
    .wait()
                   ,                          
         newButton("okay", "weiter")
            .settings.center()
            .print()
            .wait()
            .remove()
        ,
       
        getText("attentionCheck")
            .remove()
        ,   
        getScale("slider")
            .remove()
        
        );

    Thank you very much in advance!

    Best,
    Kathy

    #5976
    Jeremy
    Keymaster

    Hi Kathy,

    EDIT: Oops, looks like I misremembered how the subsequence function works. See message below for an alternative solution

    Since you’re already using the subsequence function, why don’t you just tell it exactly that? Here’s what your whole Sequence command could look like:

    Sequence( 
      "intro" 
      ,
      subsequence( 
          repeat(randomize("ListeW"), 40) , "attentionCheck"
          ,
          repeat(randomize("ListeW"), 40) , "break"
          ,
          repeat(randomize("ListeW"), 40) , "attentionCheck"
          ,
          repeat(randomize("ListeW"), 40)
      )
      ,
      "end"
    )

    I see that you named your Scale element “slider,” if you want to make it a “real” slider, you could consider using the slider command, like this:

    newScale("slider", 50)
      .before( newText("0 ") )
      .after( newText(" 50") )
      .slider()
      .print()
      .log()
      .wait()

    In any case, you don’t need to manually specify all 50 labels, you can just do this:

    newScale("slider", 50).labelsPosition("bottom")

    Jeremy

    • This reply was modified 3 years, 8 months ago by Jeremy. Reason: Mistake
    • This reply was modified 3 years, 8 months ago by Jeremy. Reason: Solution in next message
    #5980
    Jeremy
    Keymaster

    So I came up with a new function that I think is better suited to your needs: it simply picks a number of trials from a set, so in your case you can pick 40 trials from the randomized set of all the trials labeled ListeW (randomize("ListeW")), and then pick 40 other trials from that same set. The trick here is that you’ll store the set in a variable, so you can reference it when you call pick again, instead of recreating a brand new set with randomize("ListeW").

    Define the pick/Pick functions the way you defined subsequence:

    function Pick(set,n) {
        assert(set instanceof Object, "First argument of pick cannot be a plain string" );
        n = Number(n);
        if (isNaN(n) || n<0) n = 0;
        this.args = [set];
        set.remainingSet = null;
        this.run = function(arrays){
            if (set.remainingSet===null) set.remainingSet = arrays[0];
            const newArray = [];
            for (let i = 0; i < n && set.remainingSet.length; i++)
                newArray.push( set.remainingSet.shift() );
            return newArray;
        }
    }
    function pick(set, n) { return new Pick(set,n); } 

    Then you can use it like this:

    Sequence( 
        "intro",
        pick(liste=randomize("ListeW"),40),"attentionCheck",
        pick(liste,40),"break",
        pick(liste,40),"attentionCheck",
        pick(liste,40),  
        "end"
    )

    As you can see I generate a randomized set of trials in the first pick function, and I store it in a javascript variable named liste, so I can reference it in the next three pick's. You could actually even create the set above the Sequence command and only reference it using the variable in all the pick functions. You just want to always use a unique javascript variable name (liste is not ideal because the generic English word list is likely to be used elsewhere, but hopefully the final e will help avoid any conflicts).

    Let me know if you have questions

    Jeremy

    #5989
    kathy
    Participant

    Dear Jeremy,

    thanks a lot! I tried the first thing you suggested and as you said below, that doesn’t seem to be the right function for me as I realized that items will be shown repeatedly after the break or attention checks, which is not what I wanted – I’d like to have different (randomized) items from the same set in each section so that every item will have been rated only once per participant, as you said in your second reply. I’ll try out the second solution you suggested tomorrow and will probably get back to you once I encounter difficulties. Thank you so much in any case!

    Kathy

    #6645
    rhododendron
    Participant

    Hi Jeremy,

    I have been trying to use the pick function in my experiment to implement breaks as well. The problem is that I am using a csv file for the experimental trials, which have already been pseudo-randomized and thus I want to avoid using the function randomize() on the javascript list variable. I tried defining some sort of dummy string function to return the input strings and leave them unchanged. However, this does not seem to work.
    Is there any possibility to use pick without randomization or is it just easier to use separate csv files and just include breaks in between?

    Thank you!

    #6646
    Jeremy
    Keymaster

    Hi,

    Simply replace randomize with seq and it should be enough

    Jeremy

    #7587
    dod
    Participant

    Hi,

    Sorry for jumping in an old post, but I got a similar problem.
    Basically, I need to alternate every single experimental trial with 3 filler sentences to be presented either visually (read&repeat) or aurally (listen&repeat). The modality of the fillers is pre-assigned, but I need to randomize the order throughout the experiment and across participants.

    I used sepWith to alternate the experimental/filler trials, and I defined the Pick function as specified above. It was super useful and I solved the problem of randomizing the modality of the fillers as well as presenting only 3 fillers at every time.
    However, I always get the same 3 filler sentences. I know I should store the set of used fillers in a new variable (the one you referred to as ‘liste’ in the example above). But I am not completely sure about how to add this detail in my sequence without having to apply a pick function+’liste’ variable to each and every of my experimental trials as well.
    To make things even more complicated, it is a production experiment, so ideally I would want to have a sepWith asyncUpload to start uploading the recordings as they go.

    So far, the sequence is specified as follow:

    Sequence("welcome", "preload", "init", sepWith("asyncUpload",(randomize(anyOf("practice-listen","practice-read")))),
          
    	sepWith(
            pick(randomize(anyOf("filler-listen","filler-read")),3),
            "exp-trial"),
    
     "upload", "send", "bye"
    )

    where:
    – “filler-listen” is a trial with the specific code for audio (listen&repeat) stimuli;
    – “filler-read” is a trial with the specific code for visual (read&repeat) stimuli;
    – “exp-trial” is the actual experimental trial of listen&repeat(and record)-read&repeat(and record), with listen sentences and read sentences pre-paired together and stored in the same row in the csv table.

    Thank you in advance for any help!

    #7590
    Jeremy
    Keymaster

    Hi,

    If you are fine with having an “asyncUpload” trial between every single trial, you could do this:

    Sequence( 
        sepWith(
            "asyncUpload"
            ,
            subsequence( randomize("exp-trial") , repeat(randomize(startsWith("filler")),3) )
        )
    )

    Just remember to add a script file defining subsequence and repeat to your project’s Modules folder

    Jeremy

    #7593
    dod
    Participant

    Hi,

    It works perfectly, thank you!

    #10994
    suphasiree
    Participant

    Hi Jeremy!

    My experiment is a lexical decision task containing 61 experimental items and 61 fillers. There are 4 groups of experimental items; each participant would see one of these four sets, plus the fillers (same fillers across all groups).

    I’ve divided the total 122 items into 3 parts, so that participants can take a break twice during the experiment. I’ve used the pick() function that you described above and the rshuffle() function to achieve this.

    Here is the code I’m working with:
    critical = randomize(“main.trial”)
    fillers = randomize(“filler.trial”)

    Sequence( rshuffle(pick(critical, 20),
    pick(fillers, 20)
    ),
    “break_1”,
    rshuffle(pick(critical, 20),
    pick(fillers, 20)
    ),
    “break_2”,
    rshuffle(pick(critical, 21),
    pick(fillers, 21)
    ),
    “send” , “goodbye”
    );

    This is what I want to create:
    Part 1
    – Randomly pick 20 experimental items and 20 fillers, mix them together and present them in random order
    Break1
    Part 2
    – Randomly pick 20 more experimental items and 20 more fillers, mix them together and present them in random order
    Break2
    Part 3
    – Pick the remaining 21 experimental items and the 21 fillers, mix them together and present them in random order

    As described above, I want the experimental items and the fillers to be randomly shuffled together. However, right now they are evenly presented like this: experimental, filler, experimental, filler, experimental, filler …

    How can I fix the code so that the experimental items and filler items are randomly mixed together? I tried using randomize() instead of rshuffle(), but that did not work either.

    Thanks so much for your time.

    #10996
    suphasiree
    Participant

    Hi Jeremy,

    Never mind, I’ve figured it out! I didn’t realize that rshuffle() creates evenly spaced trials, which is not what I wanted. It worked when I used the randomize() function and embedded the seq() function to specify the two trial types (filler and critical).

    • This reply was modified 2 months, 1 week ago by suphasiree.
Viewing 11 posts - 1 through 11 (of 11 total)
  • You must be logged in to reply to this topic.