Multiple choice buttons and recording responses

PennController for IBEX Forums Support Multiple choice buttons and recording responses

Tagged: ,

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #5082
    chahlabena
    Participant

    I’m not sure if this question was mentioned elsewhere, so sorry if it was! My experiment involves identifying sounds and the sounds in question are p, b, v, and f. I tried the code in bold below and tried to do 4 separate buttons for both options, I only get the first “p” button, and after I press that, each one of the others follow in succession. Is there a way to get them all displayed at the same time?

    Also, I’m a bit confused with how I can get the participants responses in a .csv file later? All I need is to know what button they chose for which of the audio files (I will be adding a. csv table later with my remaining 80 trials), where exactly should I put the .log codes to record participant ID and audio + button response?

    CODE

    PennController.ResetPrefix(null)
    
    Sequence( "welcome" , "trialintro", "trial1","trial2", randomize("experiment"), "send" , "final" )
    
    newTrial("welcome",
        defaultText
            .print()
        ,
         newText("<p>Welcome!</p>")
        ,
        newText("<p>This is the first part of a two-part experiment.</p>")
        ,
        newText("<p>In this Identification experiment, you will hear a series of words, and identify which of the four sounds p, b, f or v was heard.</p>")
        ,
        newText("<p> The experiment will take you approximately 10-15 minutes and you will be compensated for your time.")
        ,
        newText("<p>Please enter your name and then click the button below to start the experiment.</p>")
        ,
        newTextInput("inputID")
            .print()
        ,
        newButton("Start")
            .print()
            .wait()
        ,
        newVar("ID")
            .global()
            .set( getTextInput("inputID") )
    )
    .log( "ID" , getVar("ID") )
    
    
    newTrial("trialintro",
     defaultText
            .print()
        ,
    newText("<p>We will begin with a trial.</p><p>You will hear a word, please identify the first or last sound you heard by choosing a button.</p>")
    .settings.css("font-size", "xxem")
    ,
     newButton("Continue to trial")
            .print()
            .wait()
    )
    
    newTrial("trial1",
    newAudio("description", "but.mp3")
        .print()
        .play()
    ,
    newText("What sound did you hear?")
        .print()
    ,
        newButton("p", "b", "f", "v")
            .settings.log()
            .print()
            .wait()
            , 
            
         getAudio("description")
        .stop()
        .log() 
        
            
    )
    
    newTrial("trial2",
    newAudio("description", "peace.mp3")
        .print()
        .play()
    ,
    newText("What sound did you hear?")
        .print()
    ,
        newButton("p", "b","f","v")
            .settings.log()
            .print()
            .wait()
            ,
    
        getAudio("description")
        .stop()
        .log() 
        
            
    )
    
    SendResults("send") 
    
    newTrial( "final" ,
        newText("<p>Thank you for your participation!</p>")
            .print()
        ,
        newText("<p>Click here to validate your participation.</p>")
            .print()
        ,
        newButton("void")
            .wait()
    )

    Thanks!

    • This topic was modified 4 years, 2 months ago by chahlabena.
    #5084
    Jeremy
    Keymaster

    Hi,

    The commands in your script are executed in the order in which they appear, from the top down, and the wait command halts the execution of the script until the relevant event happens. This is why creating 4 buttons with 4 wait commands in a top-down sequence will only get to the next buttons after the previous wait commands are released, ie your participant will have to click the earlier buttons to get to the later ones.

    Also, you cannot create multiple buttons using one newButton command the way you’re trying to do it. When in doubt check the documentation page for the element type. What you want is either a Scale element where you define 4 options with the texts you want, or print the four buttons on the page without calling .wait on them, and add them to a Selector element, on which you do call the .wait command (which will release execution when one of the items in the Selector, that is one of your four buttons, is clicked).

    Then use .log on your Scale or Selector element and it will add a line in your results file reporting which option/item was clicked.

    Note that there exists a different .log command that you should insert immediately after the closing parenthesis of newTrial, which lets you append columns to every row that the corresponding trial reports in the results file. This is the command you’ll use to keep track of your participant’s and each trial’s info. Take a look at the “Template” and “participant” pages of the tutorial to see an illustration of how to use it.

    Jeremy

    #5085
    chahlabena
    Participant

    Hello!

    Thank you!
    So I managed to make the buttons work by changing them entirely to clickable pictures. As for the results, whenever I put a .log after one of the trials, my experiment stops working after the first test trial and when I remove them, it goes all the way to the end of the main experiment (as I want it to) but I don’t get a downloadable .csv file for each participant – instead I get their results in the raw_result/result files.

    This is how the code is now set up, how/where would I put I put a .log function here to give me a downloadable output, and in the validation part towards the end, the link I’m supposed to put is the link to my experiment, yes?

    PennController.ResetPrefix(null)
    
    Sequence( "welcome" , "trialintro", "trial1","trial2", "mainintro", randomize("experiment"), "send" , "final" )
    
    newTrial("welcome",
        defaultText
            .print()
        ,
         newText("<p>Welcome!</p>")
        ,
        newText("<p>This is the first part of a two-part experiment.</p>")
        ,
        newText("<p>In this <strong>Identification</strong> experiment, you will hear a series of words, and identify which of the four sounds <strong>p</strong>, <strong>b</strong>, <strong>f</strong> or <strong>v</strong> was heard.</p>")
        ,
        newText("<p> The experiment will take you approximately 10-15 minutes and you will be compensated for your time appropriately.")
        ,
        newText("<p>Please enter your name, ID (if relevant) and course code (if relevant) and then click the button below to start the experiment.</p>")
        ,
        newText("<p> If the ID and course code's are not applicable, please insert <strong>N/A.</strong></p>")
        ,
        newTextInput("inputID")
            .settings.before(newText("ID:  "))
            .center()
            .print()
        
        ,
        
        newTextInput("inputName")
            .settings.before(newText("Name:  "))
            .center()
            .print()
            ,
            
             newTextInput("inputCoursecode")
            .settings.before(newText("Course code:  "))
            .center()
            .print()
            ,  
            
            
        newButton("Start")
            .print()
            .wait()
        ,
        newVar("ID")
            .global()
            .set( getTextInput("inputID") )
            ,
             newVar("Name")
            .global()
            .set( getTextInput("inputName") )
            ,
            
              newVar("Coursecode")
            .global()
            .set( getTextInput("inputCoursecode") )
    )
    .log( "ID" , getVar("ID") )
    .log ("Name", getVar("Name"))
    .log ("Course code", getVar("Coursecode"))
    ,
    newTrial("trialintro",
     defaultText
            .print()
        ,
    newText("<p>We will begin with a trial.</p><p>You will hear a word, please identify the first <strong>or</strong> last sound you heard by choosing the appropriate sound.</p>")
    .settings.css("font-size", "xxem")
    ,
     newButton("Continue to trial")
            .print()
            .wait()
    )
    
     
    
    newTrial("trial1",
    newAudio("description", "but.mp3")
    .center()
        .print()
        .play()
    ,
    newText("What sound did you hear?")
    .center()
    .print()
    ,
    
    newImage('b' , 'b.png' )
        .settings.size(211, 167)
    ,
    newImage('p' , 'p.png' )
        .settings.size(213, 170)
    ,
    newImage('f' , 'f.png' )
        .settings.size(205, 159)
    ,
    newImage('v' , 'v.png' )
        .settings.size(212, 173)
    ,
    
    newCanvas( 'four letters', 700, 500)
        .settings.add( 128, 155, getImage('b'), 0 )
        .settings.add( 0, 146, getImage('p'), 1 )
        .settings.add( 257, 155, getImage('f'), 2 )
        .settings.add( 382, 147, getImage('v'), 3 )
        .center() 
        .print()
    ,
    newSelector('four letters')
        .settings.add( getImage('p') , getImage('b'), getImage('f'), getImage('v') ) 
        .wait()
        .settings.log()
        ,
            
         getAudio("description")
        .stop()
        .log() 
        
            
    )
    
    newTrial("trial2",
    newAudio("description", "peace.mp3")
    .center()
        .print()
        .play()
    ,
    newText("What sound did you hear?")
    .center()
        .print()
    ,
    newImage('b' , 'b.png' )
        .settings.size(211, 167)
    ,
    newImage('p' , 'p.png' )
        .settings.size(213, 170)
    ,
    newImage('f' , 'f.png' )
        .settings.size(205, 159)
    ,
    newImage('v' , 'v.png' )
        .settings.size(212, 173)
    ,
    
    newCanvas( 'four letters', 700, 500)
        .settings.add( 128, 155, getImage('b'), 0 )
        .settings.add( 0, 146, getImage('p'), 1 )
        .settings.add( 257, 155, getImage('f'), 2 )
        .settings.add( 382, 147, getImage('v'), 3 )
        .center()
        .print()
    ,
    newSelector('four letters')
        .settings.add( getImage('p') , getImage('b'), getImage('f'), getImage('v') ) 
        .wait()
        .settings.log()
            
    )
    ,
    
    newTrial("mainintro",
     defaultText
            .print()
        ,
    newText("<p>We will now move to the main experiment.</p><p>You will hear a word, please identify the first <strong>or</strong> last sound you heard by choosing the appropriate sound.</p>")
    .settings.css("font-size", "xxem")
    ,
     newButton("Continue to experiment")
            .print()
            .wait()
    ) 
    
    
    
    Template( variable => 
      newTrial("experiment",
        newAudio("description", variable.SoundFile)
            .play()
        ,
    newText("What sound did you hear?")
    .center()
    .print()
    ,
       newImage('b' , 'b.png' )
        .settings.size(211, 167)
    ,
    newImage('p' , 'p.png' )
        .settings.size(213, 170)
    ,
    newImage('f' , 'f.png' )
        .settings.size(205, 159)
    ,
    newImage('v' , 'v.png' )
        .settings.size(212, 173)
    ,
    
    newCanvas( 'four letters', 700, 500)
        .settings.add( 128, 155, getImage('b'), 0 )
        .settings.add( 0, 146, getImage('p'), 1 )
        .settings.add( 257, 155, getImage('f'), 2 )
        .settings.add( 382, 147, getImage('v'), 3 )
        .center()
        .print()
    ,
    newSelector('four letters')
        .settings.add( getImage('p') , getImage('b'), getImage('f'), getImage('v') ) 
        .wait()
        .settings.log()
        ,
        getAudio("description")
           .wait("first")
      )
      .log( "ID" , getVar("ID") ) 
      .log ("Name", getVar("Name"))
       .log ("Course code", getVar("Coursecode"))
      .log( "CorrAns"   , variable.CorrAns   )
      .log("Word", variable.SoundFile)
    )
    
    
    
    
    SendResults("send") 
    
    newTrial( "final" ,
        newText("<p>Thank you for your participation!</p>")
            .print()
        ,
        newText("<p><a href='https://expt.pcibex.net/ibexexps/chahlabena/Identification/experiment.html'>Click here to validate your participation.</a></p>")
            .print()
        ,
        newButton("void")
            .wait()
    )

    Thank you!

    #5086
    Jeremy
    Keymaster

    Hello,

    Do you see any error messages in the Debug window when you add the .log command(s) causing your experiment to crash? Note that you won’t get any expression starting with variable. to work in a .log attached to a newTrial that is not embedded in a Template command, as those expressions have a meaning as long as they point to a row in your table.

    Also, PCIbex current does not generate individual files for your participants. Instead, it aggregates the results of all your participants in the CSV-formatted results and JSON-formatted raw_results files. Note that the CSV file results also contains comment lines prefixes with the # character: you can freely delete those lines if you want.

    As for the link at the end of your experiment, it really depends on how you recruit your participants. It’s quite unlikely that you’d really want to redirect participants who have completed your experiment to the same experiment again. Some platforms like Prolific or SONA let you provide your participants with a confirmation link to insert at the end of your experiment that will automatically validate your participants’ submissions. You can also decide to track your participants’ submissions manually if that’s an option you’d be more comfortable with, and I see you’re already collecting IDs about your participants, so it’s definitely something you can do (keep in mind though that rules and/or laws usually apply to collection and storage of identifying information, such as first and last names for example).

    Jeremy

    #5087
    chahlabena
    Participant

    No error messages, thankfully! I saw the results but thought it would output separate files, it’s fine! Thank you!

    One last question (sorry!)
    I included an html consent form, but my error messages (for incomplete forms) doesn’t seem to work, I get one “continue” button that shows up if they press “continue” with an incomplete form.

    PennController( "consent" ,
        newHtml("consent form", "consent.html")
            .print()
            .log()
        ,
        newButton("continue", "Continue")
            .print()
            .wait()
    );
            
    PennController( "authorization" ,
        newHtml("authorization form", "authorization.html")
        .settings.checkboxWarning("Please check <strong>I hereby consent to participate</strong> to continue.")
        .print()
        .settings.inputWarning("Please fill out these fields to continue.")
        .print()
        ,
        newButton("Continue")
            .print()
            .wait()
        
        ,
        getHtml("authorization form")
        .warn()
        ,
        
        newButton("Continue")
        .print()
        .wait()
      );

    Thank you so much!

    #5088
    Jeremy
    Keymaster

    Hi!

    You need to use the .test.complete and .warn commands on your Html element to achieve what you want (follow the links to see illustrations in the documentation).

    Jeremy

    #5090
    chahlabena
    Participant

    Thank you!!!!

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