AttributeError:'NonType' object has no attribute 'filename'

Dear group,

I am working on a 2-back test using windows and PsychoPy version 1.85.2. I have built the test user Builder and have no experience or knowledge of coding in Python.

I have successfully run the test many times (on a Mac) and I have moved it over to a windows machine and now I get the following error message

AttributeError: ‘NonType’ object has no attribute ‘filename’

When I run the test, I can access my first routine (an instructions page) but when I hit the space bar to force the end of the instructions routine I get a blank screen rather than the series of letters used for the 2-back.

I have tried rebuilding the 2-back test from scratch on the windows machine, I have checked that trials properties links to a valid conditions excel file.

I’m out of ideas and cannot find answers on this forum or stackoverflow.

Please help!

Martin

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
This experiment was created using PsychoPy2 Experiment Builder (v1.84.2),
    on August 16, 2017, at 15:27
If you publish work using this script please cite the 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 absolute_import, division
from psychopy import locale_setup, sound, gui, visual, core, data, event, logging
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__)).decode(sys.getfilesystemencoding())
os.chdir(_thisDir)

# Store info about the experiment session
expName = u'2-Back Experiment 1 New '  # 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 + 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=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=(1920, 1200), fullscr=True, screen=0,
    allowGUI=False, allowStencil=False,
    monitor=u'testMonitor', color=[1,1,1], 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 "Instructions"
InstructionsClock = core.Clock()
InstruText = visual.TextStim(win=win, name='InstruText',
    text=u'You will see a series of letters in the centre of the screen.\n\nIf the letter is the same as the letter 2 turns ago press the right arrow key.\nIf the letter is different to the letter 2 turns ago press the left arrow key.\n\nFor example:\n\nD,B,D\n(D is the same as the letter 2 letters back = left, left, right)\n\nD,C,C \n(C is not the same as two letters back = left, left, left)\n\nYou must press a key for every letter presented to you.',
    font=u'Arial',
    pos=(0, 0), height=0.08, wrapWidth=None, ori=0, 
    color=u'Black', colorSpace='rgb', opacity=1,
    depth=0.0);

# Initialize components for Routine "routine_2_Back"
routine_2_BackClock = core.Clock()
Lette = visual.TextStim(win=win, name='Lette',
    text='default text',
    font=u'Arial',
    pos=(0, 0), height=0.32, wrapWidth=None, ori=0, 
    color=u'Black', colorSpace='dkl', opacity=1,
    depth=0.0);

# Initialize components for Routine "Thank_You"
Thank_YouClock = core.Clock()
Thanks = visual.TextStim(win=win, name='Thanks',
    text=u'Thanks, the experiment is now over!',
    font=u'Arial',
    pos=(0, 0), height=0.1, wrapWidth=None, ori=0, 
    color=u'Black', 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 "Instructions"-------
t = 0
InstructionsClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
InstucResponse = event.BuilderKeyResponse()
# keep track of which components have finished
InstructionsComponents = [InstruText, InstucResponse]
for thisComponent in InstructionsComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

# -------Start Routine "Instructions"-------
while continueRoutine:
    # get current time
    t = InstructionsClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    
    # *InstruText* updates
    if t >= 0.0 and InstruText.status == NOT_STARTED:
        # keep track of start time/frame for later
        InstruText.tStart = t
        InstruText.frameNStart = frameN  # exact frame index
        InstruText.setAutoDraw(True)
    
    # *InstucResponse* updates
    if t >= 0.5 and InstucResponse.status == NOT_STARTED:
        # keep track of start time/frame for later
        InstucResponse.tStart = t
        InstucResponse.frameNStart = frameN  # exact frame index
        InstucResponse.status = STARTED
        # keyboard checking is just starting
        event.clearEvents(eventType='keyboard')
    if InstucResponse.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
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in InstructionsComponents:
        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 "Instructions"-------
for thisComponent in InstructionsComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# the Routine "Instructions" 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='sequential', 
    extraInfo=expInfo, originPath=-1,
    trialList=data.importConditions(u'Excel file - Experiment PAIN_AUGUST .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 "routine_2_Back"-------
    t = 0
    routine_2_BackClock.reset()  # clock
    frameN = -1
    continueRoutine = True
    routineTimer.add(2.500000)
    # update component parameters for each repeat
    Lette.setText(Letter )
    key_resp_2 = event.BuilderKeyResponse()
    # keep track of which components have finished
    routine_2_BackComponents = [Lette, key_resp_2]
    for thisComponent in routine_2_BackComponents:
        if hasattr(thisComponent, 'status'):
            thisComponent.status = NOT_STARTED
    
    # -------Start Routine "routine_2_Back"-------
    while continueRoutine and routineTimer.getTime() > 0:
        # get current time
        t = routine_2_BackClock.getTime()
        frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
        # update/draw components on each frame
        
        # *Lette* updates
        if t >= 0.5 and Lette.status == NOT_STARTED:
            # keep track of start time/frame for later
            Lette.tStart = t
            Lette.frameNStart = frameN  # exact frame index
            Lette.setAutoDraw(True)
        frameRemains = 0.5 + 0.5- win.monitorFramePeriod * 0.75  # most of one frame period left
        if Lette.status == STARTED and t >= frameRemains:
            Lette.setAutoDraw(False)
        
        # *key_resp_2* updates
        if t >= 0.5 and key_resp_2.status == NOT_STARTED:
            # keep track of start time/frame for later
            key_resp_2.tStart = t
            key_resp_2.frameNStart = frameN  # exact frame index
            key_resp_2.status = STARTED
            # keyboard checking is just starting
            win.callOnFlip(key_resp_2.clock.reset)  # t=0 on next screen flip
            event.clearEvents(eventType='keyboard')
        frameRemains = 0.5 + 2- win.monitorFramePeriod * 0.75  # most of one frame period left
        if key_resp_2.status == STARTED and t >= frameRemains:
            key_resp_2.status = STOPPED
        if key_resp_2.status == STARTED:
            theseKeys = event.getKeys(keyList=['left', 'right'])
            
            # check for quit:
            if "escape" in theseKeys:
                endExpNow = True
            if len(theseKeys) > 0:  # at least one key was pressed
                key_resp_2.keys = theseKeys[-1]  # just the last key pressed
                key_resp_2.rt = key_resp_2.clock.getTime()
                # was this 'correct'?
                if (key_resp_2.keys == str(CorrAns)) or (key_resp_2.keys == CorrAns):
                    key_resp_2.corr = 1
                else:
                    key_resp_2.corr = 0
        
        # 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 routine_2_BackComponents:
            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 "routine_2_Back"-------
    for thisComponent in routine_2_BackComponents:
        if hasattr(thisComponent, "setAutoDraw"):
            thisComponent.setAutoDraw(False)
    # check responses
    if key_resp_2.keys in ['', [], None]:  # No response was made
        key_resp_2.keys=None
        # was no response the correct answer?!
        if str(CorrAns).lower() == 'none':
           key_resp_2.corr = 1  # correct non-response
        else:
           key_resp_2.corr = 0  # failed to respond (incorrectly)
    # store data for trials (TrialHandler)
    trials.addData('key_resp_2.keys',key_resp_2.keys)
    trials.addData('key_resp_2.corr', key_resp_2.corr)
    if key_resp_2.keys != None:  # we had a response
        trials.addData('key_resp_2.rt', key_resp_2.rt)
    thisExp.nextEntry()
    
# completed 1 repeats of 'trials'


# ------Prepare to start Routine "Thank_You"-------
t = 0
Thank_YouClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
key_resp_3 = event.BuilderKeyResponse()
# keep track of which components have finished
Thank_YouComponents = [Thanks, key_resp_3]
for thisComponent in Thank_YouComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

# -------Start Routine "Thank_You"-------
while continueRoutine:
    # get current time
    t = Thank_YouClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    
    # *Thanks* updates
    if t >= 0.5 and Thanks.status == NOT_STARTED:
        # keep track of start time/frame for later
        Thanks.tStart = t
        Thanks.frameNStart = frameN  # exact frame index
        Thanks.setAutoDraw(True)
    frameRemains = 0.5 + 5- win.monitorFramePeriod * 0.75  # most of one frame period left
    if Thanks.status == STARTED and t >= frameRemains:
        Thanks.setAutoDraw(False)
    
    # *key_resp_3* updates
    if t >= 0.5 and key_resp_3.status == NOT_STARTED:
        # keep track of start time/frame for later
        key_resp_3.tStart = t
        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
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in Thank_YouComponents:
        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 "Thank_You"-------
for thisComponent in Thank_YouComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# the Routine "Thank_You" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
# 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()

Was that the entire error message or were there other lines? Could you copy/paste the entire thing please?
cheers,
Jon

Hi Jon,

Thanks for the reply. The full message in the coder view output is:

welcome to psychopy2!

v1.85.2

Traceback (most recent call last):

File “C:\Program Files (x86)\PsychoPy2\lib\site_packages\psychopy\app\coder\codser.py”, line 2527, in runfile
fullpath = self.currentDoc.filename
AttributeError: ‘NoneType’ object has no attribute ‘filename’

When I run it from the builder I press escape at the blank screen (when I should have the 2-back stimuli) and the PsychPy output reads

###########################Running C:\Pain\Pain_lastrun.py##########################
pyo version 0.8.0 (uses single precision)

I have tried upacking the demos and I have run the Stroop test and this runs with no issues.

Thanks

Maritn

sorry, codser.py should read coder.py

The filename message looks like you’re trying to run a file without having a file open in coder window!

The Builder experiment looks like it’s running fine, and has no error messages. You say you press “Escape” but that is the key that PsychoPy uses to indicate “end the experiment”. Maybe you’re just exiting the experiment?

Hi Jon,

I had to exit the experiment because it was freezing on a blank screen. I downloaded the v1.85.3 update and the problem has now gone.

Much appreciated and thanks again for PsychoPy and for providing such quick responses.

Maritn