Randomisation between and within loops without repetition

Hi all,

I am using PsychoPy v2022.2.4 on macOS Ventura Version 13.1 (22C65).

I have issues on how to randomise within and between loops without repetition. My experiment consists of 9 trials (indicated by the loop “songs” , please see picture at the bottom). In one of the sections (Encoding_StoringStage) I am presenting 12 words each trial. I have 108 different words and I would want each word to only be shown once.

As seen in the picture attached, in the loop I have my nReps at 1 and my selected rows with this as: $random(12)*108 ; with this, 12 words are presented but they are repeated both in the same trial (loop) and in the next following trials- so each word is randomly shown more than once. Then I added a code in End Routine: if WordsPresented.thisN == 11:
WordsPresented.finished = True
(please see picture) that was suggested in this previous forum post:

And the words were still being repeated between trials.I also tried adding the code in Begin Routine instead but they were still being repeated. I tried the code leaving “selected rows” and “nReps”, and just “nReps” empty but I get this error for both:
108
10.1220 WARNING t of last frame was 10.92ms (=1/91)
File “/Users/marian/Library/CloudStorage/OneDrive-UniversityofWestLondon/third year/Diss/0EXPERIMENTS/RECALL_with_Music_Marian_DissertationPsychoPy_lastrun.py”, line 1147, in
WordsPresented = data.TrialHandler(nReps=None, method=‘random’,
File “/Applications/PsychoPy.app/Contents/Resources/lib/python3.8/psychopy/data/trial.py”, line 147, in init
self.nReps = int(nReps)
TypeError: int() argument must be a string, a bytes-like object or a number, not ‘NoneType’
################# Experiment ended with exit code 1 [pid:4415] #################

When the custom code is added the words don’t repeat in the same trial, but they are shown again in other trials. When it is only $random(12)*108 is on selected rows, and no custom code is added to the routine, the words repeat within trials. I don’t want any words to be repeated at all throughout the whole experiment, I only want each of the 108 words to be shown just once.

Please let me know if I have not been clear enough. Would very much appreciate any help. Please find below some screenshots and my experiment attached to help make it more clear.

Thank you in advance.


RECALL_with_Music_Marian_DissertationPsychoPy.psyexp (90.0 KB)

I think I see the basic issue. Because selected rows is picking 12 random rows independently every time, it’s not excluding the rows it picked previously. I think the best option here is to create 9 unique and randomly selected sets of 12 words at the start of the experiment using a code element, and then use a different set of 12 on every loop of ‘songs’

So in your code element, in the ‘Before experiment’ tab, put this:

songsWordLists = []
allWords = list(range(0, 108))
for i in range(0, 9):
    # Create a list of 12 randomly selected values
    newList = list(choice(allWords, size=12, replace=False))
    songsWordLists.append(newList)
    # Remove those 12 values from the list of remaining values
    for j in range(0, len(newList)):
        allWords.pop(allWords.index(newList[j])) 

Then in your WordsPresented loop, for “selected rows”, put this:

$songsWordLists[songs.thisRepN-1]

This should make it so that on every repetition of the “songs” loop it picks a different list of 12 randomly selected items.

Thank you for your reply!

I have followed your instructions and I am getting this error:

10.4928 WARNING Couldn’t measure a consistent frame rate!
File “/Users/marian/Library/CloudStorage/OneDrive-UniversityofWestLondon/third year/Diss/0EXPERIMENTS/RECALL_with_Music_Marian_DissertationPsychoPy_lastrun.py”, line 201, in
newList = list(choice(allWords, size=12, replace=False))
NameError: name ‘choice’ is not defined
################ Experiment ended with exit code 1 [pid:11298] #################

I then tried to change “allWords” for “WordItem” (as that is how the spreadsheet with my list of words is named) and it did not work either. I am attaching screenshots to make it clearer.

Thank you!

Ah, my bad, it’s randchoice instead of choice. Try this code:

songsWordLists = []
allWords = list(range(0, 108))
for i in range(0, 9):
    # Create a list of 12 randomly selected values
    newList = list(randchoice(allWords, size=12, replace=False))
    songsWordLists.append(newList)
    # Remove those 12 values from the list of remaining values
    for j in range(0, len(newList)):
        allWords.pop(allWords.index(newList[j])) 

It did not give me an error now but it presented the same 12 words in every trial, randomising the order of the words.

I guess songs.thisRepN isn’t working the way I expected it to for some reason. OK, I think it should work if you change your “selected rows” field to this:
$songsWordLists.pop(0)

This seems to be working thank you so much!! :slight_smile: