Hello,
I create a task where I have 10 stimuli per category, and I have 8 categories. In my first block, I want the participant to see 5 of the 10 words in each category (Ok I managed to do it, with 8 csv list file). But I don’t want him to see the same stimulus again in the second block ("CategoryValenceNeg).
How do I do this? I tried adding a global loop that refers to the same list but it doesn’t work…
Any ideas? I’m a beginner, I succeeded with several tutorials and questions/answers to create the code for the randomization but I have no base in python… well now a little bit.
Hi @Cju, you could do this by using the “selected rows” field for the loops. Put a code component in front of the first loop and define two variables which contain two random non-overlapping subsets of the row indices of the conditions file. Then use those two to select the rows to be used for the first and second loop respectively.
Hi ! It partially work…
But with this code, we can see only 5 words instead of 40 like before…
Here, I have 8 categories, separated in 8 csv files.
Here is the code :
import csv
newConditions = # define an initially empty list
for fileName in [‘FrenchPosCong.csv’, ‘EnglishPosCong.csv’,‘FrenchNegCong.csv’, ‘EnglishNegCong.csv’,‘FrenchPosIncong.csv’, ‘EnglishPosIncong.csv’,‘FrenchNegIncong.csv’, ‘EnglishNegIncong.csv’]:
conditions = data.importConditions(fileName) # create a list of dictionaries
shuffle(conditions) # randomise their order
conditions = conditions[0:5] # select just ten of them
newConditions.extend(conditions)
# will end up as 20 randomly selected but balanced-for-consistency trials
header = newConditions[0].keys() # get the header labels as a list
with open(‘newConditionList1.csv’,‘w’) as file: # create a new CSV file
output = csv.DictWriter(file, fieldnames=header) # arrange to write our dictionaries to it
output.writeheader()
output.writerows(newConditions)`
I tried to change L "range(80), 40) and range(80)
but it gives me this error message :
File “/Users/Catherine/Desktop/SC-AAT_build/test_lastrun.py”, line 380, in
trialList=data.importConditions(‘newConditionList1.csv’, selection=RowsLoop1),
File “/Applications/PsychoPy 2.app/Contents/Resources/lib/python3.8/psychopy/data/utils.py”, line 463, in importConditions
trialList.append(allConds[int(ii)])
IndexError: list index out of range
################ Experiment ended with exit code 1 [pid:35667] #################
Ah sorry, I thought the categories would be presented one after the other because you were talking about 8 different csv files and you have one outer loop.
So, do I understand you correctly that participants only go through the first and the second loop once with both having 40 trials? So you basically want to take your 8 csv files, sample 5 rows out of each one for the first loop, and then sample the 5 others for the second loop?
Please try this. Not sure if it works, since I don’t have the files to test it.
import csv
import random
CSVfiles = ['FrenchPosCong.csv', 'EnglishPosCong.csv','FrenchNegCong.csv', 'EnglishNegCong.csv','FrenchPosIncong.csv', 'EnglishPosIncong.csv','FrenchNegIncong.csv', 'EnglishNegIncong.csv']
randomIndices = []
# generate indices for all csv files
for i in range(len(CSVfiles)):
RowsLoop1 = random.sample(range(10), 5)
RowsLoop2 = list(set(range(10)) - set(RowsLoop1))
randomIndices.append([RowsLoop1, RowsLoop2])
# generate two files with non-overlapping subsets, 40 trials each
for j in [1, 2]:
newConditions = [] # define an initially empty list
for i in range(len(CSVfiles)):
fileName = CSVfiles[i]
conditions = data.importConditions(fileName) # create a list of dictionaries
shuffle(conditions) # randomise their order
conditions = conditions[randomIndices[i][j - 1]] # select just 5 of them
newConditions.extend(conditions)
header = newConditions[0].keys() # get the header labels as a list
with open('newConditionList' + j + '.csv',‘w’) as file: # create a new CSV file
output = csv.DictWriter(file, fieldnames=header) # arrange to write our dictionaries to it
output.writeheader()
output.writerows(newConditions)
This (hopefully) generates two new csv files (newConditionsList1.csv and newConditionsList2.csv), which you can then use for your two loops.
Thanks, Yes ! They only see two loops, each with 5items x 8 categories (40) from a total of 80 words.
I try to debug it…
This is the error message :
File “/Users/Catherine/Desktop/SC-AAT_build/test_lastrun.py”, line 122, in
conditions = conditions[randomIndices[i][j - 1]] # select just 5 of them
TypeError: list indices must be integers or slices, not list
Now I have that… I try to resolve b myself with tuto but it getting worse lol! I need a real Python training…
File “/Users/Catherine/Desktop/SC-AAT_build/test_lastrun.py”, line 126, in
with open(‘newConditionList’ + j + ‘.csv’,‘w’) as file: # create a new CSV file
TypeError: can only concatenate str (not “int”) to str
I’ve try this : with open(‘newConditionList’ + str(j) + ‘.csv’,‘w’) as file: but not working.
Thanks for your help
The newConditionsList1 isn’t created ! I don’t know why. But the newConditionsList2 yes.
In the code I correct the missing “s” and change de ‘w’ for ‘w’.
This is my code now
import csv
import random
CSVfiles = ['FrenchPosCong.csv', 'EnglishPosCong.csv','FrenchNegCong.csv', 'EnglishNegCong.csv','FrenchPosIncong.csv', 'EnglishPosIncong.csv','FrenchNegIncong.csv', 'EnglishNegIncong.csv']
randomIndices = []
# generate indices for all csv files
for i in range(len(CSVfiles)):
RowsLoop1 = random.sample(range(10), 5)
RowsLoop2 = list(set(range(10)) - set(RowsLoop1))
randomIndices.append([RowsLoop1, RowsLoop2])
# generate two files with non-overlapping subsets, 40 trials each
for j in [1,2]:
newConditions = [] # define an initially empty list
for i in range(len(CSVfiles)):
fileName = CSVfiles[i]
conditions = data.importConditions(fileName) # create a list of dictionaries
shuffle(conditions) # randomise their order
conditions = [conditions[k] for k in randomIndices[i][j-1]] # select just 5 of them
newConditions.extend(conditions)
header = newConditions[0].keys() # get the header labels as a list
with open('newConditionsList' + str(j) + '.csv','w') as file: # create a new CSV file
output = csv.DictWriter(file, fieldnames=header) # arrange to write our dictionaries to it
output.writeheader()
output.writerows(newConditions)
I think you reformatted the code slightly which causes the error: All lines starting at the second for-loop need to be indented so they are part of the first for-loop. See my original code.
Ok but this is the message error I have when I do the same code as yours, that was I try to change it but indeed maybe my solution wasn’t good either
:
File “/Users/Catherine/Desktop/SC-AAT_build/test_lastrun.py”, line 128
output = csv.DictWriter(file, fieldnames=header) # arrange to write our dictionaries to it
^
IndentationError: expected an indented block
import csv
import random
CSVfiles = ['FrenchPosCong.csv', 'EnglishPosCong.csv','FrenchNegCong.csv', 'EnglishNegCong.csv','FrenchPosIncong.csv', 'EnglishPosIncong.csv','FrenchNegIncong.csv', 'EnglishNegIncong.csv']
randomIndices = []
# generate indices for all csv files
for i in range(len(CSVfiles)):
RowsLoop1 = random.sample(range(10), 5)
RowsLoop2 = list(set(range(10)) - set(RowsLoop1))
randomIndices.append([RowsLoop1, RowsLoop2])
# generate two files with non-overlapping subsets, 40 trials each
for j in [1,2]:
newConditions = [] # define an initially empty list
for i in range(len(CSVfiles)):
fileName = CSVfiles[i]
conditions = data.importConditions(fileName) # create a list of dictionaries
shuffle(conditions) # randomise their order
conditions = [conditions[k] for k in randomIndices[i][j-1]] # select just 5 of them
newConditions.extend(conditions)
header = newConditions[0].keys() # get the header labels as a list
with open('newConditionsList' + str(j) + '.csv','w') as file: # create a new CSV file
output = csv.DictWriter(file, fieldnames=header) # arrange to write our dictionaries to it
output.writeheader()
output.writerows(newConditions)