psychopy.org | Reference | Downloads | Github

Data saving via TrialHandler

I’m coding my first experiment in PsychoPy. I’m using TrialHandler to control the stimuli and save the data, but when I try to output the data, I get the error “TypeError: argument of type ‘int’ is not iterable”. Can someone please point out what I am doing wrong?
Note: I get the same error no matter which text mode I use to output the data: saveAsText, printAsText, or saveAsWideText.

from __future__ import division
from __future__ import print_function
from builtins import range
from psychopy import core, visual, gui, data, event
from psychopy.tools.filetools import fromFile, toFile 
import numpy, random # standard python libraries

# list default parameters here
windowSize = [400, 400]
fixationSeconds = 0.5
stimulusSeconds = .5
trialsPerCell = 2

# insert data saving information here
outputFile = 'gistWide.txt'

# create window and stimuli
win = visual.Window(windowSize, allowGUI = True, monitor = 'testMonitor', units = 'deg')
fps = win.getActualFrameRate()
print(fps)
fixationFrames = int(fps*fixationSeconds)
print(fixationFrames)
stimulusFrames = int(fps*stimulusSeconds)
print(stimulusFrames)
fixation = visual.TextStim(win, pos = [0,0], text = '+')
postStimulus= visual.ImageStim(win, image = 'anatomy1.png')

# setup trial handler
abnormal = [0,1] # 0 = normal, 1 = abnormal
trials = data.TrialHandler(abnormal, trialsPerCell, method = "fullRandom")
trials.data.addDataType('accuracy')
trials.data.addDataType('RT')
clockRT = core.Clock() # initialize reaction times

for thisTrial in trials:
    # present a single cycle
    stimulus = visual.ImageStim(win, image = 'prostate1.png')
    for f in range(fixationFrames):
        fixation.draw()
        win.flip()    
    for f in range(stimulusFrames):
        stimulus.draw()
        win.flip()
    postStimulus.draw()
    win.flip()
    clockRT.reset()
    
    # collect response
    # let's say "z" is for abnormal/present and "/" is for normal/absent
    accuracy = None
    while accuracy == None:
        allKeys = event.waitKeys(timeStamped = clockRT)
        for keyTuple in allKeys:
            [thisKey, thisRT] = keyTuple
            print(thisKey)
            print(trials.thisTrial)
            if thisKey == 'z':
                if trials.thisTrial == 1: accuracy = 1
                else: accuracy = 0
            elif thisKey == 'slash':
                if trials.thisTrial == 1: accuracy = 0
                else: accuracy = 1
            elif thisKey in ['q', 'escape']:
                core.quit()
        event.clearEvents()
    trials.addData('accuracy', accuracy)
    trials.addData('RT', thisRT)

df = trials.saveAsWideText(fileName = outputFile)

core.quit()

Please post the entire error message (all the lines) not just the final bit about not being iterable. We would need to see at what point this error occurred to be able to help.

Traceback (most recent call last):
  File "H:\Experiments\Programming\gist1.py", line 79, in <module>
    df = trials.saveAsWideText(fileName = outputFile)
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy\data.py", line 1364, in saveAsWideText
    if self.trialList[tti] and prmName in self.trialList[tti]:
TypeError: argument of type 'int' is not iterable

Ah! OK, the problem is that the trialList is expecting a list of dictionaries and you’ve given it a list of integers. Do this:

conditions = [{'abnormal':0}, {'abnormal':1}]
trials = data.TrialHandler(abnormal, trialsPerCell, method = "fullRandom")
trials.data.addDataType('accuracy')

or, ultimately, you may want to create the excel file for your conditions and then do

conditions = data.importConditions('conds.xlsx')

Either of these should get rid of the issue.

Thanks! That worked.