переменная сброса психопсии для каждого испытания

Я сделал собственную рейтинговую шкалу, представляющую собой временную шкалу от 0 до 28:18. Он перемещается в зависимости от того, как быстро люди нажимают клавиши «t» или «b» для каждого испытания. То, что появляется на экране, выглядит так:

эксперимент

Я хочу, чтобы время вверху сбрасывалось на 14:09 для каждого испытания. После каждого испытания следует 0,5-секундный интервал между испытаниями, в течение которого на экране отображается «+». У меня проблема в том, что если вы нажмете «t» или «b» во время ITI, следующее испытание не начнется в 14:09. Вместо этого он будет смещен в том направлении, в котором нажатие «t» или «b» сдвигает временную шкалу. Вот мой текущий код, где я пытался это исправить:

prevPos = 0
trialNum=0
b_list=[]
t_list=[]
key=[]

# loop through pictures
for eachPic in catPictures:
    b_list=[]
    t_list=[]
    timer = core.CountdownTimer(TrialDuration)
    while timer.getTime() > 0:
        for key in event.getKeys():
            if key in ['escape']:
                core.quit() # quit if they press escape
            if key in ['b']:
                # add keypress to list for each keypress. then move cursor proportionally to length of this list
                b_list.append(key)
                prevPos+=len(b_list)
            if key in ['t']:
                t_list.append(key)
                prevPos-=len(t_list)

    # set upper and lower limits to where cursor can go (which will later be halved to restrict range of cursor on the screen)
        if prevPos <= -849:
            prevPos = -849
        elif prevPos >=849:
            prevPos = 849
        # make absolute position so pos_absolute becomes a range from 0 to 300 (based on 28:18 min movie)
        pos_absolute = prevPos + 849
        # need to have range of 1698 (# of seconds in 28:18)
        # need to have range of 1698 (# of seconds in 28:18)
        # current range is 0 to 849 (which is 50% of 1698)
        seconds =  pos_absolute

        Image2 = visual.ImageStim(window)
        #curbImage2.setSize = ((0.5,0.5), units = 'norm')
        # make a little higher than the absolute middle
        Image2.setPos([0,100])
        # use each image (i in curbImages)
        Image2.setImage(catPictures[trialNum])

        # define cursor that moves along timeline
        cursorImage = visual.ImageStim(window)
        cursorImage.setImage(directoryStim+'cursor.png')
        # make cursor move by however big prevPos is
        cursorImage.setPos([int(prevPos)*.5,int(400)])
        # make the line
        timeline = visual.SimpleImageStim(win=window, image=directoryStim+'line.png', units='pix', pos=[0, 400])
    event.clearEvents() # get rid of other, unprocessed events

        # print min and max values next to timeline
        min = visual.TextStim(window, '0:00', color='Black', pos=[-500, 400])
        max = visual.TextStim(window, '28:18', color='Black', pos=[500, 400])
        # print constantly updating time value
        timeText = visual.TextStim(window,'%d:%02d' % (seconds/60, seconds % 60),color='Black',wrapWidth=1080,font='Verdana', pos=[0,465], height=50)

        ## now put everything on the screen
        Image2.draw(window)
        min.draw(window)
        max.draw(window)
        timeText.draw(window)
        timeline.draw(window)
        cursorImage.draw(window)
    ## flip so it actually appears
        window.flip()

    ITI = visual.TextStim(window, '+', pos=[0,0], height=50, color='Black')
    ITI.draw(window)
    window.flip()
    core.wait(.5,.5)
    trialNum+=1
    prevPos = 0
    b_list =[]
    t_list=[]
    key=[] 

Как сбросить временную шкалу на 14:09 (то есть prevPos = 0) в начале каждого испытания, даже если люди нажимают «t» или «b» в конце испытания или во время интервала между испытаниями?


person Maria    schedule 31.08.2015    source источник
comment
Не могли бы вы еще раз взглянуть на свой отступ?   -  person derricw    schedule 31.08.2015
comment
На протяжении всего цикла вы воссоздаете объекты на каждой итерации цикла. Это неэффективно по времени (для инициализации объекта требуется намного больше времени, чем для обновления его атрибутов). например timer = core.CountdownTimer(TrialDuration) должно находиться вверху кода, а в его текущем местоположении должна быть только строка timer.reset(). Точно так же сдвиньте создание каждого изображения, например. Image2 = visual.ImageStim(window), в начало кода и внутри цикла вам нужно только Image2.setImage(catPictures[trialNum]). Остальные изображения являются постоянными, поэтому их следует создавать только один раз.   -  person Michael MacAskill    schedule 31.08.2015
comment
Плюс один для котенка. Вы знаете, как привлечь внимание интернета.   -  person mmagnuski    schedule 31.08.2015


Ответы (2)


  1. Отступ под внутренним циклом for.
  2. Переместите event.clearEvents() прямо перед циклом while или после core.wait. Вот где вы начинаете прослушивать новые нажатия клавиш. Нажатия в течение периода ожидания будут возвращены при следующем вызове event.getKeys() в следующем цикле цикла while. Вот почему он сразу перемещает курсор. Нет никакой реальной причины иметь event.clearEvents() там, где он у вас есть, поскольку вы только прослушиваете события в цикле while. Вот почему я предлагаю вам переместить его, а не вставлять новый.
  3. Инициирование психопсийных стимулов требует значительных ресурсов и иногда может занять несколько сотен миллисекунд. Нет смысла создавать несколько новых ImageStims и TextStims в каждом испытании.
  4. pos_absolute и seconds избыточны. Вы могли бы сделать только с seconds.
  5. Стильная вещь: вместо stim.setPos(x) теперь можно делать stim.pos = x и так далее для всех остальных атрибутов. Теперь это предпочтительный способ установки атрибутов стимула (более чистый код и позволяет выполнять больше операций с атрибутами).

Вот очищенный код с указанными выше изменениями:

# Stimuli
Image2 = visual.ImageStim(window)
cursorImage = visual.ImageStim(window)
min = visual.TextStim(window, '0:00', color='Black', pos=[-500, 400])
max = visual.TextStim(window, '28:18', color='Black', pos=[500, 400])
timeText = visual.TextStim(window,color='Black',wrapWidth=1080,font='Verdana', pos=[0,465], height=50)
ITI = visual.TextStim(window, '+', pos=[0,0], height=50, color='Black')
timeline = visual.SimpleImageStim(win=window, image=directoryStim+'line.png', units='pix', pos=[0, 400])
timer = core.CountdownTimer(TrialDuration)

# loop through pictures
trialNum=0
for eachPic in catPictures:
    prevPos = 0
    key=[]
    b_list=[]
    t_list=[]
    timer.reset()
    event.clearEvents() # get rid of other, unprocessed events
    while timer.getTime() > 0:
        for key in event.getKeys():
            if key in ['escape']:
                core.quit() # quit if they press escape
            if key in ['b']:
                # add keypress to list for each keypress. then move cursor proportionally to length of this list
                b_list.append(key)
                prevPos+=len(b_list)
            if key in ['t']:
                t_list.append(key)
                prevPos-=len(t_list)

        # set upper and lower limits to where cursor can go (which will later be halved to restrict range of cursor on the screen)
        if prevPos <= -849:
            prevPos = -849
        elif prevPos >=849:
            prevPos = 849
        # make absolute position so pos_absolute becomes a range from 0 to 300 (based on 28:18 min movie)
        # need to have range of 1698 (# of seconds in 28:18)
        # need to have range of 1698 (# of seconds in 28:18)
        # current range is 0 to 849 (which is 50% of 1698)
        seconds =  prevPos + 849

        #curbImage2.size = ((0.5,0.5), units = 'norm')
        # make a little higher than the absolute middle
        Image2.pos = [0,100]
        # use each image (i in curbImages)
        Image2.image = catPictures[trialNum]

        # define cursor that moves along timeline
        cursorImage.image = directoryStim+'cursor.png'
        # make cursor move by however big prevPos is
        cursorImage.pos = [int(prevPos)*.5,int(400)]
        timeText.text = '%d:%02d' % (seconds/60, seconds % 60))

        ## now put everything on the screen
        Image2.draw(window)
        min.draw(window)
        max.draw(window)
        timeText.draw(window)
        timeline.draw(window)
        cursorImage.draw(window)
        ## flip so it actually appears
        window.flip()

    ITI.draw(window)
    window.flip()
    core.wait(.5,.5)
    trialNum+=1

Обратите внимание, что я также удалил несколько, казалось бы, ненужных сбросов b_list, key и т. д.

person Jonas Lindeløv    schedule 31.08.2015
comment
круто, спасибо!! К вашему сведению, единственное, что мне пришлось изменить, чтобы заставить его работать, - это сделать отступ цикла for после цикла while (до раздела ITI. Это было моим недостатком в исходном коде) и удалить круглые скобки там, где вы определяете timeText. Вы немного почистили его, спасибо! - person Maria; 01.09.2015
comment
Прохладно. Я забыл переместить timeline и timer. Я обновил код ответа этим. Также смещен внутренний цикл for. См. также новые пункты 4 и 5 с еще несколькими предложениями. - person Jonas Lindeløv; 01.09.2015

В последней строке кода попробуйте следующее:

event.clearEvents()

Клавиши, нажатые во время вашего ITI, попадают в буфер и поэтому будут собраны при следующем вызове event.getKeys(). Вызывая clearEvents(), вы очищаете этот буфер.

person Michael MacAskill    schedule 31.08.2015