When attempting to use data from a Form component e.g., form[1].response, I’m just getting errors about the Form object not being subscriptable. Any suggestions how to get around this?
(I’m essentially trying to get a simple “if any of the form responses >0, do this” sorted.)
The form component has an attribute called getData() - see Forms API. This brings up not only the data but also the form’s attributes. The format of the output seems to be an ordered dictionary within a list where one list is one question of the form.
To get the response value from getData(), in a code component end of routine tab type the below where form is then mane of the form component.
for k, v in enumerate(form.getData()): # loop through each list
for key, value in v.items(): # loop though each dictionary
if key == 'response':
if value > 0:
# do something
Note, if you attempt to print the above to the stdout, rather confusingly only prints the response to the first question only but in the background all responses are saved at the end of the routine.
Thanks for getting back to me and sincere apologies for not responding for so long!
Following your indication that the form.data is a list of dicts, I have been trying to access the ‘response’ key/value by getting the data:
consent_formList = consent_form.getData()
Then attempting to check it:
if consent_formList[2]['response'] == 1.0 \
or consent_formList[3]['response'] == 1.0 \
or consent_formList[4]['response'] == 1.0 \
or consent_formList[5]['response'] == 1.0 \
or consent_formList[6]['response'] == 1.0 :
dataCollection.finished = True
I’ve tried this and specifying the values as strings, defining variables for each of the values first (e.g., q6 = consent_formList[6]['response'] and then using that variable in the if statement, and probably other nonsensical things, but couldn’t get the experiment to end when any/all of those values were 1.0. I confirmed that these values were being fetched and stored by printing them too (though printing didn’t happen at the time the code was executed, usually at the end of the experiment instead).
I then tried just continueRoutine = False to see if it was even working and that worked as expected, leading me to think that it’s the loop exit code that’s not working somehow. So I tried currentLoop.finished = True as well, but that didn’t work either…
I’m now at a loss again.
All I want to do is essentially skip to the last routine if any of the form responses are 1.0.
Sorry to bump, but does anyone have any ideas? It seems that what I’ve done is fetching and storing the response value and checking it results in the correct output, but the loop just won’t be exited based on that data (continueRoutine = False, however, does work to exit a routine).
I’m now thinking it might not be anything to do with the form component or data, but still don’t know why I can’t exit the loop…
And if this is the case (that it’s because the finished attribute is only evaluated at the very start of the loop), how do I exit the loop on the first (and only) rep after it has started? I’ve tried using code in the Each frame tab, but not been successful there either.
Hi @PsyTechMMU, could you show a screenshot of your flow? From what you write it sounds like you want to skip/end the “data collection” if the consent form is not agreed to, right? I am wondering why the form is in a loop at all. Could you explain?
The consent form component is in the Consent routine and my last attempts to get this working are in the consentChecker routine, which is the first routine in the dataCollection loop (this contains many routines that needs to be skipped). The loop is followed by just a Debrief routine (to which we want to skip to if full consent is not obtained).
Hope that makes sense! This is how a student has explicitly stated they need it to work. Please feel free to ask any other questions or make any other suggestions.
I think the easiest solution would be to set the number of repetitions of this loop to 1 or 0 depending on your condition (consent is given / not given):
End routine
if YourCondition:
DoDatacollection = 1
else:
DoDatacollection = 0
and then use $DoDatacollection in the “number of repetitions” field of your loop.