psychopy.org | Reference | Downloads | Github

TypeError..how to create list of filenames?

Hi there,

My question is probably due to being a little naive about python in general.

I’m trying to create a list of movie filenames to use as movie stimuli. In a code component, under “Begin Experiment”, I’ve tried to create a list like so.

Which I then use in a Movie Component:

Previously, I was just using one filename [e.g. attGetters = (‘Medal_grey.mov’)] which worked fine and displayed the movie as I wanted.

But now, I get a TypeError (see below) because I’m trying to create a of filenames for the Movie Component to draw from. I know that I’m probably making a basic mistake but not certain how I can go about creating a list of filenames like this.

Any advice appreciated!

You are currently creating a tuple of two movie names, but the movie stimulus is expecting just one name. So you have to specify an individual entry, like $attGetters[0] to get the first one.

Couple of points:

  • tuples (a sequence of things in round brackets: ('a', 'b')) are a bit of a pain. In general, use a list instead (things surrounded by square brackets: ['a', 'b']), they can be a bit friendlier.
  • you probably don’t want a fixed index like $attGetters[0], because then there is no point in having a list, because you’ll always extract the same value. How and when should the filenames within the list be selected? When we know that, we can suggest a way of indexing the list to get the filename you need on a given trial.

Ah that makes a lot of sense! Thanks for that overview, Michael! :slight_smile:

Ideally, I’d like to extract the filenames at random (I’m hoping to add more files to this list if possible) but a pre-set pseudorandomised order could also work.

You don’t specify what sort of randomisation you want, but I’ll just assume that you want a different entry for each trial and that they will be sampled completely and without replacement. So in your code component:

Begin experiment:

attGetters = ['grey.mov', 'purple.mov', 'green.mov'] # etc
shuffle(attGetters) # randomise the order 

Begin routine:

current_movie = attGetters.pop() # get the next one, from the randomly ordered list
thisExp.addData('current_movie', current_movie) # record the choice in the data file

Then just put $current_movie in the “Movie file” field.

Thanks again for your time. Much appreciated. Apologies I should have been more specific!

I want a different entry for each trial but sampled with replacement. I basically want to be able to randomly call one of these files an unlimited number of times. I’d also like a different list for each participant.

Your suggestions helped me get much closer! Thank you!

I’ve now tried using numpy.random.choice() instead of shuffle() in order to randomize with replacement. However, I still run into problems because the replacement doesn’t seem to work. If I try play another movie after each movie file in the list has been played, I get the below error. I was hoping that using random.choice with replace set to True would solve this issue. Do you have any suggestions for a way around this?

Error

    currentAttGetter = attGetters.pop()
IndexError: pop from empty list

That is indeed the right approach to get random sampling with replacement. But it actually replaces both the shuffle() and .pop() steps:

Begin experiment:

attGetters = ['grey.mov', 'purple.mov', 'green.mov'] # etc

Begin routine:

current_movie = np.random.choice(attGetters)
thisExp.addData('current_movie', current_movie)

.pop() actually extracts an entry from a list, leaving the list one entry shorter (which means it will eventually become empty, leading to your error above). This is great for sampling without replacement: it means that we can’t choose the same entry more than once, as once chosen, it is no longer present in the list to be chosen again.

numpy.random.choice() meanwhile, just gives you a reference to a random entry in the list: the list itself is unchanged, so the same entry could be chosen again next time.

I did suspect that I shouldn’t be using .pop() anymore, but just wasn’t sure how to replace it! Thanks for explaining how .pop() and numpy.random.choice() are working. Really great to know this so I can apply to future experiments.

This is super - thanks again Michael for your help! :smiley: