psychopy.org | Reference | Downloads | Github

How to insert a countdown for the stimuli?

Hi, I am quite new at programming in Psychopy.

My question is:
How can I insert a countdown for the stimuli, indicating how many stimuli are still left?

My system:
macOS Sierra 10.12.6

My version:
v1.81.00

My code:

  • Please note that the code does not work for later versions.
    Should it be necessary to upgrade to implement the required feature, can you tell me also how to adapt the code to the new version?

#!/usr/bin/env python2

-- coding: utf-8 --

“”"
This experiment was created using PsychoPy2 Experiment Builder (v1.81.00), Dom 17 Giu 09:59:12 2018
If you publish work using this script please cite the relevant PsychoPy publications
Peirce, JW (2007) PsychoPy - Psychophysics software in Python. Journal of Neuroscience Methods, 162(1-2), 8-13.
Peirce, JW (2009) Generating stimuli for neuroscience using PsychoPy. Frontiers in Neuroinformatics, 2:10. doi: 10.3389/neuro.11.010.2008
“”"

from future import division # so that 1/3=0.333 instead of 1/3=0
from psychopy import visual, core, data, event, logging, sound, gui
from psychopy.constants import * # things like STARTED, FINISHED
import numpy as np # whole numpy lib is available, prepend ‘np.’
from numpy import sin, cos, tan, log, log10, pi, average, sqrt, std, deg2rad, rad2deg, linspace, asarray
from numpy.random import random, randint, normal, shuffle
import os # handy system and path functions

Ensure that relative paths start from the same directory as this script

_thisDir = os.path.dirname(os.path.abspath(file))
os.chdir(_thisDir)

Store info about the experiment session

expName = ‘Output-Trial’ # from the Builder filename that created this script
expInfo = {u’session’: u’001’, u’participant’: u’’}
dlg = gui.DlgFromDict(dictionary=expInfo, title=expName)
if dlg.OK == False: core.quit() # user pressed cancel
expInfo[‘date’] = data.getDateStr() # add a simple timestamp
expInfo[‘expName’] = expName

Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc

filename = thisDir + os.sep + 'data/%s%s_%s’ %(expInfo[‘participant’], expName, expInfo[‘date’])

An ExperimentHandler isn’t essential but helps with data saving

thisExp = data.ExperimentHandler(name=expName, version=’’,
extraInfo=expInfo, runtimeInfo=None,
originPath=’/Users/Erica/Desktop/Desktop-120518/Francia/Progetto Parigi/Experiment TIMBRE/Timbre-Oboe.psyexp’,
savePickle=True, saveWideText=True,
dataFileName=filename)
#save a log file for detail verbose info
logFile = logging.LogFile(filename+’.log’, level=logging.EXP)
logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file

endExpNow = False # flag for ‘escape’ or other condition => quit the exp

Start Code - component code to be run before the window creation

Setup the Window

win = visual.Window(size=(1680, 1050), fullscr=True, screen=0, allowGUI=True, allowStencil=False,
monitor=‘testMonitor’, color=[-1.000,-1.000,-1.000], colorSpace=‘rgb’,
blendMode=‘avg’, useFBO=True,
)

store frame rate of monitor if we can measure it successfully

expInfo[‘frameRate’]=win.getActualFrameRate()
if expInfo[‘frameRate’]!=None:
frameDur = 1.0/round(expInfo[‘frameRate’])
else:
frameDur = 1.0/60.0 # couldn’t get a reliable measure so guess

Initialize components for Routine “Instruction_1”

Instruction_1Clock = core.Clock()
text = visual.TextStim(win=win, ori=0, name=‘text’,
text=u"Le projet de recherche auquel vous participez porte sur la perception du TIMBRE (pris dans un sens large : couleur du son, texture, toute notion \xe0 l\u2019exception de la hauteur de la note).\n. \n\nVous entendrez 37 paires de sons. Pour chaque paire, vous serez appel\xe9s \xe0 r\xe9aliser une t\xe2che. \n\nIl n’y a pas de bonne ou de mauvaise r\xe9ponse, puisqu’il s’agit d’indiquer quelle est votre perception. \nLa dur\xe9e moyenne de ce test est de 30 minutes. \n\n\nVeuillez passer \xe0 la diapositive suivante en appuyant sur la barre d’espace.", font=‘Arial’,
pos=[0, 0], height=0.07, wrapWidth=None,
color=‘white’, colorSpace=‘rgb’, opacity=1,
depth=0.0)

Initialize components for Routine “Instruction_2”

Instruction_2Clock = core.Clock()
text_2 = visual.TextStim(win=win, ori=0, name=‘text_2’,
text=u"Au cours de cette exp\xe9rience, vous entendrez des s\xe9quences de paires de sons.\n\n\nVous serez appel\xe9s \xe0 \xe9valuer, sur une \xe9chelle de 1 \xe0 5, le degr\xe9 de SIMILARIT\xc9 entre les sons de chaque paire.\n\nVous pouvez \xe9couter chaque paire de stimuli deux fois de suite, s\xe9par\xe9es par un court intervalle de temps.\n\nVeuillez indiquer votre choix (une seule \xe9coute de la paire ou deux \xe9coutes successives de la paire) apr\xe8s l\u2019\xe9coute de la paire de stimuli.\n\n\nVeuillez passer \xe0 la diapositive suivante en appuyant sur la barre d’espace lorsque vous serez pr\xeat.", font=‘Arial’,
pos=[0, 0], height=0.07, wrapWidth=None,
color=‘white’, colorSpace=‘rgb’, opacity=1,
depth=0.0)

Initialize components for Routine “Instruction_3”

Instruction_3Clock = core.Clock()
text_3 = visual.TextStim(win=win, ori=0, name=‘text_3’,
text=“Maintenant, vous allez entendre le premier extrait.\n\nAppuyez sur la barre d’espace pour continuer. \n\n”, font=‘Arial’,
pos=[0, 0], height=0.07, wrapWidth=None,
color=‘white’, colorSpace=‘rgb’, opacity=1,
depth=0.0)

Initialize components for Routine “trial1_2”

trial1_2Clock = core.Clock()
text_7 = visual.TextStim(win=win, ori=0, name=‘text_7’,
text=u"Au commencement du second extrait de chaque paire, veuillez \xe9valuer le degr\xe9 de SIMILARIT\xc9 ENTRE LES DEUX SONS, de 1 \xe0 5, en cliquant sur l’un des points de l’\xe9chelle. \n\nVous pouvez changer votre \xe9valuation \xe0 votre guise. \nPour soumettre votre choix de mani\xe8re d\xe9finitive, cliquez dans le rectangle au bas de la page.", font=‘Arial’,
pos=[0, 0.2], height=0.07, wrapWidth=None,
color=‘white’, colorSpace=‘rgb’, opacity=1,
depth=0.0)
similarity = visual.RatingScale(win=win, name=‘similarity’, marker=‘triangle’,
markerColor=‘red’,
size=0.7,
pos=[0, -0.6],
low=1,
high=5,
labels=[’’],
scale=u’1 = tr\xe8s diff\xe9rent 5 = tr\xe8s semblable’,
disappear=True)
sound_6 = sound.Sound(‘A’)
sound_6.setVolume(1)

Initialize components for Routine “End”

EndClock = core.Clock()
text_12 = visual.TextStim(win=win, ori=0, name=‘text_12’,
text=u’F\xe9licitations, vous avez bien effectu\xe9 la t\xe2che demand\xe9e. \n\nVeuillez appuyer sur la barre d\u2019espace lorsque vous aurez termin\xe9.’, font=‘Arial’,
pos=[0, 0], height=0.07, wrapWidth=None,
color=‘white’, colorSpace=‘rgb’, opacity=1,
depth=0.0)

Create some handy timers

globalClock = core.Clock() # to track the time since experiment started
routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine

#------Prepare to start Routine “Instruction_1”-------
t = 0
Instruction_1Clock.reset() # clock
frameN = -1

update component parameters for each repeat

key_resp_2 = event.BuilderKeyResponse() # create an object of type KeyResponse
key_resp_2.status = NOT_STARTED

keep track of which components have finished

Instruction_1Components = []
Instruction_1Components.append(text)
Instruction_1Components.append(key_resp_2)
for thisComponent in Instruction_1Components:
if hasattr(thisComponent, ‘status’):
thisComponent.status = NOT_STARTED

#-------Start Routine “Instruction_1”-------
continueRoutine = True
while continueRoutine:
# get current time
t = Instruction_1Clock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame

# *text* updates
if t >= 0.0 and text.status == NOT_STARTED:
    # keep track of start time/frame for later
    text.tStart = t  # underestimates by a little under one frame
    text.frameNStart = frameN  # exact frame index
    text.setAutoDraw(True)

# *key_resp_2* updates
if t >= 0.0 and key_resp_2.status == NOT_STARTED:
    # keep track of start time/frame for later
    key_resp_2.tStart = t  # underestimates by a little under one frame
    key_resp_2.frameNStart = frameN  # exact frame index
    key_resp_2.status = STARTED
    # keyboard checking is just starting
    event.clearEvents(eventType='keyboard')
if key_resp_2.status == STARTED:
    theseKeys = event.getKeys(keyList=['space'])
   
    # check for quit:
    if "escape" in theseKeys:
        endExpNow = True
    if len(theseKeys) > 0:  # at least one key was pressed
        # a response ends the routine
        continueRoutine = False

# check if all components have finished
if not continueRoutine:  # a component has requested a forced-end of Routine
    routineTimer.reset()  # if we abort early the non-slip timer needs reset
    break
continueRoutine = False  # will revert to True if at least one component still running
for thisComponent in Instruction_1Components:
    if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
        continueRoutine = True
        break  # at least one component has not yet finished

# check for quit (the Esc key)
if endExpNow or event.getKeys(keyList=["escape"]):
    core.quit()

# refresh the screen
if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
    win.flip()
else:  # this Routine was not non-slip safe so reset non-slip timer
    routineTimer.reset()

#-------Ending Routine “Instruction_1”-------
for thisComponent in Instruction_1Components:
if hasattr(thisComponent, “setAutoDraw”):
thisComponent.setAutoDraw(False)

#------Prepare to start Routine “Instruction_2”-------
t = 0
Instruction_2Clock.reset() # clock
frameN = -1

update component parameters for each repeat

key_resp_3 = event.BuilderKeyResponse() # create an object of type KeyResponse
key_resp_3.status = NOT_STARTED

keep track of which components have finished

Instruction_2Components = []
Instruction_2Components.append(text_2)
Instruction_2Components.append(key_resp_3)
for thisComponent in Instruction_2Components:
if hasattr(thisComponent, ‘status’):
thisComponent.status = NOT_STARTED

#-------Start Routine “Instruction_2”-------
continueRoutine = True
while continueRoutine:
# get current time
t = Instruction_2Clock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame

# *text_2* updates
if t >= 0.0 and text_2.status == NOT_STARTED:
    # keep track of start time/frame for later
    text_2.tStart = t  # underestimates by a little under one frame
    text_2.frameNStart = frameN  # exact frame index
    text_2.setAutoDraw(True)

# *key_resp_3* updates
if t >= 0.0 and key_resp_3.status == NOT_STARTED:
    # keep track of start time/frame for later
    key_resp_3.tStart = t  # underestimates by a little under one frame
    key_resp_3.frameNStart = frameN  # exact frame index
    key_resp_3.status = STARTED
    # keyboard checking is just starting
    event.clearEvents(eventType='keyboard')
if key_resp_3.status == STARTED:
    theseKeys = event.getKeys(keyList=['space'])
   
    # check for quit:
    if "escape" in theseKeys:
        endExpNow = True
    if len(theseKeys) > 0:  # at least one key was pressed
        # a response ends the routine
        continueRoutine = False

# check if all components have finished
if not continueRoutine:  # a component has requested a forced-end of Routine
    routineTimer.reset()  # if we abort early the non-slip timer needs reset
    break
continueRoutine = False  # will revert to True if at least one component still running
for thisComponent in Instruction_2Components:
    if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
        continueRoutine = True
        break  # at least one component has not yet finished

# check for quit (the Esc key)
if endExpNow or event.getKeys(keyList=["escape"]):
    core.quit()

# refresh the screen
if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
    win.flip()
else:  # this Routine was not non-slip safe so reset non-slip timer
    routineTimer.reset()

#-------Ending Routine “Instruction_2”-------
for thisComponent in Instruction_2Components:
if hasattr(thisComponent, “setAutoDraw”):
thisComponent.setAutoDraw(False)

#------Prepare to start Routine “Instruction_3”-------
t = 0
Instruction_3Clock.reset() # clock
frameN = -1

update component parameters for each repeat

key_resp_4 = event.BuilderKeyResponse() # create an object of type KeyResponse
key_resp_4.status = NOT_STARTED

keep track of which components have finished

Instruction_3Components = []
Instruction_3Components.append(text_3)
Instruction_3Components.append(key_resp_4)
for thisComponent in Instruction_3Components:
if hasattr(thisComponent, ‘status’):
thisComponent.status = NOT_STARTED

#-------Start Routine “Instruction_3”-------
continueRoutine = True
while continueRoutine:
# get current time
t = Instruction_3Clock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame

# *text_3* updates
if t >= 0.0 and text_3.status == NOT_STARTED:
    # keep track of start time/frame for later
    text_3.tStart = t  # underestimates by a little under one frame
    text_3.frameNStart = frameN  # exact frame index
    text_3.setAutoDraw(True)

# *key_resp_4* updates
if t >= 0.0 and key_resp_4.status == NOT_STARTED:
    # keep track of start time/frame for later
    key_resp_4.tStart = t  # underestimates by a little under one frame
    key_resp_4.frameNStart = frameN  # exact frame index
    key_resp_4.status = STARTED
    # keyboard checking is just starting
    event.clearEvents(eventType='keyboard')
if key_resp_4.status == STARTED:
    theseKeys = event.getKeys(keyList=['space'])
   
    # check for quit:
    if "escape" in theseKeys:
        endExpNow = True
    if len(theseKeys) > 0:  # at least one key was pressed
        # a response ends the routine
        continueRoutine = False

# check if all components have finished
if not continueRoutine:  # a component has requested a forced-end of Routine
    routineTimer.reset()  # if we abort early the non-slip timer needs reset
    break
continueRoutine = False  # will revert to True if at least one component still running
for thisComponent in Instruction_3Components:
    if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
        continueRoutine = True
        break  # at least one component has not yet finished

# check for quit (the Esc key)
if endExpNow or event.getKeys(keyList=["escape"]):
    core.quit()

# refresh the screen
if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
    win.flip()
else:  # this Routine was not non-slip safe so reset non-slip timer
    routineTimer.reset()

#-------Ending Routine “Instruction_3”-------
for thisComponent in Instruction_3Components:
if hasattr(thisComponent, “setAutoDraw”):
thisComponent.setAutoDraw(False)

set up handler to look after randomisation of conditions etc

trials = data.TrialHandler(nReps=1, method=‘random’,
extraInfo=expInfo, originPath=’/Users/Erica/Desktop/Desktop-120518/Francia/Progetto Parigi/Experiment TIMBRE/Timbre-Oboe.psyexp’,
trialList=data.importConditions(‘datasound2.xlsx’),
seed=None, name=‘trials’)
thisExp.addLoop(trials) # add the loop to the experiment
thisTrial = trials.trialList[0] # so we can initialise stimuli with some values

abbreviate parameter names if possible (e.g. rgb=thisTrial.rgb)

if thisTrial != None:
for paramName in thisTrial.keys():
exec(paramName + ‘= thisTrial.’ + paramName)

for thisTrial in trials:
currentLoop = trials
# abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
if thisTrial != None:
for paramName in thisTrial.keys():
exec(paramName + ‘= thisTrial.’ + paramName)

#------Prepare to start Routine "trial1_2"-------
t = 0
trial1_2Clock.reset()  # clock
frameN = -1
# update component parameters for each repeat
similarity.reset()
sound_6.setSound(Sound)
scaleList2 = [similarity]

# keep track of which components have finished
trial1_2Components = []
trial1_2Components.append(text_7)
trial1_2Components.append(similarity)
trial1_2Components.append(sound_6)
for thisComponent in trial1_2Components:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

#-------Start Routine "trial1_2"-------
continueRoutine = True
while continueRoutine:
    # get current time
    t = trial1_2Clock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
   
    # *text_7* updates
    if t >= 0.0 and text_7.status == NOT_STARTED:
        # keep track of start time/frame for later
        text_7.tStart = t  # underestimates by a little under one frame
        text_7.frameNStart = frameN  # exact frame index
        text_7.setAutoDraw(True)
    # *similarity* updates
    if t > 0.0:
        similarity.draw()
        if similarity.noResponse == False:
            similarity.response = similarity.getRating()
    # start/stop sound_6
    if t >= 0.0 and sound_6.status == NOT_STARTED:
        # keep track of start time/frame for later
        sound_6.tStart = t  # underestimates by a little under one frame
        sound_6.frameNStart = frameN  # exact frame index
        sound_6.play()  # start the sound (it finishes automatically)
    count = 0
    for s in scaleList2:
        if not s.noResponse:
            count += 1
    if count == 1:
        continueRoutine = False
   
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        routineTimer.reset()  # if we abort early the non-slip timer needs reset
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in trial1_2Components:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
            continueRoutine = True
            break  # at least one component has not yet finished
   
    # check for quit (the Esc key)
    if endExpNow or event.getKeys(keyList=["escape"]):
        core.quit()
   
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()
    else:  # this Routine was not non-slip safe so reset non-slip timer
        routineTimer.reset()

#-------Ending Routine "trial1_2"-------
for thisComponent in trial1_2Components:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# store data for trials (TrialHandler)
trials.addData('similarity.response', similarity.getRating())
sound_6.stop()
thisExp.nextEntry()

completed 1 repeats of ‘trials’

get names of stimulus parameters

if trials.trialList in ([], [None], None): params = []
else: params = trials.trialList[0].keys()

save data for this loop

trials.saveAsExcel(filename + ‘.xlsx’, sheetName=‘trials’,
stimOut=params,
dataOut=[‘n’,‘all_mean’,‘all_std’, ‘all_raw’])

#------Prepare to start Routine “End”-------
t = 0
EndClock.reset() # clock
frameN = -1

update component parameters for each repeat

key_resp_10 = event.BuilderKeyResponse() # create an object of type KeyResponse
key_resp_10.status = NOT_STARTED

keep track of which components have finished

EndComponents = []
EndComponents.append(text_12)
EndComponents.append(key_resp_10)
for thisComponent in EndComponents:
if hasattr(thisComponent, ‘status’):
thisComponent.status = NOT_STARTED

#-------Start Routine “End”-------
continueRoutine = True
while continueRoutine:
# get current time
t = EndClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame

# *text_12* updates
if t >= 0.0 and text_12.status == NOT_STARTED:
    # keep track of start time/frame for later
    text_12.tStart = t  # underestimates by a little under one frame
    text_12.frameNStart = frameN  # exact frame index
    text_12.setAutoDraw(True)

# *key_resp_10* updates
if t >= 0.0 and key_resp_10.status == NOT_STARTED:
    # keep track of start time/frame for later
    key_resp_10.tStart = t  # underestimates by a little under one frame
    key_resp_10.frameNStart = frameN  # exact frame index
    key_resp_10.status = STARTED
    # keyboard checking is just starting
    event.clearEvents(eventType='keyboard')
if key_resp_10.status == STARTED:
    theseKeys = event.getKeys(keyList=['space'])
   
    # check for quit:
    if "escape" in theseKeys:
        endExpNow = True
    if len(theseKeys) > 0:  # at least one key was pressed
        # a response ends the routine
        continueRoutine = False

# check if all components have finished
if not continueRoutine:  # a component has requested a forced-end of Routine
    routineTimer.reset()  # if we abort early the non-slip timer needs reset
    break
continueRoutine = False  # will revert to True if at least one component still running
for thisComponent in EndComponents:
    if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
        continueRoutine = True
        break  # at least one component has not yet finished

# check for quit (the Esc key)
if endExpNow or event.getKeys(keyList=["escape"]):
    core.quit()

# refresh the screen
if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
    win.flip()
else:  # this Routine was not non-slip safe so reset non-slip timer
    routineTimer.reset()

#-------Ending Routine “End”-------
for thisComponent in EndComponents:
if hasattr(thisComponent, “setAutoDraw”):
thisComponent.setAutoDraw(False)

win.close()
core.quit()

1 Like

Hi @ericabisesi, it is a bit difficult to read your code as is. You need to surround your code with backticks to help the reader. However, there is a solution using the trialhandler. Your experiment trialhandler called “trials” will have an attribute called nRemaining, which gives number of trials remaining. So to access trials remaining for that loop, use:
trialsRemaining = trials.nRemaining

2 Likes

Hi David,

thanks for the suggestion. I will try.

An important question: what does it mean “surround your code with backticks”? I tried to do that, but I does not understand what is this. It will be useful in any case…

Thanks, Erica

Hi Michael and David,

I tried to implement trialsRemaining = trials.nRemaining into my code, but I have no idea on where should it go.

I attach the code, hopefully this time in the proper format. I put ``` above and below, anyway I do not see any preview…

I also attach the script. It is important for me to undersdand how to send you a code.

Thanks, Erica


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
This experiment was created using PsychoPy2 Experiment Builder (v1.81.00), Ven 29 Giu 14:35:52 2018
If you publish work using this script please cite the relevant PsychoPy publications
  Peirce, JW (2007) PsychoPy - Psychophysics software in Python. Journal of Neuroscience Methods, 162(1-2), 8-13.
  Peirce, JW (2009) Generating stimuli for neuroscience using PsychoPy. Frontiers in Neuroinformatics, 2:10. doi: 10.3389/neuro.11.010.2008
"""

from __future__ import division  # so that 1/3=0.333 instead of 1/3=0
from psychopy import visual, core, data, event, logging, sound, gui
from psychopy.constants import *  # things like STARTED, FINISHED
import numpy as np  # whole numpy lib is available, prepend 'np.'
from numpy import sin, cos, tan, log, log10, pi, average, sqrt, std, deg2rad, rad2deg, linspace, asarray
from numpy.random import random, randint, normal, shuffle
import os  # handy system and path functions

# Ensure that relative paths start from the same directory as this script
_thisDir = os.path.dirname(os.path.abspath(__file__))
os.chdir(_thisDir)

# Store info about the experiment session
expName = 'Output-Trial'  # from the Builder filename that created this script
expInfo = {u'session': u'001', u'participant': u''}
dlg = gui.DlgFromDict(dictionary=expInfo, title=expName)
if dlg.OK == False: core.quit()  # user pressed cancel
expInfo['date'] = data.getDateStr()  # add a simple timestamp
expInfo['expName'] = expName

# Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
filename = _thisDir + os.sep + 'data/%s_%s_%s' %(expInfo['participant'], expName, expInfo['date'])

# An ExperimentHandler isn't essential but helps with data saving
thisExp = data.ExperimentHandler(name=expName, version='',
    extraInfo=expInfo, runtimeInfo=None,
    originPath=None,
    savePickle=True, saveWideText=True,
    dataFileName=filename)
#save a log file for detail verbose info
logFile = logging.LogFile(filename+'.log', level=logging.EXP)
logging.console.setLevel(logging.WARNING)  # this outputs to the screen, not a file

endExpNow = False  # flag for 'escape' or other condition => quit the exp

# Start Code - component code to be run before the window creation

# Setup the Window
win = visual.Window(size=[1680, 1050], fullscr=False, screen=0, allowGUI=True, allowStencil=False,
    monitor='testMonitor', color=[-1.000,-1.000,-1.000], colorSpace='rgb',
    blendMode='avg', useFBO=True,
    )
# store frame rate of monitor if we can measure it successfully
expInfo['frameRate']=win.getActualFrameRate()
if expInfo['frameRate']!=None:
    frameDur = 1.0/round(expInfo['frameRate'])
else:
    frameDur = 1.0/60.0 # couldn't get a reliable measure so guess

# Initialize components for Routine "Instruction_1"
Instruction_1Clock = core.Clock()
text = visual.TextStim(win=win, ori=0, name='text',
    text=u"Le projet de recherche auquel vous participez porte sur la perception du TIMBRE (pris dans un sens large : couleur du son, texture, toute notion \xe0 l\u2019exception de la hauteur de la note).\n. \n\nVous entendrez 37 paires de sons. Pour chaque paire, vous serez appel\xe9s \xe0 r\xe9aliser une t\xe2che. \n\nIl n'y a pas de bonne ou de mauvaise r\xe9ponse, puisqu'il s'agit d'indiquer quelle est votre perception. \nLa dur\xe9e moyenne de ce test est de 30 minutes. \n\n\nVeuillez passer \xe0 la diapositive suivante en appuyant sur la barre d'espace.",    font='Arial',
    pos=[0, 0], height=0.07, wrapWidth=None,
    color='white', colorSpace='rgb', opacity=1,
    depth=0.0)

# Initialize components for Routine "Instruction_2"
Instruction_2Clock = core.Clock()
text_2 = visual.TextStim(win=win, ori=0, name='text_2',
    text=u"Au cours de cette exp\xe9rience, vous entendrez des s\xe9quences de paires de sons.\n\n\nVous serez appel\xe9s \xe0 \xe9valuer, sur une \xe9chelle de 1 \xe0 5, le degr\xe9 de SIMILARIT\xc9 entre les sons de chaque paire.\n\nVous pouvez \xe9couter chaque paire de stimuli deux fois de suite, s\xe9par\xe9es par un court intervalle de temps.\n\nVeuillez indiquer votre choix (une seule \xe9coute de la paire ou deux \xe9coutes successives de la paire) apr\xe8s l\u2019\xe9coute de la paire de stimuli.\n\n\nVeuillez passer \xe0 la diapositive suivante en appuyant sur la barre d'espace lorsque vous serez pr\xeat.",    font='Arial',
    pos=[0, 0], height=0.07, wrapWidth=None,
    color='white', colorSpace='rgb', opacity=1,
    depth=0.0)

# Initialize components for Routine "Instruction_3"
Instruction_3Clock = core.Clock()
text_3 = visual.TextStim(win=win, ori=0, name='text_3',
    text="Maintenant, vous allez entendre le premier extrait.\n\nAppuyez sur la barre d'espace pour continuer. \n\n",    font='Arial',
    pos=[0, 0], height=0.07, wrapWidth=None,
    color='white', colorSpace='rgb', opacity=1,
    depth=0.0)

# Initialize components for Routine "trial1_2"
trial1_2Clock = core.Clock()
text_7 = visual.TextStim(win=win, ori=0, name='text_7',
    text=u"Au commencement du second extrait de chaque paire, veuillez \xe9valuer le degr\xe9 de SIMILARIT\xc9 ENTRE LES DEUX SONS, de 1 \xe0 5, en cliquant sur l'un des points de l'\xe9chelle. \n\nVous pouvez changer votre \xe9valuation \xe0 votre guise. \nPour soumettre votre choix de mani\xe8re d\xe9finitive, cliquez dans le rectangle au bas de la page.",    font='Arial',
    pos=[0, 0.2], height=0.07, wrapWidth=None,
    color='white', colorSpace='rgb', opacity=1,
    depth=0.0)
similarity = visual.RatingScale(win=win, name='similarity', marker='triangle',
markerColor='red',
size=0.7,
pos=[0, -0.6],
low=1,
high=5,
labels=[''],
scale=u'1 = tr\xe8s diff\xe9rent                   5 = tr\xe8s semblable',
disappear=True)
sound_6 = sound.Sound('A')
sound_6.setVolume(1)

# Initialize components for Routine "End"
EndClock = core.Clock()
text_12 = visual.TextStim(win=win, ori=0, name='text_12',
    text=u'F\xe9licitations, vous avez bien effectu\xe9 la t\xe2che demand\xe9e. \n\nVeuillez appuyer sur la barre d\u2019espace lorsque vous aurez termin\xe9.',    font='Arial',
    pos=[0, 0], height=0.07, wrapWidth=None,
    color='white', colorSpace='rgb', opacity=1,
    depth=0.0)

# Create some handy timers
globalClock = core.Clock()  # to track the time since experiment started
routineTimer = core.CountdownTimer()  # to track time remaining of each (non-slip) routine

#------Prepare to start Routine "Instruction_1"-------
t = 0
Instruction_1Clock.reset()  # clock
frameN = -1
# update component parameters for each repeat
key_resp_2 = event.BuilderKeyResponse()  # create an object of type KeyResponse
key_resp_2.status = NOT_STARTED
# keep track of which components have finished
Instruction_1Components = []
Instruction_1Components.append(text)
Instruction_1Components.append(key_resp_2)
for thisComponent in Instruction_1Components:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

#-------Start Routine "Instruction_1"-------
continueRoutine = True
while continueRoutine:
    # get current time
    t = Instruction_1Clock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
   
    # *text* updates
    if t >= 0.0 and text.status == NOT_STARTED:
        # keep track of start time/frame for later
        text.tStart = t  # underestimates by a little under one frame
        text.frameNStart = frameN  # exact frame index
        text.setAutoDraw(True)
   
    # *key_resp_2* updates
    if t >= 0.0 and key_resp_2.status == NOT_STARTED:
        # keep track of start time/frame for later
        key_resp_2.tStart = t  # underestimates by a little under one frame
        key_resp_2.frameNStart = frameN  # exact frame index
        key_resp_2.status = STARTED
        # keyboard checking is just starting
        event.clearEvents(eventType='keyboard')
    if key_resp_2.status == STARTED:
        theseKeys = event.getKeys(keyList=['space'])
       
        # check for quit:
        if "escape" in theseKeys:
            endExpNow = True
        if len(theseKeys) > 0:  # at least one key was pressed
            # a response ends the routine
            continueRoutine = False
   
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        routineTimer.reset()  # if we abort early the non-slip timer needs reset
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in Instruction_1Components:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
            continueRoutine = True
            break  # at least one component has not yet finished
   
    # check for quit (the Esc key)
    if endExpNow or event.getKeys(keyList=["escape"]):
        core.quit()
   
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()
    else:  # this Routine was not non-slip safe so reset non-slip timer
        routineTimer.reset()

#-------Ending Routine "Instruction_1"-------
for thisComponent in Instruction_1Components:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)

#------Prepare to start Routine "Instruction_2"-------
t = 0
Instruction_2Clock.reset()  # clock
frameN = -1
# update component parameters for each repeat
key_resp_3 = event.BuilderKeyResponse()  # create an object of type KeyResponse
key_resp_3.status = NOT_STARTED
# keep track of which components have finished
Instruction_2Components = []
Instruction_2Components.append(text_2)
Instruction_2Components.append(key_resp_3)
for thisComponent in Instruction_2Components:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

#-------Start Routine "Instruction_2"-------
continueRoutine = True
while continueRoutine:
    # get current time
    t = Instruction_2Clock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
   
    # *text_2* updates
    if t >= 0.0 and text_2.status == NOT_STARTED:
        # keep track of start time/frame for later
        text_2.tStart = t  # underestimates by a little under one frame
        text_2.frameNStart = frameN  # exact frame index
        text_2.setAutoDraw(True)
   
    # *key_resp_3* updates
    if t >= 0.0 and key_resp_3.status == NOT_STARTED:
        # keep track of start time/frame for later
        key_resp_3.tStart = t  # underestimates by a little under one frame
        key_resp_3.frameNStart = frameN  # exact frame index
        key_resp_3.status = STARTED
        # keyboard checking is just starting
        event.clearEvents(eventType='keyboard')
    if key_resp_3.status == STARTED:
        theseKeys = event.getKeys(keyList=['space'])
       
        # check for quit:
        if "escape" in theseKeys:
            endExpNow = True
        if len(theseKeys) > 0:  # at least one key was pressed
            # a response ends the routine
            continueRoutine = False
   
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        routineTimer.reset()  # if we abort early the non-slip timer needs reset
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in Instruction_2Components:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
            continueRoutine = True
            break  # at least one component has not yet finished
   
    # check for quit (the Esc key)
    if endExpNow or event.getKeys(keyList=["escape"]):
        core.quit()
   
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()
    else:  # this Routine was not non-slip safe so reset non-slip timer
        routineTimer.reset()

#-------Ending Routine "Instruction_2"-------
for thisComponent in Instruction_2Components:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)

#------Prepare to start Routine "Instruction_3"-------
t = 0
Instruction_3Clock.reset()  # clock
frameN = -1
# update component parameters for each repeat
key_resp_4 = event.BuilderKeyResponse()  # create an object of type KeyResponse
key_resp_4.status = NOT_STARTED
# keep track of which components have finished
Instruction_3Components = []
Instruction_3Components.append(text_3)
Instruction_3Components.append(key_resp_4)
for thisComponent in Instruction_3Components:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

#-------Start Routine "Instruction_3"-------
continueRoutine = True
while continueRoutine:
    # get current time
    t = Instruction_3Clock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
   
    # *text_3* updates
    if t >= 0.0 and text_3.status == NOT_STARTED:
        # keep track of start time/frame for later
        text_3.tStart = t  # underestimates by a little under one frame
        text_3.frameNStart = frameN  # exact frame index
        text_3.setAutoDraw(True)
   
    # *key_resp_4* updates
    if t >= 0.0 and key_resp_4.status == NOT_STARTED:
        # keep track of start time/frame for later
        key_resp_4.tStart = t  # underestimates by a little under one frame
        key_resp_4.frameNStart = frameN  # exact frame index
        key_resp_4.status = STARTED
        # keyboard checking is just starting
        event.clearEvents(eventType='keyboard')
    if key_resp_4.status == STARTED:
        theseKeys = event.getKeys(keyList=['space'])
       
        # check for quit:
        if "escape" in theseKeys:
            endExpNow = True
        if len(theseKeys) > 0:  # at least one key was pressed
            # a response ends the routine
            continueRoutine = False
   
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        routineTimer.reset()  # if we abort early the non-slip timer needs reset
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in Instruction_3Components:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
            continueRoutine = True
            break  # at least one component has not yet finished
   
    # check for quit (the Esc key)
    if endExpNow or event.getKeys(keyList=["escape"]):
        core.quit()
   
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()
    else:  # this Routine was not non-slip safe so reset non-slip timer
        routineTimer.reset()

#-------Ending Routine "Instruction_3"-------
for thisComponent in Instruction_3Components:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)

# set up handler to look after randomisation of conditions etc
trials = data.TrialHandler(nReps=1, method='random',
    extraInfo=expInfo, originPath=None,
    trialList=data.importConditions('datasound2.xlsx'),
    seed=None, name='trials')
thisExp.addLoop(trials)  # add the loop to the experiment
thisTrial = trials.trialList[0]  # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb=thisTrial.rgb)
if thisTrial != None:
    for paramName in thisTrial.keys():
        exec(paramName + '= thisTrial.' + paramName)

for thisTrial in trials:
    currentLoop = trials
    # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
    if thisTrial != None:
        for paramName in thisTrial.keys():
            exec(paramName + '= thisTrial.' + paramName)
   
    #------Prepare to start Routine "trial1_2"-------
    t = 0
    trial1_2Clock.reset()  # clock
    frameN = -1
    # update component parameters for each repeat
    similarity.reset()
    sound_6.setSound(Sound)
    scaleList2 = [similarity]
   
    # keep track of which components have finished
    trial1_2Components = []
    trial1_2Components.append(text_7)
    trial1_2Components.append(similarity)
    trial1_2Components.append(sound_6)
    for thisComponent in trial1_2Components:
        if hasattr(thisComponent, 'status'):
            thisComponent.status = NOT_STARTED
   
    #-------Start Routine "trial1_2"-------
    continueRoutine = True
    while continueRoutine:
        # get current time
        t = trial1_2Clock.getTime()
        frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
        # update/draw components on each frame
       
        # *text_7* updates
        if t >= 0.0 and text_7.status == NOT_STARTED:
            # keep track of start time/frame for later
            text_7.tStart = t  # underestimates by a little under one frame
            text_7.frameNStart = frameN  # exact frame index
            text_7.setAutoDraw(True)
        # *similarity* updates
        if t > 0.0:
            similarity.draw()
            if similarity.noResponse == False:
                similarity.response = similarity.getRating()
        # start/stop sound_6
        if t >= 0.0 and sound_6.status == NOT_STARTED:
            # keep track of start time/frame for later
            sound_6.tStart = t  # underestimates by a little under one frame
            sound_6.frameNStart = frameN  # exact frame index
            sound_6.play()  # start the sound (it finishes automatically)
        count = 0
        for s in scaleList2:
            if not s.noResponse:
                count += 1
        if count == 1:
            continueRoutine = False
       
        # check if all components have finished
        if not continueRoutine:  # a component has requested a forced-end of Routine
            routineTimer.reset()  # if we abort early the non-slip timer needs reset
            break
        continueRoutine = False  # will revert to True if at least one component still running
        for thisComponent in trial1_2Components:
            if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                continueRoutine = True
                break  # at least one component has not yet finished
       
        # check for quit (the Esc key)
        if endExpNow or event.getKeys(keyList=["escape"]):
            core.quit()
       
        # refresh the screen
        if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
            win.flip()
        else:  # this Routine was not non-slip safe so reset non-slip timer
            routineTimer.reset()
   
    #-------Ending Routine "trial1_2"-------
    for thisComponent in trial1_2Components:
        if hasattr(thisComponent, "setAutoDraw"):
            thisComponent.setAutoDraw(False)
    # store data for trials (TrialHandler)
    trials.addData('similarity.response', similarity.getRating())
    sound_6.stop()
    thisExp.nextEntry()
   
# completed 1 repeats of 'trials'

# get names of stimulus parameters
if trials.trialList in ([], [None], None):  params = []
else:  params = trials.trialList[0].keys()
# save data for this loop
trials.saveAsExcel(filename + '.xlsx', sheetName='trials',
    stimOut=params,
    dataOut=['n','all_mean','all_std', 'all_raw'])

#------Prepare to start Routine "End"-------
t = 0
EndClock.reset()  # clock
frameN = -1
# update component parameters for each repeat
key_resp_10 = event.BuilderKeyResponse()  # create an object of type KeyResponse
key_resp_10.status = NOT_STARTED
# keep track of which components have finished
EndComponents = []
EndComponents.append(text_12)
EndComponents.append(key_resp_10)
for thisComponent in EndComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

#-------Start Routine "End"-------
continueRoutine = True
while continueRoutine:
    # get current time
    t = EndClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
   
    # *text_12* updates
    if t >= 0.0 and text_12.status == NOT_STARTED:
        # keep track of start time/frame for later
        text_12.tStart = t  # underestimates by a little under one frame
        text_12.frameNStart = frameN  # exact frame index
        text_12.setAutoDraw(True)
   
    # *key_resp_10* updates
    if t >= 0.0 and key_resp_10.status == NOT_STARTED:
        # keep track of start time/frame for later
        key_resp_10.tStart = t  # underestimates by a little under one frame
        key_resp_10.frameNStart = frameN  # exact frame index
        key_resp_10.status = STARTED
        # keyboard checking is just starting
        event.clearEvents(eventType='keyboard')
    if key_resp_10.status == STARTED:
        theseKeys = event.getKeys(keyList=['space'])
       
        # check for quit:
        if "escape" in theseKeys:
            endExpNow = True
        if len(theseKeys) > 0:  # at least one key was pressed
            # a response ends the routine
            continueRoutine = False
   
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        routineTimer.reset()  # if we abort early the non-slip timer needs reset
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in EndComponents:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
            continueRoutine = True
            break  # at least one component has not yet finished
   
    # check for quit (the Esc key)
    if endExpNow or event.getKeys(keyList=["escape"]):
        core.quit()
   
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()
    else:  # this Routine was not non-slip safe so reset non-slip timer
        routineTimer.reset()

#-------Ending Routine "End"-------
for thisComponent in EndComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)

win.close()
core.quit()

Timbre-Oboe.py (21.9 KB)

Hi @ericabisesi, that would depend on what you are trying to achieve. Do you want the count down to be visible during the whole trial? If so, just add a new text component, and define the text in the text component as nTrialsRemaining. E.g.,

# Add this after text_7 is created. Leave text blank for now, and set text on every trial
text_8 = visual.TextStim(win=win, ori=0, name='text_7',
    text=u"",    font='Arial',
    pos=[0, 0.2], height=0.07, wrapWidth=None,
    color='white', colorSpace='rgb', opacity=1,
    depth=0.0)

# At the beginning of a routine
text_8.setText(text=nTrialsRemaining)
text_8.setAutoDraw(True)

# At end of routine
text_8.setAutoDraw(False)

This can all be done easily in Builder using a text and code component.

Hi David,

I just want to double check that my first question was clear.

In an old post called “Visible Countdown Timer and Stimuli Progression” I read that there are some conditions to be written into the textbox, including a proper formatting for the text and a python instruction for the countdown.

Is this automatically executed when the condition trialsRemaining = trials.nRemaining is written in the right place?

Thanks, Erica

Hi David, thanks.

The answer to your question is YES.

I am sorry but I am new in python…

Well, I created a new textbox and pasted your lines according to the picture attached.

I supposed I did something wrong, as (1) the new information lasts only 1 sec (but it’s written so in the apposite field, right?), and (2) it does not display the desired number but the whole set of instructions.

Do you mean to include all the text you wrote into the field “Text” in the screenshot?

Where I am doing mistake? I am sure I misunderstood…

What do you mean by “usind a text and code component”?

I also tried to paste the 2nd and 3rd instructions into the “code” - “Each Frame” box, but it crasches.

The error message is:
File “/Users/Erica/Desktop/Desktop-120518/Francia/Progetto Parigi/Experiment TIMBRE/Trial-Oboe_lastrun.py”, line 413, in
text_8.setText(text=nTrialsRemaining)
NameError: name ‘nTrialsRemaining’ is not defined

Erica

Hi @ericabisesi

I think my response may be confusing.You would copy this code into a code component, not a text component. So what you want to do in Builder is:

  1. Create new text component called text_8, and leave it blank, and set the duration as blank
  2. Set the text box within the text component to “set every repeat”
  3. In the text box of the text component add:
$trials.nRemaning

The dollar sign shows tells psychopy to treat the text as a variable, rather than to literally print “$trials.nRemaning”.

Dear David,

I followed you but it is still not working.

The error message is:

**text_8.setText(trials.**nRemaning)
AttributeError: ‘TrialHandler’ object has no attribute 'nRemaning’

QUESTION 1) I attach a screenshot of the new textbox I created. Is it correct?

QUESTION 2) Additionally, I have not understood what should I do with the code you sent me last time, that is:


# Add this after text_7 is created. Leave text blank for now, and set text on every trial text_8 = visual.TextStim(win=win, ori=0, name='text_7', text=u"", font='Arial', pos=[0, 0.2], height=0.07, wrapWidth=None, color='white', colorSpace='rgb', opacity=1, depth=0.0) # At the beginning of a routine text_8.setText(text=
nTrialsRemaining) text_8.setAutoDraw(True) # At end of routine text_8.setAutoDraw(False)

I pasted it into the same code component I already had, intuitively splitted into three parts (Begin Routine, Each Frame and End Routine). But I am not sure. Screenshots are also attached.

Anyway, the error message above is independent on the addition of these code segments.

Thanks for your patience,

Erica

Hi @ericabisesi. Yes the first text box is correct however you are getting the error because of a spelling error in my example, should be $trials.nRemaining. Please ignore the previous coding example and only follow steps in the previous msg. The text component in Builder will give the desired effect without the need for coding.

Hi David,

the problem is fixed now.

Thanks a lot!

Erica

Dear David,

may I ask you to help me to get an answer to this topic: How to play and repeat stimuli after manual click?

I don’t know what is the procedure when no answer is provided, then I just ask for a suggestion.

Thanks, Erica