Issue with generation of random text stimuli

Hi all.

I’m very new to PsychoPy and and Python in general, I’m pretty much learning as I go along.

I’m using PsychoPy Coder to design a simple task.

The task involves the participant playing a game with two other players, controlled by the computer. The participant selects which computer player they wish to ‘pass’ an imaginary ball to, by pressing A or B respectively. The computer player they pass to then randomly either passes to the other computer player, or back to the participant. These ‘ball passes’ are just displayed as text stimuli, informing where the ball has been passed.

I’ve written the following code to do this (again, apologies if it is messy or there is some obvious mistake, I’m very inexperienced):

#participant makes their decision to pass to either computer player A or player B (text stimuli are defined earlier in code not shown)


text_dplayer.draw()
mywin.flip()
allKeys=event.waitKeys(keyList=['a','b'])


#recognising participant choice, then setting a variable 'decision' to 'a' or 'b' to remember participant choice


for thisKey in allKeys:
    if thisKey=='a':
        text_7.draw()
        mywin.flip()
        core.wait(5)
        text_2.draw()
        mywin.flip()
        decision = 'a'
        core.wait(5)
    elif thisKey=='b':
        text_8.draw()
        mywin.flip()
        core.wait(5)
        text_2.draw()
        mywin.flip()
        decision = 'b'
        core.wait(5)


#list of possible options for computer player A (text stimuli describes either passing to player B or passing back to the participant)


pickB = text_9.draw()


pickPa = text_10.draw()


actionsA = [
    pickB,
    pickPa,
]


#list of possible options for computer player B (text stimuli describes either passing to player A or passing back to the participant)


pickA = text_11.draw()


pickPb = text_12.draw()


actionsB = [
    pickA,
    pickPb,
]


#list is referenced and random choice is made by computer


if decision=='a':
    random.choice(actionsA)
    mywin.flip()
    core.wait(5)
elif decision=='b':
    random.choice(actionsB)
    mywin.flip()
    core.wait(5)

The issue is, instead of randomly displaying a single possible text stimuli from the list actionsA or actionsB (depending on whether the participant passes to A or B), all text stimuli from both lists are all displayed together in the PsychoPy window (e.g., instead of just showing “Player A passed the ball back to you!”, it shows all four possible text stimuli overlaid).

I have re-created this code just using basic Python code, no PsychoPy stuff (i.e. printing text instead of creating text stimuli) and it works as I want it to. But I can’t figure out why it doesn’t work this way in PsychoPy.

Thank you very much in advance for any help you can offer.

William Smith
University of Nottingham

This is a pretty unusual construction in Python:

pickB = text_11.draw()

as text_11.draw() is supposed to take an action (draw that stimulus to the screen, ready to be displayed at the next win.flip()) rather than be a function that returns a value (like, say, position = text_11.pos()

So I think you want to select a stimulus to draw, rather than package it like the line above, which may make them all draw anyway.

e.g. something like:

stimulus = random.choice(text11, text12)
stimulus.draw()

i.e. select a stimulus and only call the draw function of that particular stimulus.

PS once you sort this, come back to us about a better way to do your drawing. You get a lot more flexibility by avoiding core.wait() to do your stimulus timing. If instead you actively draw to the screen in a loop, on every screen refresh, you get a lot more flexibility (e.g. still being able to respond to the keyboard, rather than accepting that the computer will be unresponsive until the .wait() period is complete).

Hi Michael,

Thanks a lot for your help, that makes a lot of sense and explains where I was going wrong. It all now works as I wanted.

random.choice() only allows two arguments apparently, so I had to stick with using a list and ended up with this:

actionsA = [
    text_9,
    text_10,
]

actionsB = [
    text_11,
    text_12,
]

if decision=='a':
        stimulus = random.choice(actionsA)
        if stimulus==text_9:
            decision = 'b'
        elif stimulus==text_10:
            decision = 'p'
        stimulus.draw()
        mywin.flip()
        core.wait(5)

etc etc

That’s interesting re: the alternative to using core.wait(). In my case, making the computer unresponsive during this period has been desirable so far, as it stops the participant from pressing both A and B when waiting for a key press… but I expect there’s a better way of doing that too and so that probably isn’t a good excuse!