How to end loop after specific amount of time

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()

completed 1 repeats of ‘delay_loop’

Hi Susie,

What syntax errors do you get?