Python psychopy builder使用反馈和多个if循环进行实验

Python psychopy builder使用反馈和多个if循环进行实验,python,psychopy,experimental-design,Python,Psychopy,Experimental Design,我正试图使用Coder视图来做一个涉及反馈和多个条件语句的实验。你是怎么做到的?这项任务最终将涉及4道数学题,每道题最多允许参与者尝试3次。结构应该是这样的 循环1:处理4个问题 循环2:每个问题最多允许3次尝试 循环3:如果回答是正确的,那么说“正确”并进入下一个问题;否则,说“不正确”,并询问他们是否愿意再试一次或继续 这是我第一次使用Python,我无法解决代码中的问题。没有返回错误消息,但是代码没有注册响应,因此任务在提示屏幕上被冻结。代码如下。我没有包括库和其他设置 t=0 nProb

我正试图使用Coder视图来做一个涉及反馈和多个条件语句的实验。你是怎么做到的?这项任务最终将涉及4道数学题,每道题最多允许参与者尝试3次。结构应该是这样的

循环1:处理4个问题

循环2:每个问题最多允许3次尝试

循环3:如果回答是正确的,那么说“正确”并进入下一个问题;否则,说“不正确”,并询问他们是否愿意再试一次或继续

这是我第一次使用Python,我无法解决代码中的问题。没有返回错误消息,但是代码没有注册响应,因此任务在提示屏幕上被冻结。代码如下。我没有包括库和其他设置

t=0
nProblem=4
nAttempt=3

while currentProb <= nProblem:
    problemTimer.reset()
    attempt = 1

    # *prompt* updates
    prompt.setAutoDraw(True)
    prompt.setText(u'Problem prompt will go here.\n\nType in your answer and press enter to submit.', log=False)

    while attempt <= nAttempt:

        response = []
        # *response* updates
        core.wait(1) #LB - using this in place of that enormous if-statement

        event.clearEvents(eventType='keyboard')
        theseKeys = event.getKeys(keyList=['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'])
        # check for quit:
        if "escape" in theseKeys:
            endExpNow = True
        if ('1', '2', '3', '4', '5', '6', '7', '8', '9', '0') in theseKeys: # subject responds with number value
            response.append(theseKeys) # will tack on responses to previous responses

        while event.getKeys(keyList=['return'])==[]:

            # *timer* updates
            if t <= 0.0:
                # keep track of start time/frame for later
                timer.setAutoDraw(True)
            #elif timer.status == STARTED and t >= (0.0 + (600-win.monitorFramePeriod*0.75)): #most of one frame period left
                #timer.setAutoDraw(False)
            #if timer.status == STARTED:  # only update if being drawn
                timer.setText(str(round((600+routineTimer.getTime())/60,1)) , log=False)

            # *minutesleft* updates
            if t >= 0.0:
                # keep track of start time/frame for later
                minutesleft.setAutoDraw(True)
            #elif minutesleft.status == STARTED and t >= (0.0 + (600-win.monitorFramePeriod*0.75)): #most of one frame period left
            #minutesleft.setAutoDraw(False)

            numberlist=event.getKeys(keyList=['1','2','3','4','5','6','7','8','9','0','backspace','return'])
            for number in numberlist:
                #if key isn't backspace, add key pressed to the string
                if number !='backspace':
                    response.append(number)
                #otherwise, take the last letter off the string
                elif len(text)>=0:
                    response.remove(numberlist[number-1])
            #continually redraw text onscreen until return pressed
            answer = visual.TextStim(win, text=response,color="black",pos=(0,-100))
            answer.draw()
            win.flip()
            event.clearEvents()

        if len(theseKeys) > 0:  # at least one key was pressed
            response.keys.extend(theseKeys)  # storing all keys
            response.rt.append(response.clock.getTime())

        #check for quit
        if "escape" in theseKeys:
            endExpNow = True

        if response == '9999': # was this correct?
            correctAns = 1
        else: 
            correctAns = 0
        if theseKeys == 'enter':
            response.keys.extend(theseKeys) # storing all keys
            response.rt.append(attemptresponse.clock.getTime())
            if correctAns == 1:
                attempt += 888 #ends and goes to next problem
                currentProb += 1
                dataFile.write(attempt,attemptresponse,theseKeys,response,correctAns) #output separated by commas
                #dataFile.write('PID    COND    PROB    ATT TIME    RESP\n')
                response_correct.draw()
                win.flip()
                event.waitKeys()
            if correctAns == 0:
                attempt += 1 #LB = was previously setting to 1 forever
                dataFile.write(attempt-1,attemptresponse,theseKeys,response,correctAns) #output separated by commas
                response_incorrect.draw()
                win.flip()
                theseKeys = event.getKeys(keyList=['q','space'])
                if theseKeys == 'q':
                    continueRoutine = False
                if theseKeys == 'space':
                    prompt.draw()
                    win.flip()
                    event.waitKeys()
t=0
n问题=4
Nattent=3
而currentProb=(0.0+(600 win.monitorFramePeriod*0.75)):#一个帧周期的大部分剩余
#左分钟。设置自动绘制(假)
numberlist=event.getKeys(keyList=['1'、'2'、'3'、'4'、'5'、'6'、'7'、'8'、'9'、'0'、'backspace'、'return'])
对于数字列表中的数字:
#如果键不是backspace,则将按下的键添加到字符串中
如果数字!='退格':
响应。追加(编号)
#否则,从字符串中去掉最后一个字母
elif len(文本)>=0:
响应。删除(numberlist[number-1])
#不断在屏幕上重画文本,直到按return键
答案=视觉。文本刺激(赢,文本=响应,颜色=“黑色”,位置=(0,-100))
答案:draw()
win.flip()
event.clearEvents()
如果len(这些键)>0:#至少按下了一个键
响应.键.扩展(这些键)#存储所有键
response.rt.append(response.clock.getTime())
#检查是否退出
如果这些键中有“escape”(退出):
endExpNow=True
如果响应='9999':#这是否正确?
correctAns=1
其他:
correctAns=0
如果这些键=='输入':
响应.键.扩展(这些键)#存储所有键
response.rt.append(attemptresponse.clock.getTime())
如果correctAns==1:
尝试+=888#结束并转到下一个问题
currentProb+=1
dataFile.write(尝试、尝试响应、这些键、响应、更正)#以逗号分隔的输出
#dataFile.write('PID COND PROB ATT TIME RESP\n')
回答_正确。绘制()
win.flip()
event.waitKeys()
如果correctAns==0:
尝试+=1#LB=以前设置为1 forever
dataFile.write(尝试-1,尝试响应,这些键,响应,更正)#输出用逗号分隔
响应_不正确。绘制()
win.flip()
theseKeys=event.getKeys(keyList=['q','space'])
如果这些键=='q':
continueRoutine=False
如果这些键==“空格”:
prompt.draw()
win.flip()
event.waitKeys()

我无法写出您的完整代码,但希望能指出一些事情,帮助您完成大部分工作

得到回应 这里的
keys
只能包含
keyList
中的内容,因此“escape”永远不会出现。使用“escape”(转义)扩展键列表,并可能使用“enter”(稍后使用)

if ('1', '2', '3', '4', '5', '6', '7', '8', '9', '0') in theseKeys:
theseKeys
是一个列表,当您在列表中执行“(x,y,z)时,它将查找元素(x,y,z),而不是任何x,y和z的出现。如果您有如上所述的密钥列表,那么您知道任何非转义响应都是其中之一,因此它是不必要的。我也是

theseKeys = event.getKeys(keyList=['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'escape'])
if "escape" in theseKeys:
    core.quit()  # assuming that psychopy.core is imported
elif "enter" in theseKeys:
    # Something something
else:
   response.append(theseKeys[0])  # OBS: pick the first response
循环 看起来您真的希望使用
for
循环,而不是
while
循环。使用for循环,您不必跟踪当前循环编号。所以而不是

while currentProb <= nProblem:
然后,
currentProb
的增量自动发生,循环在应该的时候终止。如果可能的话,这会更加优雅

等待回应 我有点怀疑是否要在while循环中使用
event.waitKeys()
而不是
event.getKeys()
,如果要控制等待时间,请使用
maxWait
参数,如果要跟踪计时,请使用
core.Clock()。如果您想设置动画,while循环是可以的,但如果不可以,则
event.waitKeys()
将更加简单和安全


最后,在您尝试执行此操作时,请使用大量的
print
语句来检查
这些键的实际内容以及其他变量。这是调试和捕获gotchas的最佳方法。

嗨,Jennifer,这是一个很好的问题,Jonas提出了一些非常有用的建议(如果解决了您的问题,请记住将他的答案标记为正确)。但在未来,对于此类“编程逻辑”问题,最好让代码示例更加简洁:去掉所有与实际问题无关的行,重新保存数据、计时和刺激。你会发现,如果能更容易地看到代码的结构,更多的人会愿意阅读代码,这正是你的问题所涉及的。
while currentProb <= nProblem:
for currentProb in range(nProblem):