psychopy.org | Reference | Downloads | Github

.pop() function - Can you repopulate?

PsychoPy version (e.g. 1.84.2):

Trying to make an IAT with 7 blocks.
Defining all stimuli at the beginning of experiment in code (e.g. intWords = [‘clever’,‘bright’,‘smart’,‘quick’]

In Block 1 I am using word stimuli, retrieving from the list using this code:

if condition == ‘intL’:
wordcond = intWords.pop()
else:
wordcond = unintWords.pop()
(This is then looped via simple excel sheet, e.g. intL refers to correct answer ‘a’)

I do a similar thing in Block 2 except using Audio stim.

All this is working fine, but then I get to Block 3 which uses all of the stimuli previously used. Both words and audio.
Because I have used the .pop() function to ensure that stimuli aren’t used more than once in blocks 1 and 2, in block 3 I get the error message:

wordcond = unintWords.pop()
IndexError: pop from empty list

So in using .pop() I have depopulated these condition lists.

Is there a way to repopulate the same lists?
(Or alternatively present all stimuli randomly with code, but without the .pop() function?)

I tried draw.intWords() in Block3 at Begin Experiment, but it didn’t recognise this.

Many thanks in advance!

HI @newUser, you could instead index your lists, rather than depopulate them. At the beginning of each block create a counter, and increment that counter every time your condition is satisfied. E.g.,

# Before block begins
intCount = 0
unintCount = 0
# on condition
if condition == ‘intL’:
    wordcond = intWords[intCount]
    intCount += 1
else:
    wordcond = unintWords[unintCount]
    unintCount += 1

Thanks a lot, that’s really cool.

So I’ve implemented it, and Blocks 1 and 2 are working fine.

I’m then trying to use the same method for block 3 (Where all stimuli from first 2 blocks are used together) using this code at Begin Routine*

if condition == 'intL':
  wordcond = intWords[intCount]
  intCount += 1
elif condition == 'femalesound':
  soundfile = Fsounds[femaleCount]
  femaleCount += 1
elif condition == 'malesound':
  soundfile = Msounds[maleCount]
  maleCount += 1
else:
  wordcond = unintWords[unintCount]
  unintCount += 1

So I’ve essentially just amalgamated what happened in blocks 1 and 2.
But I’m getting this error message

IndexError: list index out of range
Exception TypeError: “‘NoneType’ object is not callable” in <bound method Server.del of <pyolib.server.Server object at 0x1DDFAED0>> ignored

Is it possible to do this without creating new indexes in block 3?
E.g. I could make new definitions such as:
intCount2 = 0, unintCount2 = 0 etc…
But there ought to be a more elegant solution I think?

Resetting the indices to zero is the elegant solution here. The lists still exist, you just start accessing them again from the beginning.

Beware that this will give you the same order of stimuli as was presented earlier. If that isn’t what you intend, as well as resetting the indices, your should should shuffle the lists of stimuli (if they don’t contain linked entries).

Right ok, thanks :slight_smile: So when you say resetting, you mean this:

Block 3, Begin routine*

intCount = 0
unintCount = 0
femaleCount = 0
maleCount = 0

shuffle(intWords)
shuffle(unintWords)
shuffle(Fsounds)
shuffle(Msounds)

?

Because this is giving me the error message: IndexError, index list out of range.

Are you saying that I have to make new indexes?

The error is telling you that the index is out of range. If there is no entry 0 in your list, then the list must be empty. I’m guessing that you are still popping entries from the list somewhere.

Insert some temporary debugging code so you can see where/when this is happening:

print(len(intWords)) # etc

The length of your lists should stay constant if you are no longer popping entries off them.