In my experiment, I have 10 trials, and at each trial, the participant has to press a key (“space”) asap after seeing a change of colour in the animation. As feedback that confirms the key pressing, I’d like to move to the next trial (move to the next loop iteration) after the key was pressed. I tried to implement the idea in my code with break and continue, but it doesn’t work:
for i in range(nTrials):
# Start with fixation cross
fixation.draw()
win.flip()
core.wait(2)
# Play the video for 200 frames
for Nframes in range(200):
optic_flow_movie.draw()
fixation.draw()
win.flip()
# Get Participants responses
keys = psychopy.event.getKeys(keyList=["space"],timeStamped=clock)
if (keys[0][0] == 'space') is True:
break
else:
continue
# Take only the timestamps from the variable key and store it in the variable RTs
RTs = [sublist[1:2] for sublist in keys] # This stores only the timestamps
RTs = [item for sublist in RTs for item in sublist] # This converts from list of lists to a flat list
Disclaimer: This answer assumes you’re not trying to run your study online.
What do you mean by
Is your issue that you cannot terminate the loop by pressing space?
You could use the line
if 'space' in keys:
break
instead of
if (keys[0][0] == 'space') is True:
break
else:
continue
because continue is redundant, if that is the last line in your loop. continue would only be important if you have some lines at the end of your loop which you want to skip by “continuing” to the next iteration of your loop.
Why are you indexing the keys array in this way keys[0][0]?
I didn’t check and you could well be right, but the documentation of psychopy.event.getKeys says nothing of nested lists. If my hunch is right keys[0][0] might return ‘s’ instad of ‘space’ if the participant spressed space, because the first item in the list would be “space”, and the first item of this string would be “s”.
Some other observations:
Are you sure, you don’t want to check for “escape” key presses? There is no way to terminate your experiment in that loop.
If you want to terminate the optic_flow_movie with a space press, then you’re checking for space at the wrong place in your script. You have a nested loop with in your trials loop and you’re only checking for space at the end of each trial.
There is a new way of checking for key presses, which has better timing (if timing is important for you): Keyboard — PsychoPy v2023.2.3
The problem comes from the fact that my if condition was inside the trial loop instead of the drawing loop. I used the new checking for key presses also, and here is the solution:
from psychopy.hardware import keyboard
for i in range(nTrials):
kb.clock.reset() # when you want to start the timer from
# Start with fixation cross
fixation.draw()
win.flip()
core.wait(2)
# Play the video for 200 frames
for Nframes in range(200):
optic_flow_movie.draw()
fixation.draw()
win.flip()
# While the video is played, check if participant presses 'space' key and get the RT
keys = kb.getKeys(['space'], waitRelease=True)
if 'space' in keys:
break
# Save the RT of the current trial in the variable RT
for key in keys:
RT = key.rt
However, by using the Keyboard class, I got the following warnings:
1.4501 WARNING Import Error: No module named ‘psychtoolbox’. Using event module for keyboard component.
and
2.5451 WARNING PTB audio lib was requested but not loaded: psychtoolbox audio failed to import
I’m glad we found the source of your problem
Please mark my answer as the solution, if everything works now.
Regarding your ImportError: How did you install PsychoPy (are you using the standalone version), what version are you using and what is your operating system? The new keyboard class (from psychopy.hardware) depends on the Psychtoolbox (ptb) package. There was an issue with older versions of PsychoPy, where ptb was not part of the standalone installation on windows (see here).
My suggestion of using the new keyboard class was just an optimisation. If you’re having problems, you can revert to using the psychopy.event.getKeys function and everything should run without problems. From the warnings it appears that Psychopy does that in the background for you anyway, but you might want to change your code to get rid of the warnings.