Hi there,
I am new to Psychopy (since Monday!) and do not have any Python experience, so am using Builder. I am using Win7,PsychoPy version 3.0.0b7.
I am trying to give feedback to participants after a trial regarding whether their response was correct or incorrect. However, at the moment, the feedback is always telling them that they are incorrect.
In my study, each trial involves two pictures being shown at the same time - a shape and label. Prior to the trial, participants are instructed that certain shapes are matched with certain labels (e.g., triangle = affected hand, circle = unaffected hand, square = other (strangers) hand). Then in the trials, if the two images that they see on the screen are a correct pairing, then they are to press ‘3’ and if it is incorrect, then press ‘2’.
This is the way that I have my .xlsx spreadsheet set up:
Here is how I have things set-up in Builder..
Practice trials
Feedback:
Here are the settings for the response in the practice trial (Practice_Resp):
For the Picture_trial and the Label_trial, I have chosen “set every repeat” and the Trials loop is “random”, 1 rep, rows 0:60.
I followed a past thread about error in giving feedback (Error in giving feedback after a trial) which was very helpful and I tried all the suggestions - i.e., in case my excel CorAns values were being treated like integers instead of string variables.
Here is the output that I got when I ran the updated the program with the suggestions from the previous thread:
Running:
keys: <psychopy.event.BuilderKeyResponse object at 0x11940B50>
CorAns: 3
False
False
keys: <psychopy.event.BuilderKeyResponse object at 0x11944C30>
CorAns: 2
False
True
keys: <psychopy.event.BuilderKeyResponse object at 0x119470D0>
CorAns: 3
False
False
keys: <psychopy.event.BuilderKeyResponse object at 0x11947490>
CorAns: 2
False
True
keys: <psychopy.event.BuilderKeyResponse object at 0x119477B0>
CorAns: 3
False
False
keys: <psychopy.event.BuilderKeyResponse object at 0x119478D0>
CorAns: 3
False
False
keys: <psychopy.event.BuilderKeyResponse object at 0x11947AF0>
CorAns: 2
False
False
keys: <psychopy.event.BuilderKeyResponse object at 0x11947D10>
CorAns: 3
False
False
keys: <psychopy.event.BuilderKeyResponse object at 0x11944FF0>
CorAns: 2
False
True
keys: <psychopy.event.BuilderKeyResponse object at 0x119400D0>
CorAns: 2
False
True
This is clearly going wrong, but I’m not quite sure what to fix! It seems like it is giving a separate true or false answer for each of my stimuli (shape picture and label picture), when I what I want is for it to give a true/false answer for the stimuli pair. I suppose this might be a problem with randomisation if the stimuli are not being presented as a pair (i.e., as one row in the excel spreadsheet) and instead are being randomly sampled from the column. However, I don’t think this is the case as it was my understanding that using the set-up I have, the random function (loop) should randomly select a row. I am sure there are other problems too because I don’t know why I am getting this output for key response (<psychopy.event.BuilderKeyResponse object at 0x119400D0>
This is what I have for the code component in my feedback routine:
if Practice_Resp == CorAns:
msg = ‘Correct’
else:
msg = ‘Sorry, Incorrect’
And this is what I have for my variable component (Practice_feedback_msg):
Last, here is what I get when I click on Compile Script:
from future import absolute_import, division
from psychopy import locale_setup, sound, gui, visual, core, data, event, logging, clock
from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
STOPPED, FINISHED, PRESSED, RELEASED, FOREVER)
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
import sys # to get file system encoding
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 = ‘CRPS_SPEtask_5_Jie_deg_setttings’ # from the Builder filename that created this script
expInfo = {‘participant’: ‘’, ‘RespHand’: “[‘left’, ‘right’]”, ‘Shapelabelpairing’: “[‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’]”, ‘session’: ‘001’}
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 + u’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=‘C:\Users\stantonr\Desktop\TASH\RESEARCH PROJECTS\Visit to Charles Spence Oxford\CRPS and SPE\CRPS SPE Experiment\CRPS_SPEtask_5_Jie_deg_setttings.py’,
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=[1920, 1080], fullscr=True, screen=0,
allowGUI=False, allowStencil=False,
monitor=‘testMonitor’, color=[0,0,0], colorSpace=‘rgb’,
blendMode=‘avg’, useFBO=True)
store frame rate of monitor if we can measure it
expInfo[‘frameRate’] = win.getActualFrameRate()
if expInfo[‘frameRate’] != None:
frameDur = 1.0 / round(expInfo[‘frameRate’])
else:
frameDur = 1.0 / 60.0 # could not measure, so guess
Initialize components for Routine “Shapelabelpairs”
ShapelabelpairsClock = core.Clock()
imageShape = visual.ImageStim(
win=win, name=‘imageShape’,
image=None, mask=None,
ori=0, pos=(0, 0), size=(0.5, 0.5),
color=[1,1,1], colorSpace=‘rgb’, opacity=1,
flipHoriz=False, flipVert=False,
texRes=128, interpolate=True, depth=0.0)
Initialize components for Routine “InstrTask”
InstrTaskClock = core.Clock()
InstrTask_2 = visual.TextStim(win=win, name=‘InstrTask_2’,
text=‘A key - LEFT index finger\nPress this if the shape and label MATCH\n\nQ key - LEFT middle finger\nPress this if the shape and label DO NOT MATCH\n\nPlease be as FAST and as ACCURATE as posssible.\n\nPress any button to begin\n’,
font=‘Arial’,
pos=(0, 0), height=0.07, wrapWidth=None, ori=0,
color=‘white’, colorSpace=‘rgb’, opacity=1,
languageStyle=‘LTR’,
depth=0.0);
Initialize components for Routine “Practicetrials”
PracticetrialsClock = core.Clock()
Fix = visual.TextStim(win=win, name=‘Fix’,
text=‘+’,
font=‘Arial’,
pos=(0, 0), height=0.1, wrapWidth=None, ori=0,
color=‘white’, colorSpace=‘rgb’, opacity=1,
languageStyle=‘LTR’,
depth=0.0);
Picture_trial = visual.ImageStim(
win=win, name=‘Picture_trial’,units=‘deg’,
image=‘sin’, mask=None,
ori=0, pos=(0, 3.5), size=(3.8, 3.8),
color=[1,1,1], colorSpace=‘rgb’, opacity=1,
flipHoriz=False, flipVert=False,
texRes=128, interpolate=True, depth=-2.0)
Label_trial = visual.ImageStim(
win=win, name=‘Label_trial’,units=‘deg’,
image=‘sin’, mask=None,
ori=0, pos=(0, -3.5), size=(6.3, 3.6),
color=[1,1,1], colorSpace=‘rgb’, opacity=1,
flipHoriz=False, flipVert=False,
texRes=128, interpolate=True, depth=-3.0)
Initialize components for Routine “Feedback”
FeedbackClock = core.Clock()
#msg variable just needs some value at start
msg=‘doh’
Practice_feedback_msg = visual.TextStim(win=win, name=‘Practice_feedback_msg’,
text=‘default text’,
font=‘Arial’,
pos=(0, 0), height=0.1, wrapWidth=None, ori=0,
color=‘white’, colorSpace=‘rgb’, opacity=1,
languageStyle=‘LTR’,
depth=-1.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 “Shapelabelpairs”-------
t = 0
ShapelabelpairsClock.reset() # clock
frameN = -1
continueRoutine = True
update component parameters for each repeat
shapelabelpairs = event.BuilderKeyResponse()
keep track of which components have finished
ShapelabelpairsComponents = [imageShape, shapelabelpairs]
for thisComponent in ShapelabelpairsComponents:
if hasattr(thisComponent, ‘status’):
thisComponent.status = NOT_STARTED
-------Start Routine “Shapelabelpairs”-------
while continueRoutine:
# get current time
t = ShapelabelpairsClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *imageShape* updates
if t >= 0.0 and imageShape.status == NOT_STARTED:
# keep track of start time/frame for later
imageShape.tStart = t
imageShape.frameNStart = frameN # exact frame index
imageShape.setAutoDraw(True)
frameRemains = 0.0 + 1.0- win.monitorFramePeriod * 0.75 # most of one frame period left
if imageShape.status == STARTED and t >= frameRemains:
imageShape.setAutoDraw(False)
# *shapelabelpairs* updates
if t >= 0.0 and shapelabelpairs.status == NOT_STARTED:
# keep track of start time/frame for later
shapelabelpairs.tStart = t
shapelabelpairs.frameNStart = frameN # exact frame index
shapelabelpairs.status = STARTED
# keyboard checking is just starting
win.callOnFlip(shapelabelpairs.clock.reset) # t=0 on next screen flip
event.clearEvents(eventType='keyboard')
if shapelabelpairs.status == STARTED:
theseKeys = event.getKeys()
# check for quit:
if "escape" in theseKeys:
endExpNow = True
if len(theseKeys) > 0: # at least one key was pressed
if shapelabelpairs.keys == []: # then this was the first keypress
shapelabelpairs.keys = theseKeys[0] # just the first key pressed
shapelabelpairs.rt = shapelabelpairs.clock.getTime()
# 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
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in ShapelabelpairsComponents:
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()
-------Ending Routine “Shapelabelpairs”-------
for thisComponent in ShapelabelpairsComponents:
if hasattr(thisComponent, “setAutoDraw”):
thisComponent.setAutoDraw(False)
check responses
if shapelabelpairs.keys in [‘’, , None]: # No response was made
shapelabelpairs.keys=None
thisExp.addData(‘shapelabelpairs.keys’,shapelabelpairs.keys)
if shapelabelpairs.keys != None: # we had a response
thisExp.addData(‘shapelabelpairs.rt’, shapelabelpairs.rt)
thisExp.nextEntry()
the Routine “Shapelabelpairs” was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
------Prepare to start Routine “InstrTask”-------
t = 0
InstrTaskClock.reset() # clock
frameN = -1
continueRoutine = True
update component parameters for each repeat
key_resp_InstrTask = event.BuilderKeyResponse()
keep track of which components have finished
InstrTaskComponents = [InstrTask_2, key_resp_InstrTask]
for thisComponent in InstrTaskComponents:
if hasattr(thisComponent, ‘status’):
thisComponent.status = NOT_STARTED
-------Start Routine “InstrTask”-------
while continueRoutine:
# get current time
t = InstrTaskClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *InstrTask_2* updates
if t >= 0.0 and InstrTask_2.status == NOT_STARTED:
# keep track of start time/frame for later
InstrTask_2.tStart = t
InstrTask_2.frameNStart = frameN # exact frame index
InstrTask_2.setAutoDraw(True)
# *key_resp_InstrTask* updates
if t >= 0.0 and key_resp_InstrTask.status == NOT_STARTED:
# keep track of start time/frame for later
key_resp_InstrTask.tStart = t
key_resp_InstrTask.frameNStart = frameN # exact frame index
key_resp_InstrTask.status = STARTED
# keyboard checking is just starting
event.clearEvents(eventType='keyboard')
if key_resp_InstrTask.status == STARTED:
theseKeys = event.getKeys()
# 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
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in InstrTaskComponents:
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()
-------Ending Routine “InstrTask”-------
for thisComponent in InstrTaskComponents:
if hasattr(thisComponent, “setAutoDraw”):
thisComponent.setAutoDraw(False)
the Routine “InstrTask” was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
set up handler to look after randomisation of conditions etc
Trials = data.TrialHandler(nReps=1, method=‘random’,
extraInfo=expInfo, originPath=-1,
trialList=data.importConditions(‘Conditions_2.xlsx’, selection=‘0:60’),
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:
exec(‘{} = thisTrial[paramName]’.format(paramName))
for thisTrial in Trials:
currentLoop = Trials
# abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
if thisTrial != None:
for paramName in thisTrial:
exec(‘{} = thisTrial[paramName]’.format(paramName))
# ------Prepare to start Routine "Practicetrials"-------
t = 0
PracticetrialsClock.reset() # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
Practice_Resp = event.BuilderKeyResponse()
Picture_trial.setImage(Picture)
Label_trial.setImage(Label)
# keep track of which components have finished
PracticetrialsComponents = [Fix, Practice_Resp, Picture_trial, Label_trial]
for thisComponent in PracticetrialsComponents:
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# -------Start Routine "Practicetrials"-------
while continueRoutine:
# get current time
t = PracticetrialsClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *Fix* updates
if t >= 0.0 and Fix.status == NOT_STARTED:
# keep track of start time/frame for later
Fix.tStart = t
Fix.frameNStart = frameN # exact frame index
Fix.setAutoDraw(True)
# *Practice_Resp* updates
if t >= 0.0 and Practice_Resp.status == NOT_STARTED:
# keep track of start time/frame for later
Practice_Resp.tStart = t
Practice_Resp.frameNStart = frameN # exact frame index
Practice_Resp.status = STARTED
# keyboard checking is just starting
win.callOnFlip(Practice_Resp.clock.reset) # t=0 on next screen flip
event.clearEvents(eventType='keyboard')
if Practice_Resp.status == STARTED:
theseKeys = event.getKeys(keyList=['2', '3'])
# check for quit:
if "escape" in theseKeys:
endExpNow = True
if len(theseKeys) > 0: # at least one key was pressed
if Practice_Resp.keys == []: # then this was the first keypress
Practice_Resp.keys = theseKeys[0] # just the first key pressed
Practice_Resp.rt = Practice_Resp.clock.getTime()
# was this 'correct'?
if (Practice_Resp.keys == str(CorAns)) or (Practice_Resp.keys == CorAns):
Practice_Resp.corr = 1
else:
Practice_Resp.corr = 0
# a response ends the routine
continueRoutine = False
# *Picture_trial* updates
if t >= 1.0 and Picture_trial.status == NOT_STARTED:
# keep track of start time/frame for later
Picture_trial.tStart = t
Picture_trial.frameNStart = frameN # exact frame index
Picture_trial.setAutoDraw(True)
frameRemains = 1.0 + 0.20- win.monitorFramePeriod * 0.75 # most of one frame period left
if Picture_trial.status == STARTED and t >= frameRemains:
Picture_trial.setAutoDraw(False)
# *Label_trial* updates
if t >= 1.0 and Label_trial.status == NOT_STARTED:
# keep track of start time/frame for later
Label_trial.tStart = t
Label_trial.frameNStart = frameN # exact frame index
Label_trial.setAutoDraw(True)
frameRemains = 1.0 + 0.20- win.monitorFramePeriod * 0.75 # most of one frame period left
if Label_trial.status == STARTED and t >= frameRemains:
Label_trial.setAutoDraw(False)
# 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 PracticetrialsComponents:
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()
# -------Ending Routine "Practicetrials"-------
for thisComponent in PracticetrialsComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
# check responses
if Practice_Resp.keys in ['', [], None]: # No response was made
Practice_Resp.keys=None
# was no response the correct answer?!
if str(CorAns).lower() == 'none':
Practice_Resp.corr = 1; # correct non-response
else:
Practice_Resp.corr = 0; # failed to respond (incorrectly)
# store data for Trials (TrialHandler)
Trials.addData('Practice_Resp.keys',Practice_Resp.keys)
Trials.addData('Practice_Resp.corr', Practice_Resp.corr)
if Practice_Resp.keys != None: # we had a response
Trials.addData('Practice_Resp.rt', Practice_Resp.rt)
# the Routine "Practicetrials" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
# ------Prepare to start Routine "Feedback"-------
t = 0
FeedbackClock.reset() # clock
frameN = -1
continueRoutine = True
routineTimer.add(1.500000)
# update component parameters for each repeat
if Practice_Resp == CorAns:
msg = 'Correct'
else:
msg = 'Sorry, Incorrect'
print("keys: %r" %(Practice_Resp))
print("CorAns: %r" %(CorAns))
print(CorAns == Practice_Resp.keys)
print(str(CorAns) == Practice_Resp.keys)
Practice_feedback_msg.setText(msg)
# keep track of which components have finished
FeedbackComponents = [Practice_feedback_msg]
for thisComponent in FeedbackComponents:
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# -------Start Routine "Feedback"-------
while continueRoutine and routineTimer.getTime() > 0:
# get current time
t = FeedbackClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *Practice_feedback_msg* updates
if t >= 0.5 and Practice_feedback_msg.status == NOT_STARTED:
# keep track of start time/frame for later
Practice_feedback_msg.tStart = t
Practice_feedback_msg.frameNStart = frameN # exact frame index
Practice_feedback_msg.setAutoDraw(True)
frameRemains = 0.5 + 1.0- win.monitorFramePeriod * 0.75 # most of one frame period left
if Practice_feedback_msg.status == STARTED and t >= frameRemains:
Practice_feedback_msg.setAutoDraw(False)
# 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 FeedbackComponents:
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()
# -------Ending Routine "Feedback"-------
for thisComponent in FeedbackComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
thisExp.nextEntry()
completed 1 repeats of ‘Trials’
these shouldn’t be strictly necessary (should auto-save)
thisExp.saveAsWideText(filename+‘.csv’)
thisExp.saveAsPickle(filename)
logging.flush()
make sure everything is closed down
thisExp.abort() # or data files will save again on exit
win.close()
core.quit()
Sorry for the long message, but I’ve tried to provide as much detail as I can to assist with your answer!
Kind regards,
Tasha






