Error: "list index out of Range"
Hey there!
I have been struggling to make a working memory task that's basically a letter version of the delayed match to the sample task.
The experiment starts with a fixation, a blank screen and then a series of Capitalized letters are displayed in a clock wise pattern with each letter being displayed for 1500 ms. The number of letters displayed is varied between 4 to 10. After the letter sequence there is a delay that ranges from 1300 ms to 1800 ms. This is followed by a target or a non target screen where the target letter is one of the letter from those previously shown letters but this time they are in non caps version. The subject has to respond whether the letter belonged to those previously shown letters.
On the basis of the description I've made the following design:
ISI (1300-1800: so basically I have 6 levels here i.e., 1300, 1400...1800) X Stimulus_set ( the number of letters i.e., 4,5,6,7,8,9)
I am sorry but I had posted a discussion previously (here) however, due to some research demands I have to make a subtle changes in the experiment.
I have added a inline code to generate the list of letters which is as follows:
import random
import string
letters = list(string.ascii_uppercase)
stim = []
if var.Stimulus_set == 4:
var.stim = random.sample(letters, 4)
elif var.Stimulus_set == 5:
var.stim = random.sample(letters,5)
elif var.Stimulus_set == 6:
var.stim = random.sample(letters,6)
elif var.Stimulus_set == 7:
var.stim = random.sample(letters,7)
elif var.Stimulus_set == 8:
var.stim = random.sample(letters,8)
elif var.Stimulus_set == 9:
var.stim = random.sample(letters,9)
if var.Target == "On":
tar = random.sample(stim, 1)
var.tar_lower = map(str, tar)
var.nontar = None
else:
nontar = random.sample(letters, 1)
nontar = map(str,nontar)
var.tar_lower = None
print stim
While running the experiment I seem to get an error saying "list index out of range"
I am not sure what this error means I had looked up into still I am I could not understand the solution
I have attached the experiment file as well
It seems my amateurism in coding is the issue
I would be grateful if someone could help me resolve this and I am pretty open to tough comments t0o
Thanks
Vatsal
Comments
Hi Vatsal,
Right now all the letter are displayed regardless of the value of var.Stimulus_set. So when stimulus set is 4, and there are four letters in stim (be carefull with using stim and var.stim) and when we get to letter 5 there are no more letters and the [=stim[5]] cannot be retrieved.
One thing you could do is enter specific values in the the 'runfif' part of the sketchpads, such as: '[Stimulus_set]=9', attached a crude example, there are some other issues but hope this at least helps, good luck
Hi Roelof!
Thanks for replying.
I just want to reiterate what you said:
So, the flow of the experiment is that at a minimum 4 letters are shown so I have used 9 sketchpads where upto sketchpad no 4 i.e., "letter4" opensesame should display whatever letters that are stored in stim. As you said I should modify the run if part of the sketchpad and not use 9 sketchpad for this right? So this way I wont need the if..elsif loop that I had created in the inline script?
Btw what other issues you were referring to I would be grateful if you could point them out?
Thanks
Vatsal
Right, my previous answers was incomplete (and to some extend incorrect), all the sketchpads are drawn in the prepare phase, this means that regardless of the 'run if' statements they will try to prepare and collect the stimulus number, only afterwards they evaluate the 'run if' statement.
So, trying to stay as close to your original design, we could make a list with random filler letters, and replace them with the real stimuli letters, and then only draw the sketchpads if the if statement evaluates to true.
Other general notes:
The general structure could use a practice block and some distinction between multiple block in the experimental phase, right now your loop is just a trial loop that repeats a single trial, but it would handy to have an outer loop that repeats multiple blocks.
Secondly a sketchpad that pops up when a timeout occurred would be handy, and maybe one that informs the participant that a next trial is coming up as well.
Thirdly, I assume that the non-target has to be a letter that is not in the stimulus set? if this is the case you have to carefully look at how you select the non-target since right now there is a chance the non target appears in the stimulus set.
small things:
1fix dot appears for the first letter, but not for the rest, I would either keep the fixation constantly present or remove it completely.
2the location of all the letter has a very heavy bias to the right of the screen, but perhaps that is what you are interested in.
3in the last sketchpad you use 'tar_lower' as well, so I never see a non-target letter appear in the sketchpads, but only 'target letter' vs 'none', is that correct?
Hope this helps, good luck,
Hey Roelof !
Thanks for replying and editing the task.
Though the experiment is running , there seems to be yet another issue which is different from the current discussion. Until now my concern was to display letters however, I've noticed that the experiment partially fulfills what I am intending to do. The experiment should display 4 or 5 or 6 or 7 or 8 or 9 number of letters in sequential order. So, for example if the Stimulus_set variable has a value 9 assigned in a trial the experiment should sequentially display 9 letters one by one around the fixation cross (apologies for the missing cross in the other slides it was mistake by me). However, the experiment currently displays only for 4 or 5 letters even if the value of stimulus_set is 9. Essentially while displaying 9 letters all the displaying sketchpads should work thus, the letters should run through every locations around the cross even those locations that are assigned to other stimulus_set values. Thus, the letter presentation should be incremental incorporating all the values preceding the current ones. Thus, I am scratching my head as to how can I do this. If you've any ideas about this please feel free to share .
Coming to the location well, I had made the experiment in a very crude and I am searching for the coordinate value that are equally spaced in respect to each other.
Lastly, I do not intend to give practice trial since this could mask the real performance. The current task is a part of a test battery that contains other tasks of the similar nature.
Thanks again
Vatsal
Right, I can see what you mean, in that case the 'run if' code has to be changed slightly, right now the sketchpads only run if the exact size of the stimulus set is either 4 or 5 or etc. It should look something like this:
[Stimulus_set]>3
instead of
[Stimulus_set]=4
and a similar replacement for the statements regarding the other set sizes
Thanks Roelof
The task is running fine
Apologies for the delay in response
Vatsal
Hey @Roelof !
``
I am here again with a problem. I have made a visuospatial N-back task. Currently, I have made a 2 back version of it but here again I am facing the same proble. "list index out of range"
I have done some coding to generate the number which I'll use to present my stimuli.
I have 8 set of pictures where a blue colored square is displayed at 8 different prositions around the fixation cross. I have coded to generate numbers between 1 to 8. The following are the parts of code
creating a variable called 'numbers' that holds numbers from 1 to 8:
import random
numbers = range(1,9)
creating a target empty list
tar = []
creating a normal stimulus list
n = []
creating a stack list to store the generated numbers. This stack list will be used to evaluate if the numbers are same at 2 back level
stack = []
In this piece of code I evaluate whether the stack list is at least 2 elements long. This is because in order to present a target number the target number should match to a number presented one trial before.
if len(stack) == 1 or len(stack) == 2: print(n)
After this I evaluate if the numbers the presence of a target number in target present case (i.e., target == yes) or if its not the case then generate another number and avoid picking up the same number.
elif var.target == "off" and stack[-3] == n and (n % 2)== 0: stack.pop() n = random.sample(numbers, 1) stack.append(n) elif var.target == "off" and stack[-3] != n: print(n) elif var.target == "on": tar = stack[-3]
Please feel free to ask any question.
experiment attached.
Thanks
Vatsal
@Roelof any lead???
Hello Vatsal,
In your experiment I see everthing in the unused items area, like this
are you sure this is the right version? (otherwise something is wrong on my end)
As for the error: it'll be handy to see the error message; but I guess that would also be solved perhaps with the correct experiment; as far as I can see for now it looks okay, but I guess there is an indexing problem somewhere,
Roelof
Hey Roelof
Thanks for the reply!
Strange. Currently I am using version 3.0 should I update it to the latest version?
I have made a new experiment the error remains (list index out of range). Also I have made some changes in the script as well
which is:
if len(stack) <4: print(n)
elif len(stack) == 4 or len(stack) > 4 and var.target == "off" and stack[-3] == n
instead of
Hi Vatsal,
The printscreen looks like it is from opensesame 2.0, since it has the 'old look', however, the experiment you attached works now, and I get indeed an index error.
What is happening is that
tar
sometimes remains empty:[8] [] this is the tar [1] [] this is the tar [5] [] this is the tar [] this is the tar [] this is the tar [] this is the tar [] this is the tar [6] [] this is the tar
And as soon as tar is empty, the sketchpad with tar[0] encounters an indexing error.
One simple way to avoid the error is by saying
tar = [1]
This is a little bit dangerous though, since if the "if else" structure is not precisely execute the script will still run and your target is defined as 1, which might not be true.
A safer way is by presenting the target in an inlinescript, and getting rid of the sketchpad:
in prep phase:
c1 = canvas() if var.target == 'on': file = '.jpg' %tar[0] c1.image(file)
and in run:
if var.target == 'on': c1.show()
But that would need some extra work.
some other notes:
1 In the inline script there are two definitions of 'n'.
2 The following line feels complex, and there are
and
andor
statements used intermixed wich might cause confusion, since it could be interpreted in multiple ways, namely:elif len(stack) == 4 or ( len(stack) > 4 and var.target == "off" and stack[-3] == n and (n % 2)== 0: )
or:
elif len(stack) == 4 or ( len(stack) > 4 ) and var.target == "off" and stack[-3] == n and (n % 2)== 0:
3 Your stack consist of a list of lists, does not matter too much but might cause confusion:
[[1], [3], [8], [1], [4], [7]]
(it actually does cause error, esp. with this line:
(n % 2)== 0:
which does not work sincen
is a list)you could consider replacing it by something like:
range_start = 1 range_end = 9 n = random.randint(range_start,range_end)
4 The variable target is for the first couple of trials empty: it is always a good idea to never have empty cells for a variable
Hope this helps, let me know if it doesn't work out,
Roelof
Hey Roelof
Thanks for your reply.
So lemme first reiterate what you suggested:
I need to do away with the sketchpad items and use inline to present the pictures
I need to re-write the if and elsif statements since they seemed to be confusing:
The purpose of this code was to print the value of 'n' until there the length of stack is 3 or beyond that. This is because in 2-nback level the the probability of a target can only be possible untill there are 3 stimulus being presented. Thats why I wrote:
if len(stack) < 4: print(n)
The second if and elif statement was to check if the length of stack is 4 and at the same time evaluate if the target variable is "off" and if its off then double check if the number currently stored in stack and n is not same as the one selected 2 trials before. However, this would cause an error as you said before the stack contains sublists.
One solution you said that I should use rand.randint() function to generate the number. Additionally, I should find a way to assign the result to n and to stack simultaneously. However, in case of stack in the forthcoming trials the newer item replace the older ones. The purpose of stack is to keep track of items so that they can be extracted in target on condition while the purpose of n is to just display numbers.
I have re-checked the loop but there are no empty cells in the target variable
Thanks
Vatsal
Hi Vatsal,
1. If you want to avoid errors that relate to the prepare phase that is mandatory in the sketchpads, inline scripts would solve it, but this needs more coding.
2. Yes, the if-else is not clear; use brackets, or split in multiple lines
3. Not sure what you mean by assign and stack n simultaneously
4. Empty cells: maybe this was another bug, but my loop table looked like this:
5.
Hope it works out, good luck
The way Python indexing works is that it starts at 0, so the first number of your list would be [0]. Index Error: List index out of range means you are trying to get an item in a list that doesn't exist. It means that you are referring to n-th element of the list, while the length of the list is smaller than n. whenever you get this type of error please cross check with items that comes between/middle in range, and insure that their index is not last if you get output then you have made perfect error that mentioned.