OS (e.g. Win10): Win8 PsychoPy version (e.g. 1.84.x): 1.84.2 Standard Standalone? (y/n) If not then what?: y
I am building an experiment where participants read sentences on a word-by-word basis. I want each word to display for 0.5 seconds plus an additional 0.17 seconds per letter in the word.
The code I have is as follows (found in another helpful discussion):
checkIndex = int(t/0.5)
if checkIndex < numWords:
if checkIndex != currentWordIndex:
currentWordIndex = checkIndex
text.setText(words[currentWordIndex]) # update to the current word
I am aware that the above has each word presented for 0.5 seconds only.
This is because although @Oli’s suggestion would be fine if you were writing the experiment from scratch in your own code, when inserted into a Builder experiment, it breaks Builder’s screen refresh cycle.
i.e. any code that runs in the Each frame tab in Builder has to be completed within one screen refresh. The suggested code is supposed to run over many seconds. It will indeed do that, but also effectively pause Builder’s drawing cycle while it does so. Builder will only start refreshing the screen once the code is complete, hence showing only the last word.
What you should do is try to amend the code in your first post to account for your extra constraint of one screen refresh per letter.
Thanks, your response makes sense. I’ve been trying for the last few hours to implement your suggestion, but haven’t managed yet.
What I thought about was something like the following:
for thisWord in words: #take a word from the sentence
letters = thisWord.split() #split the word into letters
for letter in letters:
text.setText(thisWord) #for each letter in the word: display the word
But in the ‘each frame’ tab, this still aims to run over multiple frames.
Could you help? Apologies for my multiple questions - I’m trying my best to learn.
I could see the problem but was too slow/lazy to actually propose a useful solution
I would suggest, though that counting frames rather than using timers to do this (assuming @Rob’s screen is running at 60 Hz). i.e. 0.17 is far enough away from 1/60 s that timing errors will soon start accumulating…
Builder keeps a counter of the current frame number in the trial (frameN) and I guess Rob would need to count 30 frames (i.e. 0.5 s) + the number of letters in the word. And possibly add the total number of frames up to that point (from the preceding words)?
I do think it’s better to work with frames – my attempts at modifying Oli’s code have so far produced the following:
#begin routine
if i <= len(words)-1:
wordFrames = (30 + (len(words[i].split())))
for frameN in range(wordFrames):
text.setText(words[i])
i+=1
else:
continueRoutine=False
This seems to cycle through all the words at lightning speed.
#begin routine
words = sentence.split()
i = 0
frameCounter = 0 #it all happens within the same routine so make our own counter
#each frame
if i <= len(words)-1: #-1 to account for the list index starting at 0
text.setText(words[i]) #set the word
frameCount = 30 + (len(words[i].split()) * int(0.17*60)) #int because there is a leftover so the == below doesn't work. Change frameCounter set and reset to 0.2 instead of 0 if this is an issue.
frameCounter+=1 #our own frame counter
if frameCounter == frameCount:
i+=1
frameCounter = 0
else:
continueRoutine = False
Hi there. @ Rob did you manage to run this experiment in Pavlovia? I’m using a similar code to split sentences but if gives me an error for ((len(thisWord.split()) this code…did you get that too?
I used your code and adjusted it to design an RSVP sentence comprehension experiment. Thank you for the beautiful code!
However, when I try to run it on Pavlovia, I get an error saying “cannot read property map of undefined”. Do you happen to know what’s causing this error? Here’s my code:
Begin routine:
words = practice_item.split()
i = 0
frameCounter = 0
Each Frame:
if i <= len(words)-1 and words[i] == “+”: #-1 to account for the list index starting at 0
Practice_Text.setText(words[i]) #set the word
Practice_Text.color=“black”
frameCount = 31
frameCounter+=1 #our own frame counter
if frameCounter == frameCount:
i+=1
frameCounter = 0
elif i <= len(words)-1 and words[i] != “blank”: #-1 to account for the list index starting at 0
Practice_Text.setText(words[i]) #set the word
Practice_Text.color=“black”
frameCount = 20
frameCounter+=1 #our own frame counter
if frameCounter == frameCount:
i+=1
frameCounter = 0
elif i <= len(words)-1 and words[i] == “blank”: #-1 to account for the list index starting at 0
Practice_Text.setText(words[i]) #set the word
Practice_Text.color=“white”
frameCount = 13
frameCounter+=1 #our own frame counter
if frameCounter == frameCount:
i+=1
frameCounter = 0