Experiment flow for reference:
The Popup_Loop is a conditional loop (it only runs if a variable equals 1 on a trial) and everything about it works fine. On the “Email” routine, I have a keyboard response after an image is shown, and then a code component that evaluates if the Popup_Loop should run. This is what that code looks like currently:
I need to add to that code additional conditions for running the Popup_Loop. What I need to happen is that on trials where Popup_Presence=1, if participants hit a key to respond to the picture, or if 2 seconds passes with no response, the Popup_Loop needs to be skipped.
On trials where Popup_Presence=0, participants need to be able to hit a key at any time to end the routine.
Basically what I’m trying to achieve is the following:
- If Popup_Presence=1 and a key is hit within 2 seconds, don’t run Popup_Loop
- If Popup_Presence=1 and 2 seconds passes with no response, run Popup_Loop immediately
- If Popup_Presence=0, skip Popup_Loop and allow response at any time (response will then end the routine)
I don’t know the proper Python “terms” to make this code component
Any help is greatly appreciated!
Update:
I have been working on this, and so far no luck still. This is the most recent thing I’ve tried:
I have a feeling I’m using the wrong thing for my keyboard variable. My keyboard response is called ‘Email_Response’. I also don’t know if “None” is the proper term for no response.
I also don’t know if I’m doing the time check correctly.
With this level of complexity I’d advise starting with pseudo-code! I think you have if
s and elif
s contradicting one another; if ‘Popup_presence’ is 1, then the elif
won’t run, so having Popup_presence == 1
as a condition for the elif
means it’ll never run.
With regard to checking whether there has been a response, a cool aspect of Python is that if you supply a non-boolean argument to an if loop, it will convert to boolean based on whether or not it is empty. So if Email_response.keys
is essentially the same as if Email_response.keys == []
or if len(Email_response.keys) == 0
. If there’s not been a response, then Email_response.keys
will be empty.
Based on what you wrote, you’d want something like this in Each Frame
:
if Popup_Presence==1 and t >= 2 and not Email_response.keys: # If Popup_Presence is 1 and 2 seconds pass with no response...
# Run Popup_Loop immediately
elif Popup_Presence==1 and Email_response.keys: # If Popup_Presence is 1 and a key is hit within 2 seconds...
# Don't run Popup_Loop
elif Popup_Presence==0 # If Popup_Presence is 0...
# Skip Popup_Loop...
if Email_response.keys # ...and allow response at any time, a response will then...
# End the routine
So filling in the loops with actions now, you seem to already have most of what you need. Like in your example, you could do:
if Popup_Presence==1 and t >= 2 and not Email_response.keys: # If Popup_Presence is 1 and 2 seconds pass with no response...
nRepsPopupLoop = 1 # Run Popup_Loop...
continueRoutine = False # ...immediately
elif Popup_Presence==1 and Email_response.keys: # If Popup_Presence is 1 and a key is hit within 2 seconds...
nRepsPopupLoop = 0 # Don't run Popup_Loop
elif Popup_Presence==0 # If Popup_Presence is 0...
nRepsPopupLoop = 0 # Skip Popup_Loop...
if Email_response.keys # ...and allow response at any time, a response will then...
continueRoutine = False # End the routine
Is this pretty much what you want it to do? Jon pointed out something else helpful this morning - anything which involves crashing out of a loop may not work directly in JavaScript just due to differences in the languages. Rather than having it set to Auto-JS
you may be better off coding in both
and then making alterations to the JS script. I’m mostly involved with the Python side of things but I think @apitiot has added a JS function which can end a loop safely.
Thank you so much!! With 0 coding experience, I was thinking I was somewhere on the right track, but had no idea how to get to where I needed to go. I think what you detailed is exactly what I need to happen. I assume this needs to be in the ‘each frame’ section since it deals with time, is that correct?
I will test this online and see if it needs to be written in JS as well, thank you for the suggestion! If it needs to be coded in both, do I use the ‘Both’ code type and write one below the other in the same code space?
Great, glad I could help! Yes, it needs to go in Each Frame
- as it will then be continuously checking for a response rather than checking once at the end of the routine. And yep, Both
is the option you want - that way you can have different JS and Python code in each side, one won’t override the other.
Perfect, thank you so much!!