【问题标题】:Python; add blank screen after words in a split sentencePython;在拆分句子中的单词后添加空白屏幕
【发布时间】:2016-05-24 14:49:00
【问题描述】:

我正在构建一个 Psychopy 实验,一次呈现一个单词的句子,然后呈现一个单独的单词来收集响应。我对第一部分的输入是一个完整的句子,我在代码中将其拆分为单词,并在每一帧上更新以显示句子中的当前单词 300 毫秒。现在我是一个编码新手,我不知道如何在每个单词出现后添加一个 300 毫秒的空白屏幕。

句子:“约翰踢了水桶” 拆分成单词,表现为:John(300ms)blankscreen(300ms) kicked(300ms)blankscreen(300ms)等

我已经包含了我的相关代码,但不知何故无法弄清楚如何在更新单词之间获得空白屏幕。我尝试创建一个空白屏幕图像并将其插入到不同位置的循环中,但我无法弄清楚。非常感谢您的帮助!

    # get the sentence for this trial and split it into a list of words:
words = Sentence.split() 

# count them (the length of the list): 
numWords = len(words)

# how long the text component should display for: 
totalDuration = numWords * 0.3 # time in seconds 

fixationDuration = 1.5 # put in whatever your actual fixation duration is 
currentWordIndex = -1 # will be useful in "each frame" tab

# t is the time elapsed in the trial. 
# Calculate what word we should be up to by seeing how many 300 ms periods have elapsed so far (& force it to be an integer): 
checkIndex = int((t-fixationDuration)/0.3) 

# see if we need to switch to a new word (including the very first one): 
if checkIndex < numWords:
    if checkIndex != currentWordIndex: 
        currentWordIndex = checkIndex 
        text_1.setText(words[currentWordIndex]) # update to the current word

现在经过几次迭代,我有一个功能独立的脚本,它可以拆分一个句子,并且在每次试验中会呈现一个固定交叉 1.5 秒(90 帧),然后将拆分句子中的每个单词呈现 300 毫秒每个中间有 300 毫秒的空白。但是,我无法在需要 200 个句子作为输入的较大脚本中使用它。当我尝试将它合并到 Psychopy 的 Builder 部分时(我想让它与学生兼容),它只会一遍又一遍地呈现第一句话(固定交叉、单词、空白等到句末,然后固定又是同一句话)。每个试验应如下所示:

  • 固定交叉 1.5 秒/90 帧 (60Hz)
  • 单词/空白/单词/空白句子的呈现
  • 参与者必须回应的目标词

现在目标词在 Builder 中是一个单独的例程,但这似乎不是脚本不起作用的原因。它无法跟踪它应该呈现的句子,因为它现在还没有内置(显然我用我的 Sentence 变量替换了“John kicked the bucket”句子,它是所有句子的列表),并且只是呈现相同的一个,但是多次,因为它已经分裂了句子中的单词。这就是为什么我认为我需要 checkIndex 变量。我想我需要某种索引来检查每一帧已经呈现了多少帧,以便它知道是否将我的 text_1 stim 更新为下一个单词。

    from psychopy import visual
    from psychopy import core

    words = "He kicked the bucket".split() 
    win = visual.Window()
    text_1 = visual.TextStim(win)

    text_1.setText("+")
    for frameN in range (90):
       text_1.draw()
       win.flip()

    for word in words:

        text_1.setText(word)
        for frameN in range (18):
           text_1.draw()
           win.flip()

        text_1.setText(" ")
        for frameN in range(18):
           text_1.draw()
           win.flip()

【问题讨论】:

  • 哦,原来你使用的是Builder!您是否在“开始例程”选项卡中输入了代码?该行为听起来像是在“开始实验”选项卡中。
  • 我在“开始例程”中有变量定义,之前在“每一帧”中有“逐字逐句:”的代码,所以这可能是一个问题。但是,如果我将所有这些都移到“开始例程”中,它会因为 win = visual.Window() 而崩溃。毕竟可能是电脑问题?我会尝试在家里运行它,因为两次绘制 text_1 没有帮助。那么在实验室计算机上运行它会是一个问题。感谢您的耐心和帮助,“我不知道自己在做什么”因素对我来说相当高。
  • 有效!现在在另一次尝试中,我将上面的代码放入“开始例程”中,并且必须取出 visual.Window 代码部分并在我的 Builder 实验中创建一个实际的文本刺激占位符供它参考,然后它就可以工作了。感谢大家的帮助!

标签: python psychopy


【解决方案1】:

请参阅下面的解决方案。

这里要记住的重要一点是,您应该使用离散的监视器帧/更新而不是连续时间来计时视觉刺激。例如,使用core.wait(0.300) 通常会导致文本到达下一帧,导致某些试验的实际间隔为 316.7 毫秒,而另一些试验为 300 毫秒。 visual.Window.flip() 函数会暂停一切,直到监视器更新,因此循环 flip() 将使循环与监视器同步 - 有用!

from psychopy import visual
words = 'John kicked the bucket'.split()
win = visual.Window()
text_1 = visual.TextStim(win)

for word in words:
    # Set text for this trial
    text_1.text = word

    # Show text for 300 ms = 18 frames on 60Hz monitor
    for frame in range(18):
        text_1.draw()
        win.flip()

    # Blank screen for 300 ms = 18 frames on 60Hz monitor
    for frame in range(18):
        win.flip()  # OBS: no drawing in this loop. Just a blank screen.

它确实需要您的计算机实际与显示器同步。如果您运行的刷新率不同于 60 Hz,请更改帧数,以便获得所需的 300 毫秒。如果您使用psychopy,请运行Coder --> demos --> timing --> timesByFrames,您应该会在60Hz显示器上看到大约16.667 ms的窄分布。

【讨论】:

  • 感谢您的帮助。我已经为此工作了几个小时,但它不起作用。当我运行你的脚本时,它只显示“bucket”这个词。我已经尝试了脚本的多次迭代和组合,对我来说,我似乎确实需要某种 checkIndex 组件来跟踪脚本应该呈现的单词。它似乎没有那么简单。现在我有大约 17 次实验迭代,所有这些都做了一些不同但错误的事情(比如在试验 1 中没有单词,在试验 2 中出现 1 个单词,在试验 3 中出现 2 个单词等),我迷路了。跨度>
  • 补充:我确实有一个接近你的版本,可以正确显示单词和空格,但在固定交叉上搞砸了。我会尽量在星期五之前发布。
  • 如果这不起作用,则说明您的计算机出了问题。尝试在另一台计算机上运行脚本 - 最好使用专用显卡。我希望它在那里工作。但使其在您的计算机上运行的可能解决方案是:(1) 升级您的图形驱动程序,(2) 在当前行之前创建第二个 text_1.draw() 行(绘制两次)。
  • 这不是计算机问题,它似乎是一个问题,它在 Psychopy 中作为一个单独的编码器脚本与一个句子一起工作,但是当我尝试调整它并将其合并到我的更大的脚本,从输入文件中获取 200 个句子,将它们拆分并在不同的试验中显示每个句子的单词,然后在每个句子后面加上一个目标单词。我编辑了我的原始帖子以包含当前状态。再次感谢您的帮助,这是我的第一个脚本,所以我正在研究它。
【解决方案2】:
import time

words = sentence.split()

for word in words:
    #place something to undo changes in blank screen, you can use try except
    text_1.setText(word)
    time.sleep(.3)
    text_1.setText("") 
    #make changes during blank screen, put images or something
    time.sleep(.3)       

如果我正确理解了您的问题,我想这应该可以满足您的要求。代替text_1.setText(""),当你想显示空白屏幕时,放置你想做的任何事情。

【讨论】:

  • 您应该在每个 setText 之后有一个 text_1.draw()visual.Window.flip() 以实际显示它。请参阅我的答案以获得改进的计时解决方案。
【解决方案3】:

(代表 OP 发布).

问题已解决。此代码进入 Builder 的“开始例程”部分:

 # get the sentence for this trial and 
 # split it into a list of words: 
 words = Sentence.split() 

 text_2.setText("+") #draw a fixation cross at the beginning of each trial for 90 frames
for frameN in range (90):
    text_2.draw()
    win.flip()

for word in words:

    text_2.setText(word) #set current word in Builder placeholder text variable
    for frameN in range (18):
           text_2.draw() #present current word for 18 frames
           win.flip()

    for frameN in range(18): #present blank screen for 18 frames
           win.flip()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多