If this template helps then use it. If not then just delete and start from scratch.
OS (e.g. Win10): MacOS Catalina
PsychoPy version (e.g. 1.84.x): 2020.1.2
**Standard Standalone? yes
What are you trying to achieve?:
Within a larger experiment, I have a delay task that shows trivia questions then the trivia answer after the space bar is pressed then participants say whether they got the answer correct or not. This task is done through a loop and pulls trivia questions and answers from an excel file randomly. But I don’t want each participant to do the same number of trivia questions, I want the trivia delay task to end after 10 minutes for every participant.
What did you try to make it work?:
I tried inserting code snippets to add a new clock before the loop begins and then in the each frame (for each routine within the loop) I put an if clause to check the time and end the routine if the time was greater than 600 seconds.
What specifically went wrong when you tried that?:
I kept getting syntax errors even though I was using the same syntax that I saw in another forum post.
Code without the code snippets for the clock:
Is there something I can add to the code to make the loop terminate after a certain amount of time?
set up handler to look after randomisation of conditions etc
delay_loop = data.TrialHandler(nReps=1, method=‘random’,
extraInfo=expInfo, originPath=-1,
trialList=data.importConditions(‘Delay_Trivia_Database_Conditions_v4 (1).xlsx’, selection=‘1:50’),
seed=None, name=‘delay_loop’)
thisExp.addLoop(delay_loop) # add the loop to the experiment
thisDelay_loop = delay_loop.trialList[0] # so we can initialise stimuli with some values
abbreviate parameter names if possible (e.g. rgb = thisDelay_loop.rgb)
if thisDelay_loop != None:
for paramName in thisDelay_loop:
exec(’{} = thisDelay_loop[paramName]’.format(paramName))
for thisDelay_loop in delay_loop:
currentLoop = delay_loop
# abbreviate parameter names if possible (e.g. rgb = thisDelay_loop.rgb)
if thisDelay_loop != None:
for paramName in thisDelay_loop:
exec(’{} = thisDelay_loop[paramName]’.format(paramName))
# ------Prepare to start Routine "fix_2"-------
continueRoutine = True
routineTimer.add(1.000000)
# update component parameters for each repeat
# keep track of which components have finished
fix_2Components = [fixation_text_2]
for thisComponent in fix_2Components:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# reset timers
t = 0
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
fix_2Clock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
frameN = -1
# -------Run Routine "fix_2"-------
while continueRoutine and routineTimer.getTime() > 0:
# get current time
t = fix_2Clock.getTime()
tThisFlip = win.getFutureFlipTime(clock=fix_2Clock)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *fixation_text_2* updates
if fixation_text_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
fixation_text_2.frameNStart = frameN # exact frame index
fixation_text_2.tStart = t # local t and not account for scr refresh
fixation_text_2.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(fixation_text_2, 'tStartRefresh') # time at next scr refresh
fixation_text_2.setAutoDraw(True)
if fixation_text_2.status == STARTED:
# is it time to stop? (based on global clock, using actual start)
if tThisFlipGlobal > fixation_text_2.tStartRefresh + 1-frameTolerance:
# keep track of stop time/frame for later
fixation_text_2.tStop = t # not accounting for scr refresh
fixation_text_2.frameNStop = frameN # exact frame index
win.timeOnFlip(fixation_text_2, 'tStopRefresh') # time at next scr refresh
fixation_text_2.setAutoDraw(False)
# check for quit (typically the Esc key)
if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
core.quit()
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in fix_2Components:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# -------Ending Routine "fix_2"-------
for thisComponent in fix_2Components:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
delay_loop.addData('fixation_text_2.started', fixation_text_2.tStartRefresh)
delay_loop.addData('fixation_text_2.stopped', fixation_text_2.tStopRefresh)
# ------Prepare to start Routine "trivia"-------
continueRoutine = True
# update component parameters for each repeat
trivia_text.setText(question)
key_resp.keys = []
key_resp.rt = []
_key_resp_allKeys = []
# keep track of which components have finished
triviaComponents = [trivia_text, key_resp, trivia_instructions]
for thisComponent in triviaComponents:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# reset timers
t = 0
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
triviaClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
frameN = -1
# -------Run Routine "trivia"-------
while continueRoutine:
# get current time
t = triviaClock.getTime()
tThisFlip = win.getFutureFlipTime(clock=triviaClock)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *trivia_text* updates
if trivia_text.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
trivia_text.frameNStart = frameN # exact frame index
trivia_text.tStart = t # local t and not account for scr refresh
trivia_text.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(trivia_text, 'tStartRefresh') # time at next scr refresh
trivia_text.setAutoDraw(True)
# *key_resp* updates
waitOnFlip = False
if key_resp.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
key_resp.frameNStart = frameN # exact frame index
key_resp.tStart = t # local t and not account for scr refresh
key_resp.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(key_resp, 'tStartRefresh') # time at next scr refresh
key_resp.status = STARTED
# keyboard checking is just starting
waitOnFlip = True
win.callOnFlip(key_resp.clock.reset) # t=0 on next screen flip
win.callOnFlip(key_resp.clearEvents, eventType='keyboard') # clear events on next screen flip
if key_resp.status == STARTED and not waitOnFlip:
theseKeys = key_resp.getKeys(keyList=['space'], waitRelease=False)
_key_resp_allKeys.extend(theseKeys)
if len(_key_resp_allKeys):
key_resp.keys = [key.name for key in _key_resp_allKeys] # storing all keys
key_resp.rt = [key.rt for key in _key_resp_allKeys]
# a response ends the routine
continueRoutine = False
# *trivia_instructions* updates
if trivia_instructions.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
trivia_instructions.frameNStart = frameN # exact frame index
trivia_instructions.tStart = t # local t and not account for scr refresh
trivia_instructions.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(trivia_instructions, 'tStartRefresh') # time at next scr refresh
trivia_instructions.setAutoDraw(True)
# check for quit (typically the Esc key)
if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
core.quit()
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in triviaComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# -------Ending Routine "trivia"-------
for thisComponent in triviaComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
delay_loop.addData('trivia_text.started', trivia_text.tStartRefresh)
delay_loop.addData('trivia_text.stopped', trivia_text.tStopRefresh)
# check responses
if key_resp.keys in ['', [], None]: # No response was made
key_resp.keys = None
delay_loop.addData('key_resp.keys',key_resp.keys)
if key_resp.keys != None: # we had a response
delay_loop.addData('key_resp.rt', key_resp.rt)
delay_loop.addData('key_resp.started', key_resp.tStartRefresh)
delay_loop.addData('key_resp.stopped', key_resp.tStopRefresh)
delay_loop.addData('trivia_instructions.started', trivia_instructions.tStartRefresh)
delay_loop.addData('trivia_instructions.stopped', trivia_instructions.tStopRefresh)
# the Routine "trivia" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
# ------Prepare to start Routine "trivia_answer"-------
continueRoutine = True
# update component parameters for each repeat
trivia_text2.setText(question)
exit_2.keys = []
exit_2.rt = []
_exit_2_allKeys = []
trivia_answer_text.setText(answer)
# keep track of which components have finished
trivia_answerComponents = [trivia_text2, exit_2, trivia_answer_text, trivia_instructions_2]
for thisComponent in trivia_answerComponents:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# reset timers
t = 0
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
trivia_answerClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
frameN = -1
# -------Run Routine "trivia_answer"-------
while continueRoutine:
# get current time
t = trivia_answerClock.getTime()
tThisFlip = win.getFutureFlipTime(clock=trivia_answerClock)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *trivia_text2* updates
if trivia_text2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
trivia_text2.frameNStart = frameN # exact frame index
trivia_text2.tStart = t # local t and not account for scr refresh
trivia_text2.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(trivia_text2, 'tStartRefresh') # time at next scr refresh
trivia_text2.setAutoDraw(True)
# *exit_2* updates
waitOnFlip = False
if exit_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
exit_2.frameNStart = frameN # exact frame index
exit_2.tStart = t # local t and not account for scr refresh
exit_2.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(exit_2, 'tStartRefresh') # time at next scr refresh
exit_2.status = STARTED
# keyboard checking is just starting
waitOnFlip = True
win.callOnFlip(exit_2.clock.reset) # t=0 on next screen flip
win.callOnFlip(exit_2.clearEvents, eventType='keyboard') # clear events on next screen flip
if exit_2.status == STARTED and not waitOnFlip:
theseKeys = exit_2.getKeys(keyList=['q', 'p', 'Q', 'P'], waitRelease=False)
_exit_2_allKeys.extend(theseKeys)
if len(_exit_2_allKeys):
exit_2.keys = _exit_2_allKeys[-1].name # just the last key pressed
exit_2.rt = _exit_2_allKeys[-1].rt
# a response ends the routine
continueRoutine = False
# *trivia_answer_text* updates
if trivia_answer_text.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
trivia_answer_text.frameNStart = frameN # exact frame index
trivia_answer_text.tStart = t # local t and not account for scr refresh
trivia_answer_text.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(trivia_answer_text, 'tStartRefresh') # time at next scr refresh
trivia_answer_text.setAutoDraw(True)
# *trivia_instructions_2* updates
if trivia_instructions_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
trivia_instructions_2.frameNStart = frameN # exact frame index
trivia_instructions_2.tStart = t # local t and not account for scr refresh
trivia_instructions_2.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(trivia_instructions_2, 'tStartRefresh') # time at next scr refresh
trivia_instructions_2.setAutoDraw(True)
# check for quit (typically the Esc key)
if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
core.quit()
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in trivia_answerComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# -------Ending Routine "trivia_answer"-------
for thisComponent in trivia_answerComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
delay_loop.addData('trivia_text2.started', trivia_text2.tStartRefresh)
delay_loop.addData('trivia_text2.stopped', trivia_text2.tStopRefresh)
# check responses
if exit_2.keys in ['', [], None]: # No response was made
exit_2.keys = None
delay_loop.addData('exit_2.keys',exit_2.keys)
if exit_2.keys != None: # we had a response
delay_loop.addData('exit_2.rt', exit_2.rt)
delay_loop.addData('exit_2.started', exit_2.tStartRefresh)
delay_loop.addData('exit_2.stopped', exit_2.tStopRefresh)
delay_loop.addData('trivia_answer_text.started', trivia_answer_text.tStartRefresh)
delay_loop.addData('trivia_answer_text.stopped', trivia_answer_text.tStopRefresh)
delay_loop.addData('trivia_instructions_2.started', trivia_instructions_2.tStartRefresh)
delay_loop.addData('trivia_instructions_2.stopped', trivia_instructions_2.tStopRefresh)
# the Routine "trivia_answer" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
thisExp.nextEntry()