IndexError: list index out of range using classes - python

class Island (object):
def __init__(self, i,j,k, wolf_count=0, eagle_count=0, rabbit_count=0, pigeon_count=0,):
'''Initialize grid to all 0's, then fill with animals
'''
# print(n,prey_count,predator_count)
self.i=i
self.j=j
self.k=k
self.cube= []
for k in range(k):
self.square=[]
for j in range(j):
row=[0]*i
self.square.append(row)
self.cube.append(self.square)
self.init_animals(wolf_count, eagle_count, rabbit_count, pigeon_count)
def init_animals(self,wolf_count, eagle_count, rabbit_count, pigeon_count):
count = 0
while count < wolf_count:
i = random.randint(0,self.i-1)
j = random.randint(0,self.j-1)
k = 0
if not self.animal(i,j,k):
new_Wolf=Wolf(island=self,i=i,j=j,k=0)
count += 1
self.register(new_Wolf)
def animal(self,i,j,k):
'''Return animal at location (i,j,k)'''
if 0 <= i < self.i and 0 <= j < self.j and 0 <= k < self.k:
return self.cube[i][j][k]
else:
return -1
These are sections of my program which are calling each other. When I try to run the program it gives me:
IndexError: list index out of range.
It says it for the return self.cube[i][j][k] in animal(). In reference to the if not self.animal(i,j,k): section in init_animals(). which is again in reference to the line isle = Island(i,j,k, initial_Wolf, initial_Pigeon, initial_Eagle, initial_Rabbit) in __init__().
any idea why I get this error? Sorry if its hard to read.

Your outer list self.cube has k entries, each a nested list with j entries, each containing lists of i entries. Reverse your indices:
return self.cube[k][j][i]
or invert the way you are creating your self.cube list:
for _ in range(i):
square = []
for _ in range(j):
square.append([0] * k)
self.cube.append(self.square)
or more compact still using list comprehensions:
self.cube = [[[0] * k for _ in range(j)] for _ in range(i)]

Related

List index out of range error in merge sort function

I Wrote the program of Merge sort and while copying arrays i am getting error of list index out of range while assigning values to new array at L[i] = A[p+i]
A = [1,2,6,8,3,4,5,7]
# p = 0,r = 7 ,q = 3
def Merge(A,p,q,r):
n1 = q - p
n2 = r - q
L = []
R = []
for i in range(n1):
L[i] = A[p+i]
for i in range(n2):
R[i] = A[q+i]
i = 0
j = 0
Array = []
for x in range(p,r):
if L[i] < R[j]:
Array[x] = L[i]
i = i +1
else:
Array[x] = R[j]
j = j +1
Merge(A,0,3,7)
Your L and R arrays are empty and you try to access L[i] and R[i] in the for loop. This leads to the index error. Try to initialize the array first to access its index.

Can someone say what went wrong in this code?

I am working on a problem which takes a nums, row, column as parameters and returns a resultant matrix of size row x column.
def matrixReshape(self, nums, r, c):
"""
:type nums: List[List[int]]
:type r: int
:type c: int
:rtype: List[List[int]]
"""
count = 0
i = j = 0
m = [[0]*c]*r
for row in nums:
for val in row:
if j < c and i < r:
print(val,m[i][j], i, j)
m[i][j] = val
print(val,m[i][j], i, j)
count += 1
j += 1
if j == c:
i += 1
j = 0
if count == (r*c):
return m
else:
return nums
When I tested for input like ([[1,2],[3,4]], 4, 1) it generates output [[4],[4],[4],[4]] instead of [[1],[2],[3],[4]]
m = [[0]*c]*r
This creates a list of r references to the same inner list. So, whenever you modify m[0], you're also modifying m[1], and so on, because they're the same list.
You probably wanted something like this:
m = [[0 for _ in range(c)] for _ in range(r)]
[0]*4 gives you four copies of the same object, not four independent lists.
Try
m = [[0 for i in range(c)] for j in range(r)]

Selection sort - python

I can't seem to make my selection sort work. Any idea whats wrong? When run it gives me [5,6,3,1]
Thx!
aList = [1,5,6,3]
def selection_sort( aList):
for i in range(len(aList)):
min = i
j = i + 1
for j in range(len(aList)):
if aList[j] < aList[min]:
min = j
swap(aList, min, i)
print(aList)
def swap(aList, x, y):
temp = aList[x]
aList[x] = aList[y]
aList[y] = temp
selection_sort(aList)
As I mentioned in the comment, it seemed to me that you used j = i + 1 in hopes that it will somehow effect the j in the subsequent loop, but it is a different variable. So is the aList in your function definition, it can have any name, even aList. Your j is iterating over the entire list again and again and hence the min or the smallest value is carried wherever i goes (so it ended up in the end). So what you need to do is make your second loop only iterate through the next items after i.
aList = [1,5,6,3]
def selection_sort(List):
for i in range(len(List)):
min = i
for k in range(i,len(List)):
if List[k] < List[min]:
min = k
swap(List, min, i)
print(List)
def swap(List, x, y):
temp = List[x]
List[x] = List[y]
List[y] = temp
selection_sort(aList)
def select_sort(l):
for i in range(len(l)):
min_loc = i
for j in range(i+1, len(l)):
if l[j] < l[min_loc]:
min_loc = j
l[min_loc],l[i] = l[i], l[min_loc]
return l

Finding value in a matrix using python

I am getting the error 'int object is not iterable' on this method in my class. Someone assist me find the bug as I can't see what I am doing wrong
def find(self, val): #finds value in matrix
if 0 <= val <= 8:
for i,j in range(3):
#for j in range(3):
if self.matrix[i][j] == val:
return i, j
return None
def find(self, val): # finds value in matrix
if 0 <= val <= 8:
for i in range(3):
for j in range(3):
if self[i][j] == val:
return i, j
return None
Example:
self = [[2,1,2],[1,6,4],[0,0,2]]
val = 4
i, j = find(self, val)
print(i)
print(j)
Print:
1
2
If define self as matrix of numpy:
def find(self, val): # finds value in matrix
if 0 <= val <= 8:
for i in range(3):
for j in range(3):
if self.item((i, j)) == val:
return i, j
return None
here is the part of your code that is causing the error
for i,j in range(3)
the python's built-in range function generates a sequence of number that are then assigned to one variable, but you're using two variables instead
. This is how your code should be :
def find(self, val): #finds value in matrix
if 0 <= val <= 8:
for i in range(3):
for j in range(3):
if self.matrix[i][j] == val:
return i, j
return None

Dynamic Programming: Rod cutting and remembering where cuts are made

So I have this code in python and currently it only returns the maximum value for cutting a rod. How can I modify this to also give me where the cuts were made? It takes a list of prices whose indices+1 correspond to the value of the rod at each length, and n, for length of the rod.
the problem:http://www.radford.edu/~nokie/classes/360/dp-rod-cutting.html
def cutRod(price, n):
val = [0 for x in range(n+1)]
val[0] = 0
for i in range(1, n+1):
max_val = 0
for j in range(i):
max_val = max(max_val, price[j] + val[i-j-1])
val[i] = max_val
return val[n]
If this is the question : Rod cutting
Assuming code works fine, You will have to add a condition instead of Max operation to check which of two was picked and push that one in an array :
def cutRod(price, n):
val = [0 for x in range(n+1)]
val[0] = 0
output = list()
for i in range(1, n+1):
max_val = 0
cur_max_index = -1
for j in range(i):
cur_val = price[j] + val[i-j-1]
if(cur_val>max_val):
max_val = cur_val #store current max
cur_max_index = j #and index
if cur_max_index != -1:
output.append(cur_max_index) #append in output index list
val[i] = max_val
print(output) #print array
return val[n]
I know this is old but just in case someone else has a look...I was actually just looking at this problem. I think the issue is here that these dp problems can be tricky when handling indices. The previous answer is not going to print the solution correctly simply because this line needs to be adjusted...
cur_max_index = j which should be cur_max_index = j + 1
The rest...
def cut_rod(prices, length):
values = [0] * (length + 1)
cuts = [-1] * (length + 1)
max_val = -1
for i in range(1, length + 1):
for j in range(i):
temp = prices[j] + values[i - j - 1]
if temp > max_val:
max_val = prices[j] + values[i - j - 1]
cuts[i] = j + 1
values[i] = max_val
return values[length], cuts
def print_cuts(cuts, length):
while length > 0:
print(cuts[length], end=" ")
length -= cuts[length]
max_value, cuts = cut_rod(prices, length)
print(max_value)
print_cuts(cuts, length)
Well, if you need to get the actual pieces that would be the result of this process then you'd probably need a recursion.
For example something like that:
def cutRod(price, n):
val = [0 for x in range(n + 1)]
pieces = [[0, 0]]
val[0] = 0
for i in range(1, n + 1):
max_val = 0
max_pieces = [0, 0]
for j in range(i):
curr_val = price[j] + val[i - j - 1]
if curr_val > max_val:
max_val = curr_val
max_pieces = [j + 1, i - j - 1]
pieces.append(max_pieces)
val[i] = max_val
arr = []
def f(left, right):
if right == 0:
arr.append(left)
return
f(pieces[left][0], pieces[left][1])
f(pieces[right][0], pieces[right][1])
f(pieces[n][0], pieces[n][1])
return val[n], arr
In this code, there is an additional array for pieces which represents the best way to divide our Rod with some length.
Besides, there is a function f that goes through all pieces and figures out the optimal way to divide the whole Rod.

Categories

Resources