Self Paced Reading Task with questions

Dear sir,

First of all, hello. I am a new user of Psychopy and I am working with it for my PhD thesis. I am carrying out a self paced reading task but I cant handle the fact that my words coming out one by one in each sentence followed by a question. Can you help me with this, it is a little bit urgent? By the way I have read all the forums about self paced reading task but I am not competent in writing codes. I have read this post as well Google Groups but I am stuck in the following error:

“trials_2 = data.TrialHandler(nReps=len(word_list), method=‘sequential’,
NameError: name ‘word_list’ is not defined”

the following is my experiement, can you help me pls?

sprt.psyexp (11.1 KB)

thx in advance…

2 Likes

Hi @dilsah_kalay, it would help if you encase your code in backticks - see here.

I believe you are receiving the NameError because your Sentence variable, which defines word_list is not capitalized in your code component. Python code is case sensitive, so sensitive is not the same as Sensitive.

Hi @dvbridges, I capitalized ‘Sentence’ variable but nothing changed. Actually, when I put the question routine before the trail it works but when I put it after, it doesn’t work… I don’t know what to do… or what the problem is…

Ok thanks, @dilsah_kalay. Could you please post your condition file?

@dvbridges of course… thx again for your help…

practice.xlsx (9.9 KB)

Thanks @dilsah_kalay. I think there were several factors making this experiment fail. However, if you rethink the logic of the experiment, you can successfully run the self paced reading task in the way you want. See the example attached. You do not need nested loops that repeat routines based on the word count. Instead, you can use a code component that will create a list of words in each sentence, and present a new word on every key press (‘space’ is used to move forward one word in this example). When the final word is presented, the routine breaks and moves on to the question routine.
sprt_example.psyexp (8.9 KB)

1 Like

Thx @dvbridges i will have a look at it, but can you also attach the condition file as an example. I would appreciate if you could…

Thx again… :wink:

@dilsah_kalay, its ok you can use your existing file

@dvbridges thanks a lot, I don’t know why I couldn’t insert the code but this helped a lot thank you very much… :slight_smile:

Hi again @dvbridges one more question, again thx for the setup, but esc button doesn’t work to quit the experiment during the process. I ticked the button but nothing changed? Any idea?

Thx again… :slight_smile:

Hi @dilsah_kalay, I set the letter ‘q’ to quit the experiment, e.g.,

if 'q' in kb:
    core.quit()

however you can change this to whatever you want in the code component.

@dvbridges thx it works perfectly… another and I promise the last question, when the words pass one by one it doesn’t calculate the respose times of each word. I need those times. How can I change it?

thx again… :slight_smile:

Great @dilsah_kalay. This should solve your problem. In the code component, you create an empty list for storing your code in the Start Routine tab called rtList:

word_list = Sentence.split() 
word_list.reverse() # switch the order 
event.clearEvents()
rtList = []

Then, you need to amend the code in the Each Frame tab so that the keyboard events are timestamped, that key events are indexed correctly on every frame, and stored at the appropriate time in the rtList:

while continueRoutine:
    kb = event.getKeys(timeStamped=True)
    if len(kb) > 0:
        if 'space' in kb[0]:
            try:
                nextWord = word_list.pop()
                text.setText(nextWord)
            except IndexError:
                continueRoutine = False
                rtList.append(kb[0][1])
                break
        rtList.append(kb[0][1])
        if 'q' in kb[0]:
            core.quit()
    win.flip()

Finally, in the End Routine tab. you need to run a numpy (np) function that finds the difference between the RTs in the list, because all of the RTs in the keyboard component are stored relative to the onset of the very first presentation of a text stimuli in each trial - where a trial is a presentation of a sentence + question. Note, in this version I have inserted a fixation point at the beginning of every trial to mark the trial onset, and also a time from when to collect RTs i.e., after the first button press to remove the fixation. If this is not required, the code will need to be changed a bit. Finally, run a loop that writes the RTs to a data file, in separate columns for every word:

rtList = np.ediff1d(rtList)
for rts in range(len(rtList)):
    thisExp.addData('word_{}'.format(rts), rtList[rts])

@dvbridges Is this the same code component that we created for separating each word in text stumulus (routine), in the example you have created or another code component that we need to add into the routine???

@dilsah_kalay, its the same code component. The only other change that you may want to add is a very small addition to the text component - instead of leaving it blank you may want to add a ‘+’ to mark the trial onset. Everything else is the same, so you could just insert this code into your existing code component and it will (should) work - see attached sprt_example.psyexp (9.2 KB).

@dvbridges hey again, yeah I tried it, the experiment works but the response times for each word doesn’t come up in the excell sheet. what is the problem do you think? I attached the files…_sprt_2018_Mar_24_1658.xlsx (5.8 KB)
practice.xlsx (9.9 KB)
study.xlsx (13.4 KB)
sprt.psyexp (30.8 KB)

Hi @dilsah_kalay, I see two problems. The data is not being written to the file because the trial handler is not called thisExp as it is in my example. The trial handler takes the name of the loop. In your case the loop you are interested in for test phase is called trials. However, if you simply change the name of the trial handler in the code component, there will be an error thrown because you are using the code component in another loop - the practice phase - which takes a different name trials_2. To fix this, we can catch the error and fix the problem. So, if you add the following to the End Routine tab in the code component, the error should be fixed:

rtList = np.ediff1d(rtList)
try: 
    # practice phase
    trials_2.addData('senLen', len(rtList))
    for rts in range(len(rtList)):
        trials_2.addData('word_{}'.format(rts), rtList[rts])
except NameError:
    # study phase
    trials.addData('senLen', len(rtList))
    for rts in range(len(rtList)):
        trials.addData('word_{}'.format(rts), rtList[rts])

Just to clarify, in Builder scripts, thisExp is the name of the ExperimentHandler object for the overall script. The various loops get added as TrialHandler objects to thisExp, which kind of acts like a mother ship to the individual TrialHandlers.

So thisExp.addData() should always work, and avoids having to keep track of what particular loop you are in (and I’m not sure, but might also have the advantage that all values for that variable get added to the same column in the data file, rather than a column specific to a given loop?) So maybe there is some other issue here?

2 Likes

Thanks for the clarification @Michael. It turns out the data is actually written using the experiment handler. @dilsah_kalay, when I run your experiment there are two spreadsheet files written with this experiment, one is the practice file with no RT data (this is a csv file) the other is the practice and test data (with RT data) - they have the same name but are different file types. Could you check your data outputs? If you have the excel data, then you can ignore the amendments to the code in my previous comment.

@dvbridges thnks a lot, yeah as you said all the RTs are stored in the other file but when I made a change as you said before on the End Routine tab, it worked perfectly, as well. I think both solutions are useful for me.

Thanks you very very much for your endless help. Thanks a lot… :slight_smile:

1 Like