Key press highlights wrong image

PennController for IBEX Forums Support Key press highlights wrong image

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #5240
    janina
    Participant

    Hello,

    Thank you for providing this support forum. I created an experiment that involves selecting an image that corresponds to the audio. It’s working fine, except that one of the keys (“J”) always highlights one of the pictures (image B). In later trials, the images appear on opposite sides of the screen. Yet, when the “J” key is pressed, it’s still image B that is highlighted although now the “J” key corresponds to image A. Image A is never highlighted. The F-key never results in highlighting. How can I get rid of this problem? I’m trying to illustrate the trials below.

    Thank you! I really appreciate your advice.

    Best,
    Janina

             Trial 1                                                                  Trial 2
    
    Image A         Image B                                                   Image B         Image A
     "F"             "J"                                                       "F"              "J"
    
    
    Press F: Image A is selected, no highlighting                           Press F: Image B is selected, no highlighting
    Press J: Image B is selected, image B is highlighted                    Press J: Image A is selected, Image B is highlighted
    
    *Highlighting: Box appears around the image
    
    
    
    +Template( "Template_practice.csv", variable => 
        PennController("practice1",    
        newAudio("AudioFile",variable.AudioFile)
            .play()
            .log()
        , 
        newImage("two", variable.LeftImage)
            .size(200,200)   
        ,
        newImage("one", variable.RightImage)
            .size(200,200)
        ,
        newCanvas(450,200)
            .add(   0 , 0 , getImage("two") )
            .add( 250 , 0 , getImage("one") )
            .print()
       ,
        newSelector()
            .add( getAudio("AudioFile"))
            .log()
            .shuffle()
            .add (getImage("one"), (getImage("two")))
            .log("first")
            .keys("F","J")
            .log("first")
            .wait()
        ,
        defaultText
            .print()
        ,
          newText("Press SPACE to continue ")
            .center()
       ,
        newButton("Space")
           .print()
           .center() 
       ,
        newSelector()
            .add (getButton("Space")) 
            .keys(" ")
            .wait()   
        )
        .log( "AudioFile" , variable.AudioFile )
     );
    
    Template("Template2_practice.csv", variable => 
        PennController("practice2",    
        newAudio("AudioFile",variable.AudioFile)
            .play()
        , 
        newImage("two", variable.LeftImage)
            .size(200,200)
        ,
        newImage("one", variable.RightImage)
            .size(200,200)
        ,
        newCanvas(450,200)
            .add(   0 , 0 , getImage("one") )
            .add( 250 , 0 , getImage("two") )
            .print()
      ,
        newSelector()
            .add( getAudio("AudioFile"))
            .shuffle()
            .settings.add (getImage("one"), getImage("two"))
            .keys("F","J")
            .log()
            .wait()    
         ,
        defaultText
            .print()
        ,
          newText("Press SPACE to continue ")
            .center()
       ,
        newButton("Space")
           .print()
           .center()
       ,
        newSelector()
            .add (getButton("Space")) 
            .keys(" ")
            .wait()
     )
        
        .log( "AudioFile" , variable.AudioFile )
    );
    #5241
    janina
    Participant

    Sorry, my attempt to illustrate the trials failed. I’ll try again, hope this makes sense.

    Trial 1

    Image A _________Image B
    “F”______________ “J”

    Press F: Image A is selected, no highlighting
    Press J: Image B is selected, image B is highlighted

    Trial 2

    Image B______ Image A
    “F” ____________“J”

    Press F: Image B is selected, no highlighting
    Press J: Image A is selected, Image B is highlighted

    *Highlighting: Box appears around the image

    #5242
    Jeremy
    Keymaster

    Hello Janina,

    There are a few issues with the way you use the Selector element.

    A Selector element is a purely non-visual element in and of itself, and it is meant to group other elements from the trial, which are displayed on the page. The reason you want to group elements is to represent a multiple-choice selection. In your case, your multiple-choice selection should be between two pictures: the Image element named one and the Image element named two. So these two elements should be the only ones you add to your Selector element: they are the only two possible answers. Which means you shouldn’t add the Audio element to the Selector: the Audio element is not a sensible answer (this sentence doesn’t even make much sense).

    The only time when the Selector element affects display (besides making an element clickable) is when you use shuffle. Remember, your script is evaluated in the order in which you read it, that is to say from left to right and from top to bottom. The effect of the command shuffle is to randomly switch the positions of the elements added to the Selector up to that point in the script, or to put it another way, so far in the reading. In your script, the only element that was added to the Selector when shuffle is evaluated/read is a (non-displayed) Audio element, so it has no practical effect.

    It also matters crucially in which order you add the elements to a Selector when it comes to the keys command. Much like the shuffle command, the keys command looks up the elements that were added to the Selector up to that point in the script, and in the order they were added. In your script, at the point where you keys commands are evaluated, the Selector element always contains three elements: a (non-displayed) Audio element, the Image element named one and the Image element named two. Note that you add one before two in both your Template blocks, which means that as far as the script is concerned, the Image element named two will always be the Selector’s last element when it reaches keys, ie. its third element (after the Audio element and the Image element one). The first key that you pass is associated with the first element and the second key that you pass is associated with the second element. So effectively, your first key (F) will always be associated with the Audio element and you second key (J) will always be associated with the Image element named one. Because you print that Image element to the right of you Canvas the first time, a keypress on J will highlight the right image the first time, and because you print that Image element the left of your Canvas the second time, a keypress on J will highlight the left image the second time.

    I’m also unclear on why you added multiple log commands on the Selector element. Here is a revision of your script that I think should accomplish what you want:

    Template( "Template_practice.csv", variable => 
      newTrial("practice1",    
        newAudio("AudioFile",variable.AudioFile)
            .play()
            .log()
        ,
        newImage("two", variable.LeftImage)
            .size(200,200)   
        ,
        newImage("one", variable.RightImage)
            .size(200,200)
        ,
        newCanvas(450,200)
            .add(   0 , 0 , getImage("two") )
            .add( 250 , 0 , getImage("one") )
            .print()
        ,
        newSelector()
            .add( getImage("two") , getImage("one") )
            .keys(       "F"      ,       "J"       )  // Spaces just to make the association clear
            .log("first") // or .log(), I don't know which one you want
            .wait()
        ,
        newText("Press SPACE to continue ")
            .center()
            .print()
        ,
        newButton("Space")
           .print()
           .center() 
       ,
        newSelector()
            .add( getButton("Space") )
            .keys(" ")
            .wait()   
      )
      .log( "AudioFile" , variable.AudioFile )
    );
    
    
    Template("Template2_practice.csv", variable => 
      newTrial("practice2",    
        newAudio("AudioFile",variable.AudioFile)
            .play()
        , 
        newImage("two", variable.LeftImage)
            .size(200,200)
        ,
        newImage("one", variable.RightImage)
            .size(200,200)
        ,
        newCanvas(450,200)
            .add(   0 , 0 , getImage("one") )
            .add( 250 , 0 , getImage("two") )
            .print()
        ,
        newSelector()
            .add( getImage("one") , getImage("two") )
            .keys(     "F"        ,        "J"      )
            .log("first") // or .log(), I don't know which one you want
            .wait()
        ,
        newText("Press SPACE to continue ")
            .center()
            .print()
        ,
        newButton("Space")
           .print()
           .center()
        ,
        newSelector()
            .add( getButton("Space") )
            .keys(" ")
            .wait()
      )
      .log( "AudioFile" , variable.AudioFile )
    );

    If the only difference between the two Template blocks it the left-right position of the images, I’d suggest you design your table with that manipulation in mind instead: right now the image that the LeftImage cell from Template2_practice.csv points at actually appears to the right anyway (same mismatch for RightImage) so it’s probably a better idea to merge the two tables and alternate which images you reference in LeftImage and in RightImage.

    Jeremy

    #5243
    janina
    Participant

    Hi Jeremy,

    Thank you for the quick and detailed response. I will try to implement these suggestions.

    Best,
    Janina

    #7157
    daniela
    Participant

    Hi Jeremy,

    I’m having an issue logging shuffle selector responses when there are multiple within a trial. Basically, I have 3 shuffled prompts which all require ‘F’ or ‘J’ for the response. Whichever key is selected for the final prompt is logged as the input for all responses within the trial. I’m certain I had seen somewhere how to handle this issue, but I can’t find it now unfortunately. Here’s the trial template:

    PennController. Template( PennController.GetTable( "stimuli.csv")// change this line for the appropriate experimental list
                              .filter("type" , "critical")
                              .filter("lifetime" , /^(dead|alive)$/)
                              ,
                              variable => ["post_task",
                                           "PennController", PennController(
                                               defaultText
                                               .settings.css("font-family","courier")
                                               // NEW TEXT
                                               ,
                                               newText("post_name",  variable.name)
                                               .settings.css("font-size", "25px")
                                               .settings.center()
                                               ,
                                               newText("occupation_correct", variable.occupation)
                                               .settings.css("font-size", "25px")
                                               .settings.center()
                                               ,
                                               newText("occupation_incorrect", variable.occupation_distractor)
                                               .settings.css("font-size", "25px")
                                               .settings.center()
                                               ,
                                               newText("nationality_correct",  variable.nationality)
                                               .settings.css("font-size", "25px")
                                               .settings.center()
                                               ,
                                               newText("nationality_incorrect",  variable.nationality_distractor)
                                               .settings.css("font-size", "25px")
                                               .settings.center()
                                               ,
                                               newText("lifetime_correct", variable.lifetime)
                                               .settings.css("font-size", "25px")
                                               .settings.center()
                                               ,
                                               newText("lifetime_incorrect", variable.lifetime_distractor)
                                               .settings.css("font-size", "25px")
                                               .settings.center()
                                               ,
                                               newImage("checkmark", "https://amor.cms.hu-berlin.de/~pallesid/dfg_pretests/pictures/checkmark.jpeg")
                                               .size(30,30)
                                               ,
                                               newImage("crossmark", "https://amor.cms.hu-berlin.de/~pallesid/dfg_pretests/pictures/crossmark.png")
                                               .size(30,30)
                                               ,
                                               // NAME
                                               newCanvas("name", "100vw" , "100vh")
                                               .add("center at 50%", "center at 20%", getText("post_name"))
                                               .add("center at 25%", "center at 20%", getImage("checkmark") )
                                               .add("center at 75%", "center at 20%", getImage("crossmark") )
                                               .center()
                                               .print()
                                               .log()
                                               ,
                                               newSelector("post_name")
                                               .add(getImage("checkmark"), getImage("crossmark"))
                                               .keys("F", "J")
                                               .wait()
                                               .log()
                                               ,
                                               getCanvas("name")
                                               .remove()
                                               ,
                                               // LIFETIME
                                               newCanvas("lifetime", "100vw" , "100vh")
                                               .add( "center at 30%", "center at 20%", getText("lifetime_correct"))
                                               .add( "center at 70%", "center at 20%", getText("lifetime_incorrect"))
                                               .center()
                                               .print()
                                               .log()
                                               ,
                                               newSelector("post_lifetime")
                                               .add(getText("lifetime_correct"), getText("lifetime_incorrect"))
                                               .shuffle()
                                               .keys("F", "J")
                                               .wait()
                                               .log()
                                               ,
                                               getCanvas("lifetime")
                                               .remove()
                                               ,
                                               // NATIONALITY
                                               newCanvas("nationality", "100vw" , "100vh")
                                               .add( "center at 30%", "center at 20%", getText("nationality_correct"))
                                               .add( "center at 70%", "center at 20%", getText("nationality_incorrect"))
                                               .center()
                                               .print()
                                               .log()
                                               ,
                                               newSelector("post_nationality")
                                               .add(getText("nationality_correct"), getText("nationality_incorrect"))
                                               .shuffle()
                                               .keys("F", "J")
                                               .wait()
                                               .log()
                                               ,
                                               getCanvas("nationality")
                                               .remove()
                                               ,
                                               // OCCUPATIION
                                               newCanvas("occupation", "100vw" , "100vh")
                                               .add(  "center at 30%", "center at 20%", getText("occupation_correct"))
                                               .add("center at 70%", "center at 20%", getText("occupation_incorrect"))
                                               .center()
                                               .print()
                                               .log()
                                               ,
                                               newSelector("post_occupation")
                                               .add(getText("occupation_correct"), getText("occupation_incorrect"))
                                               .shuffle()
                                               .keys("F", "J")
                                               .wait()
                                               .log()
                                               ,
                                               getCanvas("occupation")
                                               .remove()
                                               ,
                                               // WAIT
                                               newCanvas("dots", "100vw" , "100vh")
                                               .add("center at 50%", "center at 20%", newText("pleasewait_post2", "...").settings.css("font-size", "25px").settings.bold())
                                               .center()
                                               .print()
                                               .log()
                                               ,
                                               newTimer("wait_post2", 1000)
                                               .start()
                                               .wait()
                                               ,
                                               getCanvas("dots")
                                               .remove()
                                           )
                                           .log("type", variable.type)
                                           .log("lifetime" , variable.lifetime)
                                           .log("tense", variable.tense)
                                           .log("mm", variable.mm)
                                           .log("match", variable.match)
                                           .log("rating", getVar("rating"))
                                           .log("item" , variable.item_id)
                                           .log("name" , variable.name)
                                           .log("list", variable.list)
                                           .log( "withsquare", PennController.GetURLParameter("withsquare") )    
                                           .log("bare_verb", variable.bare) 
                                          ]);  

    Thanks in advance!

    Best,
    Daniela

    #7158
    Jeremy
    Keymaster

    Hi Daniela,

    Removing the Canvas element from the page does not disable the Selector element: it is still active, even if the elements it contains are not visible on the page

    Here’s an edited version of your code. Most of the edits are aesthetic; the crucial bit is the default .once() on the Selector elements, which prevents them from continuing to record keypresses after the initial choice:

    Template( 
      GetTable( "stimuli.csv")// change this line for the appropriate experimental list
          .filter("type" , "critical")
          .filter("lifetime" , /^(dead|alive)$/)
      ,
      variable => newTrial( "post_task" ,
        defaultText
            .css({"font-family":"courier","font-size":"25px"})
            .center()
        ,
        defaultSelector
            .once()
            .log()
        ,
        defaultCanvas
            .log()
            .center()
        // NEW TEXT
        ,
        newText("post_name",  variable.name)
        ,
        newText("occupation_correct", variable.occupation)
        ,
        newText("occupation_incorrect", variable.occupation_distractor)
        ,
        newText("nationality_correct",  variable.nationality)
        ,
        newText("nationality_incorrect",  variable.nationality_distractor)
        ,
        newText("lifetime_correct", variable.lifetime)
        ,
        newText("lifetime_incorrect", variable.lifetime_distractor)
        ,
        newImage("checkmark", "https://amor.cms.hu-berlin.de/~pallesid/dfg_pretests/pictures/checkmark.jpeg").size(30,30)
        ,
        newImage("crossmark", "https://amor.cms.hu-berlin.de/~pallesid/dfg_pretests/pictures/crossmark.png").size(30,30)
        ,
        // NAME
        newCanvas("name", "100vw" , "100vh")
            .add("center at 50%", "center at 20%", getText("post_name"))
            .add("center at 25%", "center at 20%", getImage("checkmark") )
            .add("center at 75%", "center at 20%", getImage("crossmark") )
            .print()
        ,
        newSelector("post_name")
            .add(getImage("checkmark"), getImage("crossmark"))
            .keys("F", "J")
            .wait()
        ,
        getCanvas("name").remove()
        ,
        // LIFETIME
        newCanvas("lifetime", "100vw" , "100vh")
            .add( "center at 30%", "center at 20%", getText("lifetime_correct"))
            .add( "center at 70%", "center at 20%", getText("lifetime_incorrect"))
            .print()
        ,
        newSelector("post_lifetime")
            .add(getText("lifetime_correct"), getText("lifetime_incorrect"))
            .shuffle()
            .keys("F", "J")
            .wait()
        ,
        getCanvas("lifetime").remove()
        ,
        // NATIONALITY
        newCanvas("nationality", "100vw" , "100vh")
            .add( "center at 30%", "center at 20%", getText("nationality_correct"))
            .add( "center at 70%", "center at 20%", getText("nationality_incorrect"))
            .print()
        ,
        newSelector("post_nationality")
            .add(getText("nationality_correct"), getText("nationality_incorrect"))
            .shuffle()
            .keys("F", "J")
            .wait()
        ,
        getCanvas("nationality").remove()
        ,
        // OCCUPATIION
        newCanvas("occupation", "100vw" , "100vh")
            .add(  "center at 30%", "center at 20%", getText("occupation_correct"))
            .add("center at 70%", "center at 20%", getText("occupation_incorrect"))
            .print()
        ,
        newSelector("post_occupation")
            .add(getText("occupation_correct"), getText("occupation_incorrect"))
            .shuffle()
            .keys("F", "J")
            .wait()
        ,
        getCanvas("occupation").remove()
        ,
        // WAIT
        newCanvas("dots", "100vw" , "100vh")
            .add("center at 50%", "center at 20%", newText("pleasewait_post2", "...").bold())
            .print()
        ,
        newTimer("wait_post2", 1000)
            .start()
            .wait()
        ,
        getCanvas("dots").remove()
      )
      .log("type", variable.type)
      .log("lifetime" , variable.lifetime)
      .log("tense", variable.tense)
      .log("mm", variable.mm)
      .log("match", variable.match)
      .log("rating", getVar("rating"))
      .log("item" , variable.item_id)
      .log("name" , variable.name)
      .log("list", variable.list)
      .log( "withsquare", GetURLParameter("withsquare") )    
      .log("bare_verb", variable.bare) 
    )
    

    Jeremy

    #7159
    daniela
    Participant

    Hi Jeremy,

    great, thanks again! It’s logging correctly now 🙂

    Best,
    Daniela

Viewing 7 posts - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.