I am making an infinite loop where python turtles draw a radar and an enemy. Everything works fine except every so often my program ends with the error.
IndexError: list assignment index out of range
This is the code:
##figuring out where the enemy is
bogey1x = random.randint(1, 15)
bogey1y = random.randint(1, 10)
ran = random.randint(-1,10)
rancirc = random.randint(-1,15)
truelist = []
circlist = []
## tracking the enemy
for n in range(10):
truelist.append(0)
truelist[ran] = 1
for n2 in range(15):
circlist.append(0)
circlist[rancirc] = 1
I don't know how much code I should put here, so if I need to put more so you can help me I will.
I tried to mess with the values of both the list as well as the random number. Nothing worked. The point of these lists is to have them be full of zeros and one 1. Then, later in the code, a conditional statement determines if it has found the 1 yet. If it has then it places a mark where the enemy is. It seems to work other that the code breaking.
Related
Question originally posted in Spanish, on es.stackoverflow.com, by Ezequiel:
I am trying to make a program that removes certain elements from a
group of lists if a certain condition passes, and that duplicates them
if a certain other happens. But I have the following problem: when
the program is in iteration 50 of 100, it marks IndexError and
closes.
Here is the code snippet in which I have the problem:
nnl_len = len(neuralNetworkList) # longitud de lista de objetos
fitl_copy = fitness # lista de floats
best_fitness_reproduced = 0
if worst_fitness < 0 and first_iteration == 0: # I guess this can
worst_fitness = 0 # be ignored
for i in range(nnl_len):
print(i)
if fitl_copy[i] < best_fitness: # EXACT LINE OF THE ERROR <------------------
print("I DIED WITH A FITNESS OF ",fitness[i], ", BEING THE LIMIT ",best_fitness)
neuralNetworkList.pop(i)
x.pop(i)
y.pop(i)
fitness.pop(i)
colors.pop(i)
elif fitl_copy[i] == best_fitness and best_fitness_reproduced:
print("I DIED BECAUSE A TOP FITNESS CREATURE ALREADY REPRODUCED ",fitness[i])
neuralNetworkList.pop(i)
x.pop(i)
y.pop(i)
fitness.pop(i)
colors.pop(i)
else:
best_fitness_reproduced = 1
for j in range(99): # plus the mother is 100
print("I SURVIVED WITH A FITNESS OF ",fitness[i], ", BEING THE LIMIT ",best_fitness)
neuralNetworkList.append(neuralNetworkList[i])
if random.randint(1,3) == 1:
neuralNetworkList[i].mutate(i)
x.append(width)
y.append(height)
fitness.append(0)
newcolor = []
for h in range(3):
newcolor.append(round( colors[i][h]*random.choice((0.9, 1.1)) ))
colors.append(newcolor)
#except IndexError:
# pass
# print("I NEITHER DIED NOR REPRODUCED BECAUSE OF AN INDEX ERROR")
nnl_len = len(neuralNetworkList)
for i in range(nnl_len):
x[i] = width
y[i] = height
fitness[i] = 0
print("population after reproduction:", len(neuralNetworkList))
this is the traceback:
Traceback (most recent call last):
File "C:\Users\Ezequiel\Desktop\Archivos pavos\Sublime Text 3\pruebas_phyton.pyw", line 4921, in <module>
if fitl_copy[i] < best_fitness: # fitness[i] <= worst_fitness*4
IndexError: list index out of range
when the program is in iteration 50 of 100, it marks IndexError and closes.
That is the clue; the problem happens halfway through the process. This is a sign of trying to remove from a list while iterating over it; each time through the loop you remove an element, so after 50 times you have i == 50 and only 50 elements still in the list, so the index is out of bounds.
Why does this happen? Well...
fitl_copy = fitness # lista de floats
This does not make a copy of fitness; it makes another name for fitness.
Consequently, these two lines...
if fitl_copy[i] < best_fitness:
# ...
fitness.pop(i)
operate on the same list; and boom.
I think you should first try to rethink your algorithm. My guess is that you don't really need to want to do all this popping from lists at all. I think you will have a much easier time if you:
Rewrite so that you produce a new list with all of the creatures for the new generation, starting from scratch (empty list)
Leave the old creature list alone while you do this, and then just replace it with the new list at the end
You may also benefit from using some kind of structured data for your creatures, instead of having parallel lists with all their attributes; and also by using list comprehensions and generators instead of for-loops.
I'm new to a programming language and wanted to start with Python as its the recommendation of most people (as far as i see).
So, im practising on some functions to improve my understanding on loops, and basic statements etc. Though i'm not very good at it yet, i do believe that i'll improve sooner or later.
Here is an example where i'm stuck at:
def L():
List = []
TauS = []
a = 12
for i in range(1,a+1):
if a % i == 0:
List.append(i)
if a % len(List) == 0:
TauS.append(a)
print(List)
print(TauS)
L()
This is the function i want to have and the output is:
[1, 2, 3, 4, 6, 12]
[12]
As i expected.However, the problem is that i want "a" to be a variable instead of a constant.Something like:
def L():
List = []
TauS = []
for a in range(2,20):
for i in range(1,a+1):
if a % i == 0:
List.append(i)
if a % len(List) == 0:
TauS.append(a)
print(List)
print(TauS)
L()
Fails because it seems like for loop is working before the 2nd if statement (if a % len(list)) == 0: TauS.append(a)).I have also tried a "while" loop instead of a "for" loop as:
a = 2
while a <= 20:
for i in range(1,a+1):...(The rest is the same)
It would be a better idea if your help focus on the basic ideas instead of just giving the right function.
Thanks a lot from now!
Regards.
Python uses indention levels to tell whether code is in within a function, loop or condition, the general thing being that if there is a : then all the code indented underneath it is within that statement.
The problem with your code is that the second if statement is on the same indention level as the for loop rather than being on the indention level below the for loop. This means that rather than running in the for loop it runs after it.
So to fix your code all you need to do is select the if statement and press crtl + ] which is pythons keyboard shortcut for indent code section.
edit:
I think what you're asking for is to get all the factors of numbers from 2 to 19 and then print numbers where the number of factors is a factor of that number.
def L():
List = []
TauS = []
for a in range(2,20):
l=[] #this is the list for each individual number
#if i is a factor of a add it to l
for i in range(1,a+1):
if a % i == 0:
l.append(i)
#if length of l is a factor of a add a to TauS
if a % len(l) == 0:
TauS.append(a)
List.append(l)
print(List)
print(TauS)
L()
It fails because of variable scope.
Python uses indention to represent code block. So, here for loop and 2nd if condition has same indention which means they belong to same code block and can access variables defined in the same or the outer code block. "List" & "Taus" in this case.
However, Variable "a" is localize to outer for loop and can be access in the same or inner for loop and cant be access from outside. Similarly variable "i" is specific to inner for loop and cant be access outside of the loops block, not even from outer for loop.
Hope it helps...
In this piece of code
def maxVal(toConsider, avail):
if toConsider == [] or avail == 0:
result = (0, ())
elif toConsider[0].getCost() > avail:
result = maxVal(toConsider[1:], avail)
else:
nextItem = toConsider[0]
withVal, withToTake = maxVal(toConsider[1:],
avail - nextItem.getCost())
withVal += nextItem.getValue()
withoutVal, withoutToTake = maxVal(toConsider[1:], avail)
if withVal > withoutVal:
result = (withVal, withToTake + (nextItem,))
else:
result = (withoutVal, withoutToTake)
return result
How is withVal not some sort of infinite loop because it gets it's assigned variables from the function, which means it repeats again without the first variable so shouldn't it just keep going and going? Until avail reaches 0 but then it also is added to 'nextItem' which drives my head in.
So I know that
withVal, withToTake = maxVal(toConsider[1:],
avail - nextItem.getCost())
comes before
withVal += nextItem.getValue()
And doesn't for an infinite loop, so my question is how is withVal able to stay in order with 2 assignments considering the first example demonstrates that it recalls the function again?
This function is guaranteed to terminate since avail == 0 isn't the only stopping condition. It also suffices to have toConsider == []. When you call the code
withVal, withToTake = maxVal(toConsider[1:],
avail - nextItem.getCost())
Notice in particular the snippet [1:]. This says that you're only passing in most of the toConsider list. It's getting smaller each time by 1, and eventually its length will hit 0. Since the recursion eventually ends, you're able to finally get to the next assignment withVal += nextItem.getValue().
Sometimes getting to the bottom of questions like this can be made easier in the beginning with pythontutor.com, which allows you to step through and visualize code one piece at a time and see which values change in which order. I'm not affiliated with them, but they have an okay product for small problems like this.
Hello i'm new to Python and i'm having a little trouble. I'm reading Hello Python
and i'm typing a code down it told me to type, but when i run the code, it gives me an error.
Error: caves[next_cave].append(i) List index out of range
This is the code i'm typing out.
Code:
from random import choice
cave_numbers = range(0,20)
caves = []
for i in cave_numbers:
caves.append([])
unvisited_caves = range(0,20)
visited_caves = [0]
unvisited_caves.remove(0)
while unvisited_caves != []:
i = choice(visited_caves)
if len(caves[i]) >= 3:
continue
next_cave = choice(unvisited_caves)
caves[i].append(next_cave)
caves[next_cave].append(i)
visited_caves.append(next_cave)
unvisited_caves.remove(next_cave)
for number in cave_numbers:
print number, ":", caves[number]
print'-----------'
for i in cave_numbers:
while len(caves[i]) < 3:
passage_to = choice(cave_numbers)
cave[i].append(passage_to)
for number in cave_numbers:
print number, ":", caves[number]
print '----------'
Thank you for answering my question
-Cyr
choice(unvisited_caves) in going to return a number from unvisited_caves = range(0,20), so that would be a random number from 0..19.
caves[next_cave].append(i) will error 90% of the time (18/20 times) because all you have done is caves = [] and caves.append([]), so caves has at most one element in the first iteration of your program.
Maybe you have an indentation problem, but overall, using random numbers of a different range to index a list seems like a bad design.
I think your problem is just with indentation. I believe that your intent was to use the for loop to give your list of caves 20 empty arrays before you begin your simulation. As you had it, your loop would add one array and then start the simulation right away. Your caves list is not ready for this, and so it errors.
The following should work better:
from random import choice
cave_numbers = range(0,20)
caves = []
for i in cave_numbers:
caves.append([])
unvisited_caves = range(0,20)
visited_caves = [0]
unvisited_caves.remove(0)
while unvisited_caves != []:
i = choice(visited_caves)
if len(caves[i]) >= 3:
continue
next_cave = choice(unvisited_caves)
caves[i].append(next_cave)
caves[next_cave].append(i)
visited_caves.append(next_cave)
unvisited_caves.remove(next_cave)
for number in cave_numbers:
print number, ":", caves[number]
print'-----------'
for i in cave_numbers:
while len(caves[i]) < 3:
passage_to = choice(cave_numbers)
caves[i].append(passage_to)
for number in cave_numbers:
print number, ":", caves[number]
print '----------'
I only made two edits:
First, I unindented so that the while loop comes after the for loop finishes
You also had a typo where you said cave[i] instead of caves[i]
Also note, there are some opportunities to simplify your code here. At first this may seem merely aesthetic, but it can actually help avoid errors like this. For example:
for i in cave_numbers:
caves.append([])
can become caves = [ [] for each in cave_numbers] which would have left less room for errors.
That error means that at some point, the value in next_cave exceeds the length of the caves list.
You'd get that same error by doing this:
caves = [[0,1,2], [4,5,6]]
caves[2].append([7,8,9])
I am using the simple program below to see how long an iterative process takes to terminate. However, in line 15, I cannot figure out why I am getting index out range error.
An example of what I am trying to count is the number of steps it takes for the following example iteration: User inputs 4 and then 1234. Then we have: [1,2,3,4] --> [1,1,1,1] --> [0,0,0,0] and then termination. 2 steps is required to get to [0,0,0,0]. I have proven that for the values of n that I am inserting, the system goes to [0,0,0,0] eventually.
import math
index = input("Enter length: ")
n = int(index)
game = input("Enter Coordinates of length n as a number: ")
s = list(game)
Game = []
for k in s:
Game.append(int(k))
l = len(game)
while sum(Game) > 0:
Iteration = []
k = 0
j = 0
while j < l-1:
Iteration.append(math.fabs(Game[j]-Game[j+1])) # line 15
j = j+1
k = k+1
Game = Iteration
print(k)
Game = Iteration is probably why. When j = 1, Game will be a list with only one item because of that. Then, Game[1]-Game[2] will be out of bounds.
Your code is written in a very un-Pythonic style that suggests you're translating directly from C code. (Also, you should basically never use input(); it's insecure because it evaluates arbitrarily user-entered Python code! Use raw_input() instead.)
If you rewrite it in a more Pythonic style, it becomes clear what the problem is:
import math
# you don't do anything with this value, but okay
s = index = int(raw_input("Enter length: "))
# game/Game naming will lead to confusion in longer code
game = raw_input("Enter Coordinates of length n as a list of comma-separated numbers: ")
Game = [int(k) for k in game.split(',')]
l = len(Game)
while sum(Game) > 0:
Game = [math.fabs(Game[j]-Game[j+1]) for j in range(l-1)] # problem here
# no idea what k is for, but it's not used in the loop anywhere
The problem is that in every iteration through your inner while loop, or the line marked # problem here in my version, your Game list gets shorter by one element! So on the second time through the outer while loop, it reads an element past the end of Game.
I have no idea what this code is trying to do, so I can't really suggest a fix, but if you truly intend to shorten the list on every pass, then you of course need to account for its shorter length by putting l=len(Game) inside the while loop.