Search code examples
pythonpsychopy

random choice: how can I get a weighted presentation for x trials?


I need a randomized selection of two values (300,-300) over x trials, I need both values to get selected at 50% of the time.

As an alternative I tried to create a list with both values presented there multiple times (5 x "300", 5 x "-300") and then shuffle the list each time and loop over it. I can not do that because of the current structure of the code and other resulting problems. I am new to python, too.

def one_stim_testing():
    facestims = choice(["-300", "300"])
    punktestims = choice(["-300", "300"])
    visual.ImageStim(win, "emo" + str(choice(range(23))) + ".jpg",
                     size=(300, 300), pos=(facestims,0)).draw()
    if facestims is "300": 
        visual.ImageStim(win, "neutral" + str(choice(range(23))) + ".jpg",size=(300, 300), pos=(-300,0)).draw()
    else:
        visual.ImageStim(win, "neutral" + str(choice(range(23))) + ".jpg", size=(300, 300), pos=(300,0)).draw()
    win.flip()
    core.wait(.5)
    win.flip()
    visual.ImageStim(win, "vertical.jpg",
                     size=(300,300), pos=(punktestims,0)).draw()
    if punktestims is "300":
        visual.ImageStim(win, "horizontal.jpg",
                         size=(300, 300), pos=(-300,0)).draw()
    else:
        visual.ImageStim(win, "horizontal.jpg",
                         size=(300, 300), pos=(300,0)).draw()

Solution

  • Do something like this:

        # Set up stimulus container once. Saves memory and ressources.
        # Do not generate new during runtime.
        image1 = visual.ImageStim(win, size=(300, 300))
        image2 = visual.ImageStim(win, size=(300, 300))
    
        image_horizontal = visual.ImageStim(win, image='horizontal.jpg', size=(300, 300))
        image_vertical = visual.ImageStim(win, image='vertical.jpg', size=(300, 300))
    
        # Generate factorial sequences
        # This is a list of dictionaries
        # There are better ways to do it in this particular example, 
        # but this approach scales well to all sorts of trial structures.
        REPETITIONS = 5
        trials = []
        for facestim in [-300, 300]:  # For each of these coordinates
            for punktestim in [-300, 300]:  # ... and for each of these coordinates
                for _ in range(REPETITIONS):  # ... and for each repetition:
                    trials.append({'facestim': facestim,
                                   'punktestim': punktestim})  #... add this combination
    
        # Randomize order
        random.shuffle(trials)
        #print(trials)  # If you want to inspect what happened
    
        # Showtime! Now loop through the factorial trials:
        for trial in trials:
            # Set image 1
            image1.image = 'emo%i.jpg' %choice(range(23))
            image1.pos = (trial['facestim'], 0)
            image1.draw()
    
            # Draw image 2 (the opposite side)
            image2.image = 'neutral%i.jpg' %choice(range(23))
            image2.pos = (-trial['facestim'], 0)  # The other coordinate
            image2.draw()
    
            # Show it
            win.flip()
            core.wait(0.5)
            win.flip()
    
            # Show horizontal and vertical in the correct positions
            image_vertical.pos = (trial['punktestim'], 0)
            image_vertical.draw()
            image_horizontal.pos = (-trial['punktestim'], 0)  # The other side
            image_horizontal.draw()
    
            # Perhaps a win.flip() here?
    

    (code not tested because I don't have the stimuli)