Creating an experiment with multiple buttons that can only be selected one time each


Creating an experiment with multiple buttons that can only be selected...
Author
Message
ejn528
ejn528
New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)
Group: Forum Members
Posts: 4, Visits: 4
I am trying to create an implementation of the Automatic Balloon Analogue Risk Task (autoBART) using buttons instead of a text box to collect responses from the participants. I am new to inquisit and have been unable to complete this task.

The goal is to have 50 buttons on the screen (representing 1-50 pumps) and allow users to select how many pumps they desire, with each selection only being available once. So if they choose 30 pumps the first trial, that button will disappear for trial 2, and this will continue as they select from the remaining buttons.


I have a prototype that works, with 50 buttons that dictate the amount of pumps for the balloon, however I am not able to take options away in subsequent trials after they have been selected. So a participant could select the same number of pumps for every trial. This is what I am trying to prevent.

I hoped the solution would be found in lists, in theory I would have 3 lists: one master list of all buttons: "list.allbuttons", one list of unselected buttons: "list.unselected", which would contain all buttons at the start of the experiment, then as each button is selected the respective button would be removed from "list.unselected", and added to the third list: "list.selected".

This is not proving to be possible for several reasons:
First, lists behavior seems to only allow for a random selection of one of the items at a time, not all of the items.
Secondly, trial /validresponse does not take a list as a valid option, giving error message: "Could not locate element list.allpumpbuttons.items". All variations of list referencing that I tried throw a similar error

I am thinking if not lists, perhaps using values to accomplish this would work, but honestly I am at a loss and just need some guidance.

I have created this prototype by editing the autoBART task downloaded from Inquisit. I am providing only chunks of my script below for brevity sake, but it should make it clear how I have implemented my experiment. If more code is needed I will happily provide it.


****
Button Creation
****

<button pump1>
/ caption = "1"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 20%)
</button>

<button pump2>
/ caption = "2"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 25%)
</button>

<button pump3>
/ caption = "3"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 30%)
</button>

<button pump4>
/ caption = "4"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 35%)
</button>

<button pump5>
/ caption = "5"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 40%)
</button>

<button pump6>
/ caption = "6"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 20%)
</button>

<button pump7>
/ caption = "7"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 25%)
</button>

<button pump8>
/ caption = "8"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 30%)
</button>

<button pump9>
/ caption = "9"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 35%)
</button>

<button pump10>
/ caption = "10"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 40%)
</button>

//continues from button pump11 to button pump50//

***
List Creation
***
<list allbuttons>
/ items = (button.pump1, button.pump2, button.pump3, button.pump4, button.pump5, button.pump6, button.pump7, button.pump8, button.pump9. button.pump10,
button.pump11, button.pump12, button.pump13, button.pump14, button.pump15, button.pump16, button.pump17, button.pump18, button.pump19. button.pump20,
button.pump21, button.pump22, button.pump23, button.pump24, button.pump25, button.pump26, button.pump27, button.pump28, button.pump29. button.pump30,
button.pump31, button.pump32, button.pump33, button.pump34, button.pump35, button.pump36, button.pump37, button.pump38, button.pump39. button.pump40,
button.pump41, button.pump42, button.pump43, button.pump44, button.pump45, button.pump46, button.pump47, button.pump48, button.pump49. button.pump50)
/ replace = false
/ selectionmode = random
/ selectionrate = always
</list>

<list unselected>
/ items = (button.pump1, button.pump2, button.pump3, button.pump4, button.pump5, button.pump6, button.pump7, button.pump8, button.pump9. button.pump10,
button.pump11, button.pump12, button.pump13, button.pump14, button.pump15, button.pump16, button.pump17, button.pump18, button.pump19. button.pump20,
button.pump21, button.pump22, button.pump23, button.pump24, button.pump25, button.pump26, button.pump27, button.pump28, button.pump29. button.pump30,
button.pump31, button.pump32, button.pump33, button.pump34, button.pump35, button.pump36, button.pump37, button.pump38, button.pump39. button.pump40,
button.pump41, button.pump42, button.pump43, button.pump44, button.pump45, button.pump46, button.pump47, button.pump48, button.pump49. button.pump50)
/ replace = false
/ selectionmode = random
/ selectionrate = always
</list>

<list selected>
/ items = ()
/ replace = false
/ selectionmode = random
/ selectionrate = always
</list>

***
Trial which collects wantedpumps
***
<trial pumpinput>
/ stimulustimes = [0=balloon, totalearnings, pumpcount, potentialearnings, ballooncount, pumpcount, pumpinputinstruct1, wantedpumps;
10 = pump1, pump2, pump3, pump4, pump5,
pump6, pump7, pump8, pump9, pump10,
pump11, pump12, pump13, pump14, pump15,
pump16, pump17, pump18, pump19, pump20,
pump21, pump22, pump23, pump24, pump25,
pump26, pump27, pump28, pump29, pump30,
pump31, pump32, pump33, pump34, pump35,
pump36, pump37, pump38, pump39, pump40,
pump41, pump42, pump43, pump44, pump45,
pump46, pump47, pump48, pump49, pump50]
/ inputdevice = mouse
/ validresponse = (pump1, pump2, pump3, pump4, pump5,
pump6, pump7, pump8, pump9, pump10,
pump11, pump12, pump13, pump14, pump15,
pump16, pump17, pump18, pump19, pump20,
pump21, pump22, pump23, pump24, pump25,
pump26, pump27, pump28, pump29, pump30,
pump31, pump32, pump33, pump34, pump35,
pump36, pump37, pump38, pump39, pump40,
pump41, pump42, pump43, pump44, pump45,
pump46, pump47, pump48, pump49, pump50)
/ ontrialend = [
    values.wantedpumps = +trim(trial.pumpinput.response, "pump");
    //values.wantedpumps = trial.pumpinput.response;
    if (monkey.monkeyMode == true)
        values.wantedpumps = list.monkeyresponses.nextValue;
    if (parameters.fixed_explosionsequence == true)
        values.explosionpoint = list.fixed_explosionpoints.nextValue;
    values.timebefore1stpump = trial.pumpinput.latency;
    values.total_wantedpumps += values.wantedpumps;
    if (values.ballooncount < 11)
        values.total_wantedpumps_10 += values.wantedpumps
    else if (values.ballooncount <21 )
        values.total_wantedpumps_20 += values.wantedpumps
    else if (values.ballooncount <31 )
        values.total_wantedpumps_30 += values.wantedpumps
    ;
]    
/ branch = [
    if (values.wantedpumps > 0)
        return trial.pump;
    else
        return trial.collect;
]
/ recorddata = false
</trial>
Dave
Dave
Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)
Group: Administrators
Posts: 12K, Visits: 98K
ejn528 - 4/26/2024
I am trying to create an implementation of the Automatic Balloon Analogue Risk Task (autoBART) using buttons instead of a text box to collect responses from the participants. I am new to inquisit and have been unable to complete this task.

The goal is to have 50 buttons on the screen (representing 1-50 pumps) and allow users to select how many pumps they desire, with each selection only being available once. So if they choose 30 pumps the first trial, that button will disappear for trial 2, and this will continue as they select from the remaining buttons.


I have a prototype that works, with 50 buttons that dictate the amount of pumps for the balloon, however I am not able to take options away in subsequent trials after they have been selected. So a participant could select the same number of pumps for every trial. This is what I am trying to prevent.

I hoped the solution would be found in lists, in theory I would have 3 lists: one master list of all buttons: "list.allbuttons", one list of unselected buttons: "list.unselected", which would contain all buttons at the start of the experiment, then as each button is selected the respective button would be removed from "list.unselected", and added to the third list: "list.selected".

This is not proving to be possible for several reasons:
First, lists behavior seems to only allow for a random selection of one of the items at a time, not all of the items.
Secondly, trial /validresponse does not take a list as a valid option, giving error message: "Could not locate element list.allpumpbuttons.items". All variations of list referencing that I tried throw a similar error

I am thinking if not lists, perhaps using values to accomplish this would work, but honestly I am at a loss and just need some guidance.

I have created this prototype by editing the autoBART task downloaded from Inquisit. I am providing only chunks of my script below for brevity sake, but it should make it clear how I have implemented my experiment. If more code is needed I will happily provide it.


****
Button Creation
****

<button pump1>
/ caption = "1"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 20%)
</button>

<button pump2>
/ caption = "2"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 25%)
</button>

<button pump3>
/ caption = "3"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 30%)
</button>

<button pump4>
/ caption = "4"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 35%)
</button>

<button pump5>
/ caption = "5"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 40%)
</button>

<button pump6>
/ caption = "6"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 20%)
</button>

<button pump7>
/ caption = "7"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 25%)
</button>

<button pump8>
/ caption = "8"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 30%)
</button>

<button pump9>
/ caption = "9"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 35%)
</button>

<button pump10>
/ caption = "10"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (24%, 40%)
</button>

//continues from button pump11 to button pump50//

***
List Creation
***
<list allbuttons>
/ items = (button.pump1, button.pump2, button.pump3, button.pump4, button.pump5, button.pump6, button.pump7, button.pump8, button.pump9. button.pump10,
button.pump11, button.pump12, button.pump13, button.pump14, button.pump15, button.pump16, button.pump17, button.pump18, button.pump19. button.pump20,
button.pump21, button.pump22, button.pump23, button.pump24, button.pump25, button.pump26, button.pump27, button.pump28, button.pump29. button.pump30,
button.pump31, button.pump32, button.pump33, button.pump34, button.pump35, button.pump36, button.pump37, button.pump38, button.pump39. button.pump40,
button.pump41, button.pump42, button.pump43, button.pump44, button.pump45, button.pump46, button.pump47, button.pump48, button.pump49. button.pump50)
/ replace = false
/ selectionmode = random
/ selectionrate = always
</list>

<list unselected>
/ items = (button.pump1, button.pump2, button.pump3, button.pump4, button.pump5, button.pump6, button.pump7, button.pump8, button.pump9. button.pump10,
button.pump11, button.pump12, button.pump13, button.pump14, button.pump15, button.pump16, button.pump17, button.pump18, button.pump19. button.pump20,
button.pump21, button.pump22, button.pump23, button.pump24, button.pump25, button.pump26, button.pump27, button.pump28, button.pump29. button.pump30,
button.pump31, button.pump32, button.pump33, button.pump34, button.pump35, button.pump36, button.pump37, button.pump38, button.pump39. button.pump40,
button.pump41, button.pump42, button.pump43, button.pump44, button.pump45, button.pump46, button.pump47, button.pump48, button.pump49. button.pump50)
/ replace = false
/ selectionmode = random
/ selectionrate = always
</list>

<list selected>
/ items = ()
/ replace = false
/ selectionmode = random
/ selectionrate = always
</list>

***
Trial which collects wantedpumps
***
<trial pumpinput>
/ stimulustimes = [0=balloon, totalearnings, pumpcount, potentialearnings, ballooncount, pumpcount, pumpinputinstruct1, wantedpumps;
10 = pump1, pump2, pump3, pump4, pump5,
pump6, pump7, pump8, pump9, pump10,
pump11, pump12, pump13, pump14, pump15,
pump16, pump17, pump18, pump19, pump20,
pump21, pump22, pump23, pump24, pump25,
pump26, pump27, pump28, pump29, pump30,
pump31, pump32, pump33, pump34, pump35,
pump36, pump37, pump38, pump39, pump40,
pump41, pump42, pump43, pump44, pump45,
pump46, pump47, pump48, pump49, pump50]
/ inputdevice = mouse
/ validresponse = (pump1, pump2, pump3, pump4, pump5,
pump6, pump7, pump8, pump9, pump10,
pump11, pump12, pump13, pump14, pump15,
pump16, pump17, pump18, pump19, pump20,
pump21, pump22, pump23, pump24, pump25,
pump26, pump27, pump28, pump29, pump30,
pump31, pump32, pump33, pump34, pump35,
pump36, pump37, pump38, pump39, pump40,
pump41, pump42, pump43, pump44, pump45,
pump46, pump47, pump48, pump49, pump50)
/ ontrialend = [
    values.wantedpumps = +trim(trial.pumpinput.response, "pump");
    //values.wantedpumps = trial.pumpinput.response;
    if (monkey.monkeyMode == true)
        values.wantedpumps = list.monkeyresponses.nextValue;
    if (parameters.fixed_explosionsequence == true)
        values.explosionpoint = list.fixed_explosionpoints.nextValue;
    values.timebefore1stpump = trial.pumpinput.latency;
    values.total_wantedpumps += values.wantedpumps;
    if (values.ballooncount < 11)
        values.total_wantedpumps_10 += values.wantedpumps
    else if (values.ballooncount <21 )
        values.total_wantedpumps_20 += values.wantedpumps
    else if (values.ballooncount <31 )
        values.total_wantedpumps_30 += values.wantedpumps
    ;
]    
/ branch = [
    if (values.wantedpumps > 0)
        return trial.pump;
    else
        return trial.collect;
]
/ recorddata = false
</trial>

<button> elements are stimulus elements. You "remove" them by not displaying them on-screen in the first place, and you can use dynamically updated lists to determine which button stimuli should or should not be displayed and/or accepted as response.

<list buttonlist>
/ items = (button.pump1, button.pump2, button.pump3, button.pump4)
/ selectionrate = always
/ selectionmode = sequence
</list>

<list usedbuttons>
</list>

<button pump1>
/ caption = "1"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 20%)
</button>

<button pump2>
/ caption = "2"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 25%)
</button>

<button pump3>
/ caption = "3"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 30%)
</button>

<button pump4>
/ caption = "4"
/ fontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ size = (8%, 5%)
/ position = (16%, 35%)
</button>

<trial exampletrial>
/ ontrialbegin = [
    trial.exampletrial.resetstimulusframes();
    var i = 0;
    while (i < list.buttonlist.itemcount) {
        trial.exampletrial.insertstimulusframe(list.buttonlist.nextvalue, 1); // display all buttons contained in the list
    i += 1;
    };
]
/ ontrialend = [
    list.usedbuttons.appenditem(trial.exampletrial.response); // add the clicked button to a list for response (in)validation
    list.buttonlist.removeitem(list.buttonlist.indexof(trial.exampletrial.response)); // remove the button that was clicked from the list
]
/ inputdevice = mouse
/ validresponse = (button.pump1, button.pump2, button.pump3, button.pump4)
/ isvalidresponse = [
    list.usedbuttons.indexof(trial.exampletrial.response) == -1; // response is only valid if the button has not yet been used
]
</trial>

<block myblock>
/ trials = [1-4 = trial.exampletrial]
</block>

ejn528
ejn528
New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)
Group: Forum Members
Posts: 4, Visits: 4
Thank you so much for the quick response! I understand the logic of the code you provided, but Inquisit is throwing an error:
ERROR /ontrialbegin: '  i' Expression contains an unknown element or property name.

The error is within <trial pumpinput>, which is what controls the stimulus presentation, however the number of trials is handled through a few other blocks of code. Again, this is downloaded from Inquisit with minimal edits from me.

Here is the exact code I have that controls the entire experiment:

<trial init>
/ ontrialbegin = [
    values.pumpcount = 0;
    values.wantedpumps = 0;
    values.explosionpoint = 0;
    list.pumpresult.reset();
    values.explosion = 0;
    values.scalingFactor = 1;
]
/ stimulustimes = [0=clearScreen]
/ response = noresponse
/ ontrialend = [
    if (trial.init.trialcount <= parameters.totalballoons) {
        values.ballooncount += 1;
        if (values.ballooncount < 11) {
            values.ballooncount_10 += 1;
        } else if (values.ballooncount <21) {
            values.ballooncount_20 += 1;
        } else if (values.ballooncount <31) {
            values.ballooncount_30 += 1;
        }
    }
    shape.blank.width = values.balloonwidth;
    shape.blank.height = values.balloonheight;
]
/ branch = [return trial.pumpinput;]
/ recorddata = false
</trial>


Notes:
* provides the textbox to collect number of pumps that participant would like to pump the balloon
* determines the explosionpoint if parameters.fixed_explosionsequence == true
* updates summary variables
* calls trial.pump if that number > 0 otherwise calls trial.collect
<trial pumpinput>
/ stimulusframes = [1=balloon, totalearnings, pumpcount, potentialearnings, ballooncount, pumpcount, pumpinputinstruct1, wantedpumps]
/ inputdevice = mouse
/ ontrialbegin = [
    trial.pumpinput.resetstimulusframes();
    var i = 0;
    while (i < list.buttonlist.itemcount) {
        trial.pumpinput.insertstimulusframe(list.buttonlist.nextvalue, 1); // display all buttons contained in the list
    i += 1;
    };
]
/ ontrialend = [
  list.usedbuttons.appenditem(trial.pumpinput.response); // add the clicked button to a list for response (in)validation
    list.buttonlist.removeitem(list.buttonlist.indexof(trial.pumpinput.response)); // remove the button that was clicked from the list
    values.wantedpumps = +trim(trial.pumpinput.response, "pump");
    //values.wantedpumps = trial.pumpinput.response;
    if (monkey.monkeyMode == true)
        values.wantedpumps = list.monkeyresponses.nextValue;
    if (parameters.fixed_explosionsequence == true)
        values.explosionpoint = list.fixed_explosionpoints.nextValue;
    values.timebefore1stpump = trial.pumpinput.latency;
    values.total_wantedpumps += values.wantedpumps;
    if (values.ballooncount < 11)
        values.total_wantedpumps_10 += values.wantedpumps
    else if (values.ballooncount <21 )
        values.total_wantedpumps_20 += values.wantedpumps
    else if (values.ballooncount <31 )
        values.total_wantedpumps_30 += values.wantedpumps
    ;
]    

/ isvalidresponse = [
    list.usedbuttons.indexof(trial.pumpinput.response) == -1; // response is only valid if the button has not yet been used
]
/ branch = [
    if (values.wantedpumps > 0)
        return trial.pump;
    else
        return trial.collect;
]
/ recorddata = false
</trial>






Note:
- pumps up the balloon by increasing the balloons size and playing a pump sound
- lasts as long as indicated by parameters.pumpduration (editable value)
- determines if balloon is to pop after a pump
if yes -> calls trial.pop
if no -> determines if balloon needs to be pumped further
            if yes -> calls itself again
            if no -> calls trial.collect
<trial pump>
/ ontrialbegin = [
    if (parameters.fixed_explosionsequence == false)
        values.pumpresult = list.pumpresult.nextValue;
    values.scalingFactor += parameters.balloonsizeincrement;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
    values.pumpcount += 1;
]
/ stimulustimes = [1= balloon, totalearnings, pumpcount, potentialearnings, ballooncount, inflatesound, wantedpumps]
/ trialduration = parameters.pumpduration
/ ontrialend = [
    values.totalpumpcount += 1;
    if (values.ballooncount < 11)
        values.totalpumpcount _10 += 1
    else if (values.ballooncount > 10 && values.ballooncount <21 )
        values.totalpumpcount_20 += 1
    else if (values.ballooncount > 20 && values.ballooncount <31 )
        values.totalpumpcount_30 += 1
    ;
]
/ branch = [
    if (parameters.fixed_explosionsequence == false && values.pumpresult == 1)
        return trial.pop;
    else if (parameters.fixed_explosionsequence == true && values.pumpcount == values.explosionpoint)
        return trial.pop;
    else if (values.pumpcount == values.wantedpumps)
        return trial.collect;
    else
        return trial.pump;
]
/ recorddata = false
</trial>



Notes:
- trial explodes the balloon
- updates number of explosions
- calls trial.init for another round

<trial pop>
/ ontrialbegin = [
    values.explosion = 1;
    values.total_explosions += 1;
    if (values.ballooncount < 11)
        values.total_explosions_10 += 1
    else if (values.ballooncount <21 )
        values.total_explosions_20 += 1
    else if (values.ballooncount <31 )
        values.total_explosions_30 += 1
    ;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
]
/ stimulustimes = [1=popsound, poppedballoon, totalearnings]
/ response = noresponse
/ ontrialend = [
    values.average_wantedpumps = values.total_wantedpumps/values.ballooncount;
    if (values.ballooncount < 11)
        values.average_wantedpumps_10 = values.total_wantedpumps_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.average_wantedpumps_20 = values.total_wantedpumps_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.average_wantedpumps_30 = values.total_wantedpumps_30/values.ballooncount_30
    ;
    values.ss_wantedpumps += (values.wantedpumps * values.wantedpumps);
    values.averagepumpcount = values.totalpumpcount/values.ballooncount;
    if (values.ballooncount < 11)
        values.averagepumpcount_10 = values.totalpumpcount_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.averagepumpcount_20 = values.totalpumpcount_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.averagepumpcount_30 = values.totalpumpcount_30/values.ballooncount_30
    ;
    values.ss_pumpcount += (values.pumpcount * values.pumpcount);
    if (parameters.fixed_explosionsequence == false)
        values.explosionpoint = values.pumpcount;
]
/ branch = [return trial.summary;]
/ responseinterrupt = trial
/ recorddata = false
</trial>


Note:
- trial updates the actual winnings and the number of nonexploded balloons
- if parameters.fixed_explosionsequence == true calls trial.reveal
- if parameters.fixed_explosionsequence == false calls trial.findexplosionpoint
<trial collect>
/ ontrialbegin = [
    values.nonexplodedballoons += 1;
    if (values.ballooncount < 11)
        values.nonexplodedballoons_10 += 1
    else if (values.ballooncount <21 )
        values.nonexplodedballoons_20 += 1
    else if (values.ballooncount <31 )
        values.nonexplodedballoons_30 += 1
    ;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
    values.totalearnings = values.totalearnings + (values.pumpcount * parameters.pumpvalue);
]
/ stimulustimes = [1=collectsound, totalearnings]
/ response = noresponse

/ ontrialend = [
    values.average_wantedpumps = values.total_wantedpumps/values.ballooncount;
    if (values.ballooncount < 11)
        values.average_wantedpumps_10 = values.total_wantedpumps_10/values.ballooncount_10
    else if (values.ballooncount > 10 && values.ballooncount <21 )
        values.average_wantedpumps_20 = values.total_wantedpumps_20/values.ballooncount_20
    else if (values.ballooncount > 20 && values.ballooncount <31 )
        values.average_wantedpumps_30 = values.total_wantedpumps_30/values.ballooncount_30
    ;
    values.ss_wantedpumps += (values.wantedpumps * values.wantedpumps);
    values.averagepumpcount = values.totalpumpcount/values.ballooncount;
    if (values.ballooncount < 11)
        values.averagepumpcount_10 = values.totalpumpcount_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.averagepumpcount_20 = values.totalpumpcount_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.averagepumpcount_30 = values.totalpumpcount_30/values.ballooncount_30
    ;
    values.ss_pumpcount += (values.pumpcount * values.pumpcount);
    values.adjustedtotalpumpcount += values.pumpcount;
    if (values.ballooncount < 11)
        values.adjustedtotalpumpcount_10 += values.pumpcount
    else if (values.ballooncount <21 )
        values.adjustedtotalpumpcount_20 += values.pumpcount
    else if (values.ballooncount <31 )
        values.adjustedtotalpumpcount_30 += values.pumpcount
    ;
    values.adjustedaveragepumpcount = values.adjustedtotalpumpcount / values.nonexplodedballoons;
    if (values.ballooncount < 11)
        values.adjustedaveragepumpcount_10 = values.adjustedtotalpumpcount_10 / values.nonexplodedballoons_10
    else if (values.ballooncount <21 )
        values.adjustedaveragepumpcount_20 = values.adjustedtotalpumpcount_20 / values.nonexplodedballoons_20
    else if (values.ballooncount <31 )
        values.adjustedaveragepumpcount_30 = values.adjustedtotalpumpcount_30 / values.nonexplodedballoons_30
    ;
    values.ss_adjustedpumpcount += (values.pumpcount * values.pumpcount);
]
/ branch = [
    if (parameters.fixed_explosionsequence == false) {
        values.explosionpoint = values.pumpcount;
        return trial.findexplosionpoint;
    } else {
        if (parameters.revealexplosionpoint == true) {
            return trial.reveal;
        } else {
            return trial.summary;
        }
    }
]
/ responseinterrupt = trial
/ recorddata = false
</trial>


Notes:
- this trial is only run if parameters.fixed_explosionsequence = false (and the balloon did not pop)
as the explosion point in this case is not known beforehand
- determines the explosionpoint by sampling from list.pumpresult as long as it takes to sample the 1
- once the explosionpoint is established, calls trial.reveal if parameters.revealexplosionpoint = true,
otherwise calls trial.summary
<trial findexplosionpoint>
/ ontrialbegin = [
    values.explosionpoint += 1;
    values.pumpresult = list.pumpresult.nextValue;
]
/ branch = [
    if (values.pumpresult == 1) {
        if (parameters.revealexplosionpoint == true) {
            return trial.reveal;
        } else {
            return trial.summary;
        }
    } else {
        return trial.findexplosionpoint;
    }
]    
/ trialduration = 0
/ recorddata = false
</trial>


Notes:
- trial is only run if balloon did not pop
- reveals the explosion point of the current balloon for a set amount of time parameters.revealduration (editable value)
<trial reveal>
/ stimulusframes = [1 = clearScreen, explosionreveal]
/ timeout = parameters.revealduration
/ branch = [return trial.summary;]
/ recorddata = false
</trial>

Notes:
- purpose of this trial is to save all relevant data to the raw data file
<trial summary>
/ recorddata = true
/ trialduration = 0
/ branch = [return trial.init;]
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************
<block BART>
/ onblockbegin = [
    values.balloonwidth = 0.3 * display.width;
    values.balloonheight = 0.3 * display.height;
]
/ trials = [1-2=instructions; 3=init; 4=instructions]
/ stop = [trial.init.trialcount > parameters.totalballoons]
</block>

<block summary>
/ trials = [1= finish]
</block>


*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt BART>
/ onexptbegin = [
    if ( !parameters.showpumpcount )
        text.pumpcount.hposition = 100%;
    if ( !parameters.showballooncount )
        text.ballooncount.hposition = 100%;
    if ( !parameters.showpotentialearnings )
        text.potentialearnings.hposition = 100%;
]
/ blocks = [
    1=BART;
    2=summary;
]
</expt>
Dave
Dave
Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)
Group: Administrators
Posts: 12K, Visits: 98K
ejn528 - 4/26/2024
Thank you so much for the quick response! I understand the logic of the code you provided, but Inquisit is throwing an error:
ERROR /ontrialbegin: '  i' Expression contains an unknown element or property name.

The error is within <trial pumpinput>, which is what controls the stimulus presentation, however the number of trials is handled through a few other blocks of code. Again, this is downloaded from Inquisit with minimal edits from me.

Here is the exact code I have that controls the entire experiment:

<trial init>
/ ontrialbegin = [
    values.pumpcount = 0;
    values.wantedpumps = 0;
    values.explosionpoint = 0;
    list.pumpresult.reset();
    values.explosion = 0;
    values.scalingFactor = 1;
]
/ stimulustimes = [0=clearScreen]
/ response = noresponse
/ ontrialend = [
    if (trial.init.trialcount <= parameters.totalballoons) {
        values.ballooncount += 1;
        if (values.ballooncount < 11) {
            values.ballooncount_10 += 1;
        } else if (values.ballooncount <21) {
            values.ballooncount_20 += 1;
        } else if (values.ballooncount <31) {
            values.ballooncount_30 += 1;
        }
    }
    shape.blank.width = values.balloonwidth;
    shape.blank.height = values.balloonheight;
]
/ branch = [return trial.pumpinput;]
/ recorddata = false
</trial>


Notes:
* provides the textbox to collect number of pumps that participant would like to pump the balloon
* determines the explosionpoint if parameters.fixed_explosionsequence == true
* updates summary variables
* calls trial.pump if that number > 0 otherwise calls trial.collect
<trial pumpinput>
/ stimulusframes = [1=balloon, totalearnings, pumpcount, potentialearnings, ballooncount, pumpcount, pumpinputinstruct1, wantedpumps]
/ inputdevice = mouse
/ ontrialbegin = [
    trial.pumpinput.resetstimulusframes();
    var i = 0;
    while (i < list.buttonlist.itemcount) {
        trial.pumpinput.insertstimulusframe(list.buttonlist.nextvalue, 1); // display all buttons contained in the list
    i += 1;
    };
]
/ ontrialend = [
  list.usedbuttons.appenditem(trial.pumpinput.response); // add the clicked button to a list for response (in)validation
    list.buttonlist.removeitem(list.buttonlist.indexof(trial.pumpinput.response)); // remove the button that was clicked from the list
    values.wantedpumps = +trim(trial.pumpinput.response, "pump");
    //values.wantedpumps = trial.pumpinput.response;
    if (monkey.monkeyMode == true)
        values.wantedpumps = list.monkeyresponses.nextValue;
    if (parameters.fixed_explosionsequence == true)
        values.explosionpoint = list.fixed_explosionpoints.nextValue;
    values.timebefore1stpump = trial.pumpinput.latency;
    values.total_wantedpumps += values.wantedpumps;
    if (values.ballooncount < 11)
        values.total_wantedpumps_10 += values.wantedpumps
    else if (values.ballooncount <21 )
        values.total_wantedpumps_20 += values.wantedpumps
    else if (values.ballooncount <31 )
        values.total_wantedpumps_30 += values.wantedpumps
    ;
]    

/ isvalidresponse = [
    list.usedbuttons.indexof(trial.pumpinput.response) == -1; // response is only valid if the button has not yet been used
]
/ branch = [
    if (values.wantedpumps > 0)
        return trial.pump;
    else
        return trial.collect;
]
/ recorddata = false
</trial>






Note:
- pumps up the balloon by increasing the balloons size and playing a pump sound
- lasts as long as indicated by parameters.pumpduration (editable value)
- determines if balloon is to pop after a pump
if yes -> calls trial.pop
if no -> determines if balloon needs to be pumped further
            if yes -> calls itself again
            if no -> calls trial.collect
<trial pump>
/ ontrialbegin = [
    if (parameters.fixed_explosionsequence == false)
        values.pumpresult = list.pumpresult.nextValue;
    values.scalingFactor += parameters.balloonsizeincrement;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
    values.pumpcount += 1;
]
/ stimulustimes = [1= balloon, totalearnings, pumpcount, potentialearnings, ballooncount, inflatesound, wantedpumps]
/ trialduration = parameters.pumpduration
/ ontrialend = [
    values.totalpumpcount += 1;
    if (values.ballooncount < 11)
        values.totalpumpcount _10 += 1
    else if (values.ballooncount > 10 && values.ballooncount <21 )
        values.totalpumpcount_20 += 1
    else if (values.ballooncount > 20 && values.ballooncount <31 )
        values.totalpumpcount_30 += 1
    ;
]
/ branch = [
    if (parameters.fixed_explosionsequence == false && values.pumpresult == 1)
        return trial.pop;
    else if (parameters.fixed_explosionsequence == true && values.pumpcount == values.explosionpoint)
        return trial.pop;
    else if (values.pumpcount == values.wantedpumps)
        return trial.collect;
    else
        return trial.pump;
]
/ recorddata = false
</trial>



Notes:
- trial explodes the balloon
- updates number of explosions
- calls trial.init for another round

<trial pop>
/ ontrialbegin = [
    values.explosion = 1;
    values.total_explosions += 1;
    if (values.ballooncount < 11)
        values.total_explosions_10 += 1
    else if (values.ballooncount <21 )
        values.total_explosions_20 += 1
    else if (values.ballooncount <31 )
        values.total_explosions_30 += 1
    ;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
]
/ stimulustimes = [1=popsound, poppedballoon, totalearnings]
/ response = noresponse
/ ontrialend = [
    values.average_wantedpumps = values.total_wantedpumps/values.ballooncount;
    if (values.ballooncount < 11)
        values.average_wantedpumps_10 = values.total_wantedpumps_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.average_wantedpumps_20 = values.total_wantedpumps_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.average_wantedpumps_30 = values.total_wantedpumps_30/values.ballooncount_30
    ;
    values.ss_wantedpumps += (values.wantedpumps * values.wantedpumps);
    values.averagepumpcount = values.totalpumpcount/values.ballooncount;
    if (values.ballooncount < 11)
        values.averagepumpcount_10 = values.totalpumpcount_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.averagepumpcount_20 = values.totalpumpcount_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.averagepumpcount_30 = values.totalpumpcount_30/values.ballooncount_30
    ;
    values.ss_pumpcount += (values.pumpcount * values.pumpcount);
    if (parameters.fixed_explosionsequence == false)
        values.explosionpoint = values.pumpcount;
]
/ branch = [return trial.summary;]
/ responseinterrupt = trial
/ recorddata = false
</trial>


Note:
- trial updates the actual winnings and the number of nonexploded balloons
- if parameters.fixed_explosionsequence == true calls trial.reveal
- if parameters.fixed_explosionsequence == false calls trial.findexplosionpoint
<trial collect>
/ ontrialbegin = [
    values.nonexplodedballoons += 1;
    if (values.ballooncount < 11)
        values.nonexplodedballoons_10 += 1
    else if (values.ballooncount <21 )
        values.nonexplodedballoons_20 += 1
    else if (values.ballooncount <31 )
        values.nonexplodedballoons_30 += 1
    ;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
    values.totalearnings = values.totalearnings + (values.pumpcount * parameters.pumpvalue);
]
/ stimulustimes = [1=collectsound, totalearnings]
/ response = noresponse

/ ontrialend = [
    values.average_wantedpumps = values.total_wantedpumps/values.ballooncount;
    if (values.ballooncount < 11)
        values.average_wantedpumps_10 = values.total_wantedpumps_10/values.ballooncount_10
    else if (values.ballooncount > 10 && values.ballooncount <21 )
        values.average_wantedpumps_20 = values.total_wantedpumps_20/values.ballooncount_20
    else if (values.ballooncount > 20 && values.ballooncount <31 )
        values.average_wantedpumps_30 = values.total_wantedpumps_30/values.ballooncount_30
    ;
    values.ss_wantedpumps += (values.wantedpumps * values.wantedpumps);
    values.averagepumpcount = values.totalpumpcount/values.ballooncount;
    if (values.ballooncount < 11)
        values.averagepumpcount_10 = values.totalpumpcount_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.averagepumpcount_20 = values.totalpumpcount_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.averagepumpcount_30 = values.totalpumpcount_30/values.ballooncount_30
    ;
    values.ss_pumpcount += (values.pumpcount * values.pumpcount);
    values.adjustedtotalpumpcount += values.pumpcount;
    if (values.ballooncount < 11)
        values.adjustedtotalpumpcount_10 += values.pumpcount
    else if (values.ballooncount <21 )
        values.adjustedtotalpumpcount_20 += values.pumpcount
    else if (values.ballooncount <31 )
        values.adjustedtotalpumpcount_30 += values.pumpcount
    ;
    values.adjustedaveragepumpcount = values.adjustedtotalpumpcount / values.nonexplodedballoons;
    if (values.ballooncount < 11)
        values.adjustedaveragepumpcount_10 = values.adjustedtotalpumpcount_10 / values.nonexplodedballoons_10
    else if (values.ballooncount <21 )
        values.adjustedaveragepumpcount_20 = values.adjustedtotalpumpcount_20 / values.nonexplodedballoons_20
    else if (values.ballooncount <31 )
        values.adjustedaveragepumpcount_30 = values.adjustedtotalpumpcount_30 / values.nonexplodedballoons_30
    ;
    values.ss_adjustedpumpcount += (values.pumpcount * values.pumpcount);
]
/ branch = [
    if (parameters.fixed_explosionsequence == false) {
        values.explosionpoint = values.pumpcount;
        return trial.findexplosionpoint;
    } else {
        if (parameters.revealexplosionpoint == true) {
            return trial.reveal;
        } else {
            return trial.summary;
        }
    }
]
/ responseinterrupt = trial
/ recorddata = false
</trial>


Notes:
- this trial is only run if parameters.fixed_explosionsequence = false (and the balloon did not pop)
as the explosion point in this case is not known beforehand
- determines the explosionpoint by sampling from list.pumpresult as long as it takes to sample the 1
- once the explosionpoint is established, calls trial.reveal if parameters.revealexplosionpoint = true,
otherwise calls trial.summary
<trial findexplosionpoint>
/ ontrialbegin = [
    values.explosionpoint += 1;
    values.pumpresult = list.pumpresult.nextValue;
]
/ branch = [
    if (values.pumpresult == 1) {
        if (parameters.revealexplosionpoint == true) {
            return trial.reveal;
        } else {
            return trial.summary;
        }
    } else {
        return trial.findexplosionpoint;
    }
]    
/ trialduration = 0
/ recorddata = false
</trial>


Notes:
- trial is only run if balloon did not pop
- reveals the explosion point of the current balloon for a set amount of time parameters.revealduration (editable value)
<trial reveal>
/ stimulusframes = [1 = clearScreen, explosionreveal]
/ timeout = parameters.revealduration
/ branch = [return trial.summary;]
/ recorddata = false
</trial>

Notes:
- purpose of this trial is to save all relevant data to the raw data file
<trial summary>
/ recorddata = true
/ trialduration = 0
/ branch = [return trial.init;]
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************
<block BART>
/ onblockbegin = [
    values.balloonwidth = 0.3 * display.width;
    values.balloonheight = 0.3 * display.height;
]
/ trials = [1-2=instructions; 3=init; 4=instructions]
/ stop = [trial.init.trialcount > parameters.totalballoons]
</block>

<block summary>
/ trials = [1= finish]
</block>


*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt BART>
/ onexptbegin = [
    if ( !parameters.showpumpcount )
        text.pumpcount.hposition = 100%;
    if ( !parameters.showballooncount )
        text.ballooncount.hposition = 100%;
    if ( !parameters.showpotentialearnings )
        text.potentialearnings.hposition = 100%;
]
/ blocks = [
    1=BART;
    2=summary;
]
</expt>

If you need to provide full code, don't paste it into a post's body. Instead attach the actual script. (+Insert -> Add File)
ejn528
ejn528
New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)
Group: Forum Members
Posts: 4, Visits: 4
Dave - 4/26/2024
ejn528 - 4/26/2024
Thank you so much for the quick response! I understand the logic of the code you provided, but Inquisit is throwing an error:
ERROR /ontrialbegin: '  i' Expression contains an unknown element or property name.

The error is within <trial pumpinput>, which is what controls the stimulus presentation, however the number of trials is handled through a few other blocks of code. Again, this is downloaded from Inquisit with minimal edits from me.

Here is the exact code I have that controls the entire experiment:

<trial init>
/ ontrialbegin = [
    values.pumpcount = 0;
    values.wantedpumps = 0;
    values.explosionpoint = 0;
    list.pumpresult.reset();
    values.explosion = 0;
    values.scalingFactor = 1;
]
/ stimulustimes = [0=clearScreen]
/ response = noresponse
/ ontrialend = [
    if (trial.init.trialcount <= parameters.totalballoons) {
        values.ballooncount += 1;
        if (values.ballooncount < 11) {
            values.ballooncount_10 += 1;
        } else if (values.ballooncount <21) {
            values.ballooncount_20 += 1;
        } else if (values.ballooncount <31) {
            values.ballooncount_30 += 1;
        }
    }
    shape.blank.width = values.balloonwidth;
    shape.blank.height = values.balloonheight;
]
/ branch = [return trial.pumpinput;]
/ recorddata = false
</trial>


Notes:
* provides the textbox to collect number of pumps that participant would like to pump the balloon
* determines the explosionpoint if parameters.fixed_explosionsequence == true
* updates summary variables
* calls trial.pump if that number > 0 otherwise calls trial.collect
<trial pumpinput>
/ stimulusframes = [1=balloon, totalearnings, pumpcount, potentialearnings, ballooncount, pumpcount, pumpinputinstruct1, wantedpumps]
/ inputdevice = mouse
/ ontrialbegin = [
    trial.pumpinput.resetstimulusframes();
    var i = 0;
    while (i < list.buttonlist.itemcount) {
        trial.pumpinput.insertstimulusframe(list.buttonlist.nextvalue, 1); // display all buttons contained in the list
    i += 1;
    };
]
/ ontrialend = [
  list.usedbuttons.appenditem(trial.pumpinput.response); // add the clicked button to a list for response (in)validation
    list.buttonlist.removeitem(list.buttonlist.indexof(trial.pumpinput.response)); // remove the button that was clicked from the list
    values.wantedpumps = +trim(trial.pumpinput.response, "pump");
    //values.wantedpumps = trial.pumpinput.response;
    if (monkey.monkeyMode == true)
        values.wantedpumps = list.monkeyresponses.nextValue;
    if (parameters.fixed_explosionsequence == true)
        values.explosionpoint = list.fixed_explosionpoints.nextValue;
    values.timebefore1stpump = trial.pumpinput.latency;
    values.total_wantedpumps += values.wantedpumps;
    if (values.ballooncount < 11)
        values.total_wantedpumps_10 += values.wantedpumps
    else if (values.ballooncount <21 )
        values.total_wantedpumps_20 += values.wantedpumps
    else if (values.ballooncount <31 )
        values.total_wantedpumps_30 += values.wantedpumps
    ;
]    

/ isvalidresponse = [
    list.usedbuttons.indexof(trial.pumpinput.response) == -1; // response is only valid if the button has not yet been used
]
/ branch = [
    if (values.wantedpumps > 0)
        return trial.pump;
    else
        return trial.collect;
]
/ recorddata = false
</trial>






Note:
- pumps up the balloon by increasing the balloons size and playing a pump sound
- lasts as long as indicated by parameters.pumpduration (editable value)
- determines if balloon is to pop after a pump
if yes -> calls trial.pop
if no -> determines if balloon needs to be pumped further
            if yes -> calls itself again
            if no -> calls trial.collect
<trial pump>
/ ontrialbegin = [
    if (parameters.fixed_explosionsequence == false)
        values.pumpresult = list.pumpresult.nextValue;
    values.scalingFactor += parameters.balloonsizeincrement;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
    values.pumpcount += 1;
]
/ stimulustimes = [1= balloon, totalearnings, pumpcount, potentialearnings, ballooncount, inflatesound, wantedpumps]
/ trialduration = parameters.pumpduration
/ ontrialend = [
    values.totalpumpcount += 1;
    if (values.ballooncount < 11)
        values.totalpumpcount _10 += 1
    else if (values.ballooncount > 10 && values.ballooncount <21 )
        values.totalpumpcount_20 += 1
    else if (values.ballooncount > 20 && values.ballooncount <31 )
        values.totalpumpcount_30 += 1
    ;
]
/ branch = [
    if (parameters.fixed_explosionsequence == false && values.pumpresult == 1)
        return trial.pop;
    else if (parameters.fixed_explosionsequence == true && values.pumpcount == values.explosionpoint)
        return trial.pop;
    else if (values.pumpcount == values.wantedpumps)
        return trial.collect;
    else
        return trial.pump;
]
/ recorddata = false
</trial>



Notes:
- trial explodes the balloon
- updates number of explosions
- calls trial.init for another round

<trial pop>
/ ontrialbegin = [
    values.explosion = 1;
    values.total_explosions += 1;
    if (values.ballooncount < 11)
        values.total_explosions_10 += 1
    else if (values.ballooncount <21 )
        values.total_explosions_20 += 1
    else if (values.ballooncount <31 )
        values.total_explosions_30 += 1
    ;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
]
/ stimulustimes = [1=popsound, poppedballoon, totalearnings]
/ response = noresponse
/ ontrialend = [
    values.average_wantedpumps = values.total_wantedpumps/values.ballooncount;
    if (values.ballooncount < 11)
        values.average_wantedpumps_10 = values.total_wantedpumps_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.average_wantedpumps_20 = values.total_wantedpumps_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.average_wantedpumps_30 = values.total_wantedpumps_30/values.ballooncount_30
    ;
    values.ss_wantedpumps += (values.wantedpumps * values.wantedpumps);
    values.averagepumpcount = values.totalpumpcount/values.ballooncount;
    if (values.ballooncount < 11)
        values.averagepumpcount_10 = values.totalpumpcount_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.averagepumpcount_20 = values.totalpumpcount_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.averagepumpcount_30 = values.totalpumpcount_30/values.ballooncount_30
    ;
    values.ss_pumpcount += (values.pumpcount * values.pumpcount);
    if (parameters.fixed_explosionsequence == false)
        values.explosionpoint = values.pumpcount;
]
/ branch = [return trial.summary;]
/ responseinterrupt = trial
/ recorddata = false
</trial>


Note:
- trial updates the actual winnings and the number of nonexploded balloons
- if parameters.fixed_explosionsequence == true calls trial.reveal
- if parameters.fixed_explosionsequence == false calls trial.findexplosionpoint
<trial collect>
/ ontrialbegin = [
    values.nonexplodedballoons += 1;
    if (values.ballooncount < 11)
        values.nonexplodedballoons_10 += 1
    else if (values.ballooncount <21 )
        values.nonexplodedballoons_20 += 1
    else if (values.ballooncount <31 )
        values.nonexplodedballoons_30 += 1
    ;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
    values.totalearnings = values.totalearnings + (values.pumpcount * parameters.pumpvalue);
]
/ stimulustimes = [1=collectsound, totalearnings]
/ response = noresponse

/ ontrialend = [
    values.average_wantedpumps = values.total_wantedpumps/values.ballooncount;
    if (values.ballooncount < 11)
        values.average_wantedpumps_10 = values.total_wantedpumps_10/values.ballooncount_10
    else if (values.ballooncount > 10 && values.ballooncount <21 )
        values.average_wantedpumps_20 = values.total_wantedpumps_20/values.ballooncount_20
    else if (values.ballooncount > 20 && values.ballooncount <31 )
        values.average_wantedpumps_30 = values.total_wantedpumps_30/values.ballooncount_30
    ;
    values.ss_wantedpumps += (values.wantedpumps * values.wantedpumps);
    values.averagepumpcount = values.totalpumpcount/values.ballooncount;
    if (values.ballooncount < 11)
        values.averagepumpcount_10 = values.totalpumpcount_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.averagepumpcount_20 = values.totalpumpcount_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.averagepumpcount_30 = values.totalpumpcount_30/values.ballooncount_30
    ;
    values.ss_pumpcount += (values.pumpcount * values.pumpcount);
    values.adjustedtotalpumpcount += values.pumpcount;
    if (values.ballooncount < 11)
        values.adjustedtotalpumpcount_10 += values.pumpcount
    else if (values.ballooncount <21 )
        values.adjustedtotalpumpcount_20 += values.pumpcount
    else if (values.ballooncount <31 )
        values.adjustedtotalpumpcount_30 += values.pumpcount
    ;
    values.adjustedaveragepumpcount = values.adjustedtotalpumpcount / values.nonexplodedballoons;
    if (values.ballooncount < 11)
        values.adjustedaveragepumpcount_10 = values.adjustedtotalpumpcount_10 / values.nonexplodedballoons_10
    else if (values.ballooncount <21 )
        values.adjustedaveragepumpcount_20 = values.adjustedtotalpumpcount_20 / values.nonexplodedballoons_20
    else if (values.ballooncount <31 )
        values.adjustedaveragepumpcount_30 = values.adjustedtotalpumpcount_30 / values.nonexplodedballoons_30
    ;
    values.ss_adjustedpumpcount += (values.pumpcount * values.pumpcount);
]
/ branch = [
    if (parameters.fixed_explosionsequence == false) {
        values.explosionpoint = values.pumpcount;
        return trial.findexplosionpoint;
    } else {
        if (parameters.revealexplosionpoint == true) {
            return trial.reveal;
        } else {
            return trial.summary;
        }
    }
]
/ responseinterrupt = trial
/ recorddata = false
</trial>


Notes:
- this trial is only run if parameters.fixed_explosionsequence = false (and the balloon did not pop)
as the explosion point in this case is not known beforehand
- determines the explosionpoint by sampling from list.pumpresult as long as it takes to sample the 1
- once the explosionpoint is established, calls trial.reveal if parameters.revealexplosionpoint = true,
otherwise calls trial.summary
<trial findexplosionpoint>
/ ontrialbegin = [
    values.explosionpoint += 1;
    values.pumpresult = list.pumpresult.nextValue;
]
/ branch = [
    if (values.pumpresult == 1) {
        if (parameters.revealexplosionpoint == true) {
            return trial.reveal;
        } else {
            return trial.summary;
        }
    } else {
        return trial.findexplosionpoint;
    }
]    
/ trialduration = 0
/ recorddata = false
</trial>


Notes:
- trial is only run if balloon did not pop
- reveals the explosion point of the current balloon for a set amount of time parameters.revealduration (editable value)
<trial reveal>
/ stimulusframes = [1 = clearScreen, explosionreveal]
/ timeout = parameters.revealduration
/ branch = [return trial.summary;]
/ recorddata = false
</trial>

Notes:
- purpose of this trial is to save all relevant data to the raw data file
<trial summary>
/ recorddata = true
/ trialduration = 0
/ branch = [return trial.init;]
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************
<block BART>
/ onblockbegin = [
    values.balloonwidth = 0.3 * display.width;
    values.balloonheight = 0.3 * display.height;
]
/ trials = [1-2=instructions; 3=init; 4=instructions]
/ stop = [trial.init.trialcount > parameters.totalballoons]
</block>

<block summary>
/ trials = [1= finish]
</block>


*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt BART>
/ onexptbegin = [
    if ( !parameters.showpumpcount )
        text.pumpcount.hposition = 100%;
    if ( !parameters.showballooncount )
        text.ballooncount.hposition = 100%;
    if ( !parameters.showpotentialearnings )
        text.potentialearnings.hposition = 100%;
]
/ blocks = [
    1=BART;
    2=summary;
]
</expt>

If you need to provide full code, don't paste it into a post's body. Instead attach the actual script. (+Insert -> Add File)

Ah, thanks for the tip. Here is the actual script attached. Thanks!!

Attachments
autoBART forced pumps.iqx (13 views, 52.00 KB)
Dave
Dave
Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)
Group: Administrators
Posts: 12K, Visits: 98K
ejn528 - 4/26/2024
Dave - 4/26/2024
ejn528 - 4/26/2024
Thank you so much for the quick response! I understand the logic of the code you provided, but Inquisit is throwing an error:
ERROR /ontrialbegin: '  i' Expression contains an unknown element or property name.

The error is within <trial pumpinput>, which is what controls the stimulus presentation, however the number of trials is handled through a few other blocks of code. Again, this is downloaded from Inquisit with minimal edits from me.

Here is the exact code I have that controls the entire experiment:

<trial init>
/ ontrialbegin = [
    values.pumpcount = 0;
    values.wantedpumps = 0;
    values.explosionpoint = 0;
    list.pumpresult.reset();
    values.explosion = 0;
    values.scalingFactor = 1;
]
/ stimulustimes = [0=clearScreen]
/ response = noresponse
/ ontrialend = [
    if (trial.init.trialcount <= parameters.totalballoons) {
        values.ballooncount += 1;
        if (values.ballooncount < 11) {
            values.ballooncount_10 += 1;
        } else if (values.ballooncount <21) {
            values.ballooncount_20 += 1;
        } else if (values.ballooncount <31) {
            values.ballooncount_30 += 1;
        }
    }
    shape.blank.width = values.balloonwidth;
    shape.blank.height = values.balloonheight;
]
/ branch = [return trial.pumpinput;]
/ recorddata = false
</trial>


Notes:
* provides the textbox to collect number of pumps that participant would like to pump the balloon
* determines the explosionpoint if parameters.fixed_explosionsequence == true
* updates summary variables
* calls trial.pump if that number > 0 otherwise calls trial.collect
<trial pumpinput>
/ stimulusframes = [1=balloon, totalearnings, pumpcount, potentialearnings, ballooncount, pumpcount, pumpinputinstruct1, wantedpumps]
/ inputdevice = mouse
/ ontrialbegin = [
    trial.pumpinput.resetstimulusframes();
    var i = 0;
    while (i < list.buttonlist.itemcount) {
        trial.pumpinput.insertstimulusframe(list.buttonlist.nextvalue, 1); // display all buttons contained in the list
    i += 1;
    };
]
/ ontrialend = [
  list.usedbuttons.appenditem(trial.pumpinput.response); // add the clicked button to a list for response (in)validation
    list.buttonlist.removeitem(list.buttonlist.indexof(trial.pumpinput.response)); // remove the button that was clicked from the list
    values.wantedpumps = +trim(trial.pumpinput.response, "pump");
    //values.wantedpumps = trial.pumpinput.response;
    if (monkey.monkeyMode == true)
        values.wantedpumps = list.monkeyresponses.nextValue;
    if (parameters.fixed_explosionsequence == true)
        values.explosionpoint = list.fixed_explosionpoints.nextValue;
    values.timebefore1stpump = trial.pumpinput.latency;
    values.total_wantedpumps += values.wantedpumps;
    if (values.ballooncount < 11)
        values.total_wantedpumps_10 += values.wantedpumps
    else if (values.ballooncount <21 )
        values.total_wantedpumps_20 += values.wantedpumps
    else if (values.ballooncount <31 )
        values.total_wantedpumps_30 += values.wantedpumps
    ;
]    

/ isvalidresponse = [
    list.usedbuttons.indexof(trial.pumpinput.response) == -1; // response is only valid if the button has not yet been used
]
/ branch = [
    if (values.wantedpumps > 0)
        return trial.pump;
    else
        return trial.collect;
]
/ recorddata = false
</trial>






Note:
- pumps up the balloon by increasing the balloons size and playing a pump sound
- lasts as long as indicated by parameters.pumpduration (editable value)
- determines if balloon is to pop after a pump
if yes -> calls trial.pop
if no -> determines if balloon needs to be pumped further
            if yes -> calls itself again
            if no -> calls trial.collect
<trial pump>
/ ontrialbegin = [
    if (parameters.fixed_explosionsequence == false)
        values.pumpresult = list.pumpresult.nextValue;
    values.scalingFactor += parameters.balloonsizeincrement;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
    values.pumpcount += 1;
]
/ stimulustimes = [1= balloon, totalearnings, pumpcount, potentialearnings, ballooncount, inflatesound, wantedpumps]
/ trialduration = parameters.pumpduration
/ ontrialend = [
    values.totalpumpcount += 1;
    if (values.ballooncount < 11)
        values.totalpumpcount _10 += 1
    else if (values.ballooncount > 10 && values.ballooncount <21 )
        values.totalpumpcount_20 += 1
    else if (values.ballooncount > 20 && values.ballooncount <31 )
        values.totalpumpcount_30 += 1
    ;
]
/ branch = [
    if (parameters.fixed_explosionsequence == false && values.pumpresult == 1)
        return trial.pop;
    else if (parameters.fixed_explosionsequence == true && values.pumpcount == values.explosionpoint)
        return trial.pop;
    else if (values.pumpcount == values.wantedpumps)
        return trial.collect;
    else
        return trial.pump;
]
/ recorddata = false
</trial>



Notes:
- trial explodes the balloon
- updates number of explosions
- calls trial.init for another round

<trial pop>
/ ontrialbegin = [
    values.explosion = 1;
    values.total_explosions += 1;
    if (values.ballooncount < 11)
        values.total_explosions_10 += 1
    else if (values.ballooncount <21 )
        values.total_explosions_20 += 1
    else if (values.ballooncount <31 )
        values.total_explosions_30 += 1
    ;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
]
/ stimulustimes = [1=popsound, poppedballoon, totalearnings]
/ response = noresponse
/ ontrialend = [
    values.average_wantedpumps = values.total_wantedpumps/values.ballooncount;
    if (values.ballooncount < 11)
        values.average_wantedpumps_10 = values.total_wantedpumps_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.average_wantedpumps_20 = values.total_wantedpumps_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.average_wantedpumps_30 = values.total_wantedpumps_30/values.ballooncount_30
    ;
    values.ss_wantedpumps += (values.wantedpumps * values.wantedpumps);
    values.averagepumpcount = values.totalpumpcount/values.ballooncount;
    if (values.ballooncount < 11)
        values.averagepumpcount_10 = values.totalpumpcount_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.averagepumpcount_20 = values.totalpumpcount_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.averagepumpcount_30 = values.totalpumpcount_30/values.ballooncount_30
    ;
    values.ss_pumpcount += (values.pumpcount * values.pumpcount);
    if (parameters.fixed_explosionsequence == false)
        values.explosionpoint = values.pumpcount;
]
/ branch = [return trial.summary;]
/ responseinterrupt = trial
/ recorddata = false
</trial>


Note:
- trial updates the actual winnings and the number of nonexploded balloons
- if parameters.fixed_explosionsequence == true calls trial.reveal
- if parameters.fixed_explosionsequence == false calls trial.findexplosionpoint
<trial collect>
/ ontrialbegin = [
    values.nonexplodedballoons += 1;
    if (values.ballooncount < 11)
        values.nonexplodedballoons_10 += 1
    else if (values.ballooncount <21 )
        values.nonexplodedballoons_20 += 1
    else if (values.ballooncount <31 )
        values.nonexplodedballoons_30 += 1
    ;
    shape.blank.width = picture.balloon.width;
    shape.blank.height = picture.balloon.height;
    values.totalearnings = values.totalearnings + (values.pumpcount * parameters.pumpvalue);
]
/ stimulustimes = [1=collectsound, totalearnings]
/ response = noresponse

/ ontrialend = [
    values.average_wantedpumps = values.total_wantedpumps/values.ballooncount;
    if (values.ballooncount < 11)
        values.average_wantedpumps_10 = values.total_wantedpumps_10/values.ballooncount_10
    else if (values.ballooncount > 10 && values.ballooncount <21 )
        values.average_wantedpumps_20 = values.total_wantedpumps_20/values.ballooncount_20
    else if (values.ballooncount > 20 && values.ballooncount <31 )
        values.average_wantedpumps_30 = values.total_wantedpumps_30/values.ballooncount_30
    ;
    values.ss_wantedpumps += (values.wantedpumps * values.wantedpumps);
    values.averagepumpcount = values.totalpumpcount/values.ballooncount;
    if (values.ballooncount < 11)
        values.averagepumpcount_10 = values.totalpumpcount_10/values.ballooncount_10
    else if (values.ballooncount <21 )
        values.averagepumpcount_20 = values.totalpumpcount_20/values.ballooncount_20
    else if (values.ballooncount <31 )
        values.averagepumpcount_30 = values.totalpumpcount_30/values.ballooncount_30
    ;
    values.ss_pumpcount += (values.pumpcount * values.pumpcount);
    values.adjustedtotalpumpcount += values.pumpcount;
    if (values.ballooncount < 11)
        values.adjustedtotalpumpcount_10 += values.pumpcount
    else if (values.ballooncount <21 )
        values.adjustedtotalpumpcount_20 += values.pumpcount
    else if (values.ballooncount <31 )
        values.adjustedtotalpumpcount_30 += values.pumpcount
    ;
    values.adjustedaveragepumpcount = values.adjustedtotalpumpcount / values.nonexplodedballoons;
    if (values.ballooncount < 11)
        values.adjustedaveragepumpcount_10 = values.adjustedtotalpumpcount_10 / values.nonexplodedballoons_10
    else if (values.ballooncount <21 )
        values.adjustedaveragepumpcount_20 = values.adjustedtotalpumpcount_20 / values.nonexplodedballoons_20
    else if (values.ballooncount <31 )
        values.adjustedaveragepumpcount_30 = values.adjustedtotalpumpcount_30 / values.nonexplodedballoons_30
    ;
    values.ss_adjustedpumpcount += (values.pumpcount * values.pumpcount);
]
/ branch = [
    if (parameters.fixed_explosionsequence == false) {
        values.explosionpoint = values.pumpcount;
        return trial.findexplosionpoint;
    } else {
        if (parameters.revealexplosionpoint == true) {
            return trial.reveal;
        } else {
            return trial.summary;
        }
    }
]
/ responseinterrupt = trial
/ recorddata = false
</trial>


Notes:
- this trial is only run if parameters.fixed_explosionsequence = false (and the balloon did not pop)
as the explosion point in this case is not known beforehand
- determines the explosionpoint by sampling from list.pumpresult as long as it takes to sample the 1
- once the explosionpoint is established, calls trial.reveal if parameters.revealexplosionpoint = true,
otherwise calls trial.summary
<trial findexplosionpoint>
/ ontrialbegin = [
    values.explosionpoint += 1;
    values.pumpresult = list.pumpresult.nextValue;
]
/ branch = [
    if (values.pumpresult == 1) {
        if (parameters.revealexplosionpoint == true) {
            return trial.reveal;
        } else {
            return trial.summary;
        }
    } else {
        return trial.findexplosionpoint;
    }
]    
/ trialduration = 0
/ recorddata = false
</trial>


Notes:
- trial is only run if balloon did not pop
- reveals the explosion point of the current balloon for a set amount of time parameters.revealduration (editable value)
<trial reveal>
/ stimulusframes = [1 = clearScreen, explosionreveal]
/ timeout = parameters.revealduration
/ branch = [return trial.summary;]
/ recorddata = false
</trial>

Notes:
- purpose of this trial is to save all relevant data to the raw data file
<trial summary>
/ recorddata = true
/ trialduration = 0
/ branch = [return trial.init;]
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************
<block BART>
/ onblockbegin = [
    values.balloonwidth = 0.3 * display.width;
    values.balloonheight = 0.3 * display.height;
]
/ trials = [1-2=instructions; 3=init; 4=instructions]
/ stop = [trial.init.trialcount > parameters.totalballoons]
</block>

<block summary>
/ trials = [1= finish]
</block>


*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt BART>
/ onexptbegin = [
    if ( !parameters.showpumpcount )
        text.pumpcount.hposition = 100%;
    if ( !parameters.showballooncount )
        text.ballooncount.hposition = 100%;
    if ( !parameters.showpotentialearnings )
        text.potentialearnings.hposition = 100%;
]
/ blocks = [
    1=BART;
    2=summary;
]
</expt>

If you need to provide full code, don't paste it into a post's body. Instead attach the actual script. (+Insert -> Add File)

Ah, thanks for the tip. Here is the actual script attached. Thanks!!

In Inquisit Lab, open the script and select Script -> Show Whitespace.

Scroll down to the section that throws the error.



Then fix the indentation, i.e. use tabs, not spaces.


ejn528
ejn528
New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)
Group: Forum Members
Posts: 4, Visits: 4
Incredible! I feel a bit foolish about the last part haha, but thank you for sticking with me.

It works as expected now. You're a legend Dave!
AKrishna
AKrishna
Distinguished Member (3.2K reputation)Distinguished Member (3.2K reputation)Distinguished Member (3.2K reputation)Distinguished Member (3.2K reputation)Distinguished Member (3.2K reputation)Distinguished Member (3.2K reputation)Distinguished Member (3.2K reputation)Distinguished Member (3.2K reputation)Distinguished Member (3.2K reputation)
Group: Forum Members
Posts: 93, Visits: 283
...I just learned you can run a while loop in an /ontrialbegin statement from this thread. And apparently declare a temporary variable. This makes a lot of things SO MUCH more elegant.

Thanks Dave!

GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Reading This Topic

Explore
Messages
Mentions
Search