Randomly select two pictures of the three group of pictures without replacing

OS: Win 11
PsychoPy version: v2024.1.5
**Standard Standalone? yes

In my experiment I want to show two images in each trial. These two pictures must be selected from three groups of pictures so that no two pictures are from the same group and the pictures are not duplicated.

My Excel file is called images and it has three conditions, group 1, group 2, and group 3.
In fact, in each trial, I want to randomly select two of the three groups to take a picture, and then take a picture from each one without placing them.

Whether the image is on the right or the left must be random!

How can I make this condition?

Begin Experiment:

image_list =

for thisRow in trials.trialList:
image_list.append(thisRow[‘image’])

Begin Routine:

import random

chosen_images = random.sample(image_list, 2)
left_image = chosen_images[0]
right_image = chosen_images[1]

How does your code select from two of the three groups?

Put import random (if you need it) in Begin Experiment, not Begin Routine.

What I often do is randomise the position of the two images rather than randomising which image each of them contains. What does the participant have to do in the experiment?

“How does your code select from two of the three groups?”
My code does not do this. Because I’m new to psychopy and have no idea how to do this.

The participant only has to see two images side by side on the screen and the eye tracker is also recorded. These images are selected from three different categories. And they must be placed together two by two. I want to see which image the person’s gaze goes to in each pair that appears.

What I have in mind is to put the images in three columns of excel. When the test enters the loop, first select two of these three columns and then select an image from each column without replacing. These two images are displayed side by side in a fixed place on the screen. This process continues until all the images are showed.

I think that the easiest option would be to preload your image filenames into three lists (e.g. listA, listB and listC) and in your speadsheet have columns called Left and Right with all six permutations of one list on one side and the other on the other (AB, AC, BC, BA, CA, CB).

Then in your code you can have something like:

if Left == 'listA':
     left_image = listA.pop()
elif Left == 'listB':
     left_image = listB.pop()
elif Left == 'listC':
     left_image = listC.pop()
if Right == 'listA':
     right_image = listA.pop()
elif Right == 'listB':
     right_image = listB.pop()
elif Right == 'listC':
     right_image = listC.pop()

You’ll need to put left_image = '' and right_image = '' in Begin Experiment (for it to work online).

To load the images in the first place you could use a loop or have a look and my TrialHandler code here: PsychoPy Code Component Snippets - Google Docs

1 Like

Thank you for your previous response; it was very helpful. However, I have encountered another issue now.

This script randomly selects pairs of images from three groups and displays them.

import random

# Initialize image lists
group1_images = []
group2_images = []
group3_images = []

if 'trials' in locals():
    # Load images from the Excel file into the lists
    for thisRow in trials.trialList:
        group1_images.append(thisRow['images1'])
        group2_images.append(thisRow['images2'])
        group3_images.append(thisRow['images3'])
else:
    print("trials is not defined. Make sure the loop is named correctly.")

# Initialize counter for the number of pairs displayed
num_pairs = 0

# Ensure that the lists have at least one image each
while len(group1_images) > 0 and len(group2_images) > 0 and len(group3_images) > 0:
   
    # Randomly pick two different groups
    groups = random.sample([1, 2, 3], 2)
   
    # Select a random image from each chosen group and remove it
    if groups[0] == 1:
        left_image = group1_images.pop(random.randrange(len(group1_images)))
    elif groups[0] == 2:
        left_image = group2_images.pop(random.randrange(len(group2_images)))
    elif groups[0] == 3:
        left_image = group3_images.pop(random.randrange(len(group3_images)))
   
    if groups[1] == 1:
        right_image = group1_images.pop(random.randrange(len(group1_images)))
    elif groups[1] == 2:
        right_image = group2_images.pop(random.randrange(len(group2_images)))
    elif groups[1] == 3:
        right_image = group3_images.pop(random.randrange(len(group3_images)))
   
    # Randomize the positions
    if random.choice([True, False]):
        left_image, right_image = right_image, left_image
   
    # Show the images (this part depends on your PsychoPy setup)
    # Example: win.flip()
   
    # Print the images for debugging
    print(f"Left image: {left_image}, Right image: {right_image}")
   
    # Increment the number of pairs
    num_pairs += 1

# Print the total number of pairs displayed
print(f"{num_pairs} pairs of images have been displayed.")

The images are selected such that:

Each pair contains one image from each of two different groups.
The positions of the images (left or right) are randomized.
The script counts and prints the number of pairs displayed at the end.

I placed this code in the begin routine section. What I want is for it to display 12 non-repetitive and non-same-group image pairs exactly once. However, the code is currently separating these pairs and displaying only one pair at a time. It performs this operation for as many times as the length of each group (which is 8), leading to the possibility of duplicate pairs in the output.

Could the issue be related to the placement of my code?