How do I get Moving window presentation in self paced reading task?

Win10
PsychoPy version 1.84.2

Hi

Is it possible to build a moving window presentation for self paced reading task? The words are being presented in the center of the screen by default. How can I get the words one by one from left to right? Somewhat Like the gif below but without the masking dashes.

Thank you for your time.

I would start by Googling “psychopy self-paced reading task” and then perhaps following the results to a link like this:

https://groups.google.com/forum/#!topic/psychopy-users/sjX7_Oa_WXc

Hi
I am trying to make the same “masked self-paced reading task” too.
And I did read through the posts you linked and other people trying to do similar things in the discourse page.

https://groups.google.com/forum/#!topic/psychopy-users/sjX7_Oa_WXc24

But, what completes this task is that the lines masking the words in the sentence should not move just like the gif above (and below).

This is why it is called “moving window” in linguistics field I believe. I can make sentences masked with dashes and collect separate RTs from previous links but I cannot make those masking dashes stay still while I move through the sentence. It seems like it is aligning itself automatically but I couldn’t come up with an idea to set it still.

Would there be a solution to this problem?

Yours sincerely,

Kyung

What I tried was using defined integer for the number of dashes to cover the words.
This solved the problem of “different number of dashes masking different word length”.
You can see that I put ‘6’ instead of len(word) to do so.

sentenceList = sentence.split() 
# this breaks your sentence's single string of characters into a list of individual 
# words, e.g. 'The quick brown fox.' becomes ['The', 'quick', 'brown', 'fox.'] 

# keep track of which word we are up to: 
wordNumber = -1 # -1 as we haven't started yet 

# now define a function which we can use here and later on to replace letters with '-': 

def replaceWithdash(textList, currentWordNumber): 
    
    dashSentence = '' 
    for index, word in enumerate(textList): # cycle through the words and their index numbers 
        if index != currentWordNumber: 
            dashSentence = dashSentence + '-' * 6 + ' ' # add a string of dash characters 
        else: 
            dashSentence = dashSentence + word # except for the current word 

    return dashSentence # yields the manipulated sentence 

# now at the very beginning of the trial, we need to run this function for the 
# first time. As the current word number is -1, it should make all words '-'. 
# Use the actual name of your Builder text component here: 

text.text = replaceWithdash(sentenceList, wordNumber) 

# In the Builder interface, specify a "constant" value for the text content, e.g. 
# 'test', so it doesn't conflict with our code.

With this, I could make the length an array of the dashes constant before the first word is revealed.
But to accomplish true ‘moving window’, array(x,y position) of the dashes should stay still. This is not achieved because once a word is shown, their true length is revealed and somehow their variable length influence the array of other yet to be revealed(or masked again) dashes to move a little bit. I attached the screenshots to describe this. FYI the characters are Korean.

Above is the first screen with words covered by identical number(6) of dashes. So it does not reveal any length information of the masked sentence.

Two screens compared after different length of words are revealed. You can see that the position of the remaining dashes when 4-letter-word(count a letter like Chinese character) is revealed is different from that of 2-letter-word. I drew red lines to show that it has moved.

Right now, I couldn’t think of a way to solve this within code component. I also tried putting a white line image in the background and unmasking each word on that line. But this poses another methodological problems(e.g. small portion of lines shown at the left side of the very first word, which harms the cognitive presumption that there should be no masking at the left of the very first word of the sentence).

Thank you for your time.

Kyung

Hello Kyung,

Are you able to use a monospaced Korean font? i.e. “typewriter”-like fonts where each character takes up the same horizontal space, regardless of the width of its glyph. e.g. compare the width of these runs of four characters in this proportional width font:

||||
iiii
OOOO
----

to this monospace font:

||||
iiii
OOOO
----

Dear Michael,

Thank you for the reply.

I just tried a monospace Korean font(NanumGothicCoding) but still the dashes are moving.
I think it is not the matter of width of a single letter but the number of letters in one word.
When masked, it doesn’t matter whether the word is 4-letter word or 2-letter word because it is only represented by 6 dashes. But once unmasked, the length of a word come into play because it has to fit in with other masked dashes. It doesn’t seem easy to me too since it looks like the problem is regarding mechanism of how the computer deals with inter-word gaps.
The ultimate way is to make every word(or whole sentence with each word revealed) into image but this will take up great amount of time. Or, if I should give up using ‘sentence.split()’ code, maybe we can store every word separated in Excel from the first time and code it that way. I didn’t get to there yet but maybe worth trying…

Yours sincerely,

Kyung

I would have though that you would want the number of dashes to match the number of characters. Otherwise, there will naturally be movement, as the total number of characters is changing from moment to moment. i.e. the total number of dashes and spaces should be equal to the total number of masked characters and spaces.

Dear Michael,

Thank you for the reply. But this “movement” happens regardless of how I mask the words.
It is not important whether the number of the dash is 6 or 7. I just wanted to exclude any word length information as an experimental manipulation. And the movement still happens even if I set the number of the dash to its length. The screenshot below depicts that this moving phenomenon still happens even if I mask the words by their length.

You can see that as the first 4-letter word is revealed, the whole dash array moves rightward. So it is not about how many dashes I use.

Edit: I did some additional search and there is two points to be mentioned.

  1. The Korean monospace font I am currently using(NaunumGothicCoding) is not monospaced over the different category of characters.

    As you can see, Koreans themselves, English themselves and numbers share same width but not universal. Especially special characters’ width is different from that of Korean. I could think of masking by a meaningless Korean letter but I coudln’t use Korean character in the code component.

  2. Even if the mask(dashes etc.) and the Korean letter share same width, it moves. Since the Korean words are consisted of different number of Korean letters, even if they are masked by same length, once the words are revealed, they are realigned by newly revealed word width.

One possible hypothesis is that if I find a special character that has exactly half the width of Korean letter, I could use it. If I use that character to fill the space with that same character too, I think I can manage it to stay still.

Yours sincerely,
Kyung.

Problem solved!

Following are the gif of my final result and the code I used. I only changed the part from ‘Begin Routine’ tap of the code component. The original code is from Michael from this link:
https://groups.google.com/forum/#!topic/psychopy-users/sjX7_Oa_WXc


def replaceWithdash(textList, currentWordNumber):     
    dashSentence = ''
    for index, word in enumerate(textList): # cycle through the words and their index numbers 
        if index != currentWordNumber: 
            dashSentence = dashSentence + '--' * len(word) + '--' # add two strings of dash characters 
        elif wordNumber==5: 
            dashSentence = ' ' + dashSentence + word + '.'# the last word will appear with a period
        else:
            dashSentence = ' ' + dashSentence + word + ' ' # except for the current word 
    return dashSentence # yields the manipulated sentence

Thank you for all the advice, Michael. Your answers led me to find a way to solve this problem even with those obstacles above.

Yours sincerely,
Kyung.

2 Likes