list index out of range in while loop - python

I'm trying to implemnt Minesweeper game , but i'm stuck , i'm getting the list out of range error and i don't where i did wrong
def Int_jeu(largeur,longueur,diff):
global n, m,T
dif = diff
n=largeur
m=longueur
T = [[0 for i in range(n)] for j in range(m)]
d=((n*m)*dif)//100
print(len(T[0]))
for i in range(d):
a=random.randint(0,len(T)-1)
b=random.randint(0,len(T[0])-1)
while (T[a][b] == "2"):
a=random.randint(0,n-1)
b=random.randint(0,m-1)
T[a][b] = "2"
return(T)
this is the line where i got the error
while (T[a][b] == "2"):
i have declared the matrix T out of the int_jeu function
T = []
can anyone explain me why i get the error please.

m is your first dimension, n is your second, but a is used to index the first dimension (m) while being derived from n (same for b, in reverse).
Change:
a=random.randint(0,n-1)
b=random.randint(0,m-1)
to:
a=random.randint(0,m-1) # Or to simplify, random.randrange(m)
b=random.randint(0,n-1) # Or to simplify, random.randrange(n)
to fix.

Related

Need explaination of a python code - newbiew to Python

I am quite new to Python and there is one assignment that I could not understand even though I have already reviewed similar solutions:
Assignment: Find K numbers in a list that their sum is equal to M ( input K and M). Print these numbers
For example:
Array= [3,2,4,8,5]
Input:K=2, M=5
Output: [3,2]
Input: K=3, M=13
Output: [3,2,8]
Here is a solution of this modified assignment: print all subsequences that their sum is equal to M.
def subsetSumToK(arr,k):
if len(arr)==0:
if k == 0:
return [[]]
else:
return []
output=[]
if arr[0]<=k:
temp2=subsetSumToK(arr[1:],k-arr[0]) #Including the current element
if len(temp2)>0:
for i in range(len(temp2)):
temp2[i].insert(0,arr[0])
output.append(temp2[i])
temp1=subsetSumToK(arr[1:],k) #Excluding the current element
if len(temp1)>0:
for i in range(len(temp1)):
output.append(temp1[i])
return output
arr=[int(i) for i in input().split()]
k=int(input())
sub=subsetSumToK(arr,k)
for i in sub:
for j in range(len(i)):
if j==len(i)-1:
print(i[j])
else:
print(i[j],end=" ")
Ex: Input:K=2, M=5
Output: [3,2], [5]
The problem here is, even though I have already had seen solutions, I tried to do manually by doing iterations by hand, but I could not understand the algorithm, maybe I read it wrong. I really need your help.
Especially starting from these lines:
if arr[0]<=k:
temp2=subsetSumToK(arr[1:],k-arr[0]) #Including the current element
if len(temp2)>0:
for i in range(len(temp2)):
temp2[i].insert(0,arr[0])
output.append(temp2[i])
Here were my plain explainations:
arr=[3,2,4,8,5], K=5
#1st iteration:
if array[0] #(=3)<=5 :True
temp2=subsetSumToK(arr[1:],k-arr[0]) # temp2= ( [2,4,8,5], 2)
if len(temp2)>0 #(2>0: True):
for i in range (len(temp2)): # i=0
temp2[i].insert(0,arr[0]) # temp2[0]=[2,4,8,5]
# => temp2= ( [3,2,4,8,5],2)
output.append(temp2[i]) # output= ([3,2,4,8,5])
#2nd iteration:
for i in range (len(temp2)): # i=1
temp2[i].insert(0,arr[0]) # temp2[1]= (2)
#=> temp2= ( [3,2,4,8,5], 2, 2) ????
output.append(temp2[i]) # output= ( [3,2,4,8,5], 2)?????
# And then I realised that the length of temp2 goes to infinitive.....
# Far beyond

looping gives me the same set of matrices

Hello so I am trying to run this code where i want X_Matrices dictionary to contain all the X_matrix_i matricies. However, all i am getting that X_Matrices end up being the final X_matrix_i of the final loop. I am not quite sure where i am stuck. Any information would be appreciated! thanks.
n = 5
T = 3
p = 5
X_matrix_i = np.zeros((T,p))
X_Matrices = {}
for i in range(n):
X_Matrices["X" + str(i)] = np.zeros((T,p))
for i in range(n):
for t in range(T):
#initial randomness for loop t
ϵ = np.random.normal(0,1,1)
η = np.random.normal(0,1,1)
Covu = np.zeros((p,p))
#Generating X and e of X
for j in range(len(Covu[0])): #covariance matrix for vector x
for l in range(len(Covu)):
Covu[l,j] = 0.7**(np.abs(l-j))
Zerop = np.zeros(p) # mean vector for vector x
x = np.random.multivariate_normal(Zerop,Covu)
X_matrix_i[t] = x
X_Matrices["X" + str(i)] = X_matrix_i
There are two problems here. First one is the conflicting "i" variables in for loops.
One of them should be changed! I replaced the first for loop i variable with k.
for k in range(n):
for t in range(T):
#initial randomness for loop t
The second problem is that by doing
X_Matrices["X" + str(i)] = X_matrix_i
(last line) you are referencing X_Matrices["X" + str(i)] to X_matrix_i! The issue with mutable objects in Python happens! Instead of doing so, you should use shallow copy to assign values to X_Matrices["X" + str(i)]. So a copy of X_matrix_i will be assigned, not X_matrix_i itself.
I replaced the last line with
X_Matrices["X" + str(k)][:] = X_matrix_i
and the problem solved.
[:] acts as shallow copy here.
I think your problem is caused by the redeclaration of i in the second for loop
for j in range(len(Covu[0])): #covariance matrix for vector x
for i in range(len(Covu)):
Covu[i,j] = 0.7**(np.abs(i-j))
Try to rename the i to something else and it should solve your problem.

NameError: Name 'ShiftArr' is not defined

# indices to calculate pair-wise products (H, V, D1, D2)
shifts = [[0,1], [1,0], [1,1], [-1,1]]
# calculate pairwise components in each orientation
for itr_shift in range(1, len(shifts) + 1):
OrigArr = structdis
reqshift = shifts[itr_shift-1] # shifting index
for i in range(structdis.shape[0]):
for j in range(structdis.shape[1]):
if(i + reqshift[0] >= 0 and i + reqshift[0] < structdis.shape[0] \
and j + reqshift[1] >= 0 and j + reqshift[1] < structdis.shape[1]):
ShiftArr[i, j] = OrigArr[i + reqshift[0], j + reqshift[1]]
else:
ShiftArr[i, j] = 0
If I try to run the code, I get the following error:
NameError: Name 'ShiftArr' is not defined
How can I solve this error?
By the looks of things you have not defined ShiftArr before you have used it. This is what the error is saying.
It looks like you first use ShiftArr in your nested loop, but nowhere before have you said something like ShiftArr = ...
If you add ShiftArr = [] before your first for loop, this should solve your issue I think. It's a little difficult to understand what you're trying to do as your variable names aren't super informative - this might help you when drying to fix errors in your code.

Defining and populating a matrix in Python

I'm taking a Python class this semester, and my instructor delights in matrices.
My assigned task is as follows:
Create a matrix (x) that is 3 rows, 5 columns.
Populate the matrix using given values loaded from an external file, loading the numbers row-wise (meaning, if you replace the numbers with the order in which they load into the matrix you have:
1, 2, 3
4, 5, 6
7, 8, 9....etc.)
Print the matrix- display it on the screen, and sent the results to an external file.
The given range of numbers is 1,3,5,7,9,0,2,4,6,8,0,1,2,3,4. I have the numbers stored in a file called lab5matrix.dat. The numbers are in the exact same format, commas and all.
The "A" that appears as part of LOADX represents "x". My professor switches up the variables, saying that one doesn't want "too much sugar". I don't have any idea what that means.
When I attempt to run the module i get this:
Traceback (most recent call last):
File "E:/PythonScripts/Lab5-Matrices/lab5matrix.py", line 51, in <module>
main()
File "E:/PythonScripts/Lab5-Matrices/lab5matrix.py", line 15, in main
LOADX(infile, x)
File "E:/PythonScripts/Lab5-Matrices/lab5matrix.py", line 33, in LOADX
A[j][k] = int(templist[n])
IndexError: list index out of range
Any help is sincerely appreciated.
This is my code, The indentation appears to be accurate:
def main():
#matrix initialization
x=[[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]
#file declaration
infile = open('lab5matrix.dat','r')
outfile = open('lab5test.out', 'w')
#call functions
LOADX(infile, x)
#close files
infile.close()
infile.close()
outfile.close()
dummy = input('Press any key to continue.')
#load matrix x
def LOADX(infile, A):
#local variables
n=0
k=0
s=0
templist = (infile.readline().strip('\n').split(','))
while (k<=3):
j=0
while(j<=5):
A[j][k] = int(templist[n])
s=s+A[j][k]
j=j+1
n=n+1
k=k+1
def OUTDATA(outfile, A):
i=0
j=0
k=0
while (k<3):
print(A[k][0],A[k][1],A[k][2],A[k][3],A[k][4])
file.write[str(A[k][0])+str(A[k][1])+str(A[k][2])+str(A[k][3])+str(A[k][3])+str(A[k][4])]
k=k+1
main()
A is a list with 5 elements. So you can only use the numbers 0 to 4 to index it in the function. Note the condition of your inner while loop. You are using the values of j from 0 to 5. When j equals 5 you will run into a problem.
There is a similar problem with the outer while loop.
In the future you should try to debug small errors like this. The easiest way to do this is with print statements! The error message tells you the error is on line 33. It also tells you that there is a list index out of range. So if you simply put print(j,k,n) before the error occurs you can determine what exactly is going wrong for yourself :)
Hope this helps :)
First of all, sorry if I'm not as versed in the etiquette governing this forum as I might be. I'm very new at this particular language- I'm much more proficient in web programming- and while the logic and concepts can be somewhat similar to JavaScript, finding and fixing errors really isn't. Not for me, anyway.
Secondly, the one small question I posted was part of a much larger program that was assigned as a lab...figuring out what I was doing wrong with the X matrix was the Rosetta Stone that helped the whole mess fall into place. I had honestly just gotten to a point where I was just stuck and had no idea what to do. I'm taking this class during summer semester, which is half the length of a regular semester with no fewer assignments or requirements- moving that quickly through this type of material is not conducive to knowledge retention.
A fellow student helped me to get it going...yes, there was a problem with the values in the loop posted above. I fixed that by changing the 'less than or equal to" to just "less than", using all the values up to but not including the value following the operator.
Here's the final (working) X matrix loop:
def loadx(file,A):
#local variable
k=0
n=0
templist=file.readline().strip("\n").split(",")
while(k<5):
j=0
while(j<3):
A[k][j]=int(templist[n])
j=j+1
n=n+1
k=k+1
And, if anyone's interested, I'll post the whole working version of the program- basically, we were given two sets of data, and using these, we wrote a program to load matrix x (5 rows by 3 columns) from a file, loading the values in rows, load matrix y(3 rows, 7 columns) from a file, loading the values in columns, add the sum of column one of the x matrix to the sum of row one of the y matrix, find the smallest value in row 0 of the y matrix, and multiply matrix x by matrix y to generate matrix z, and print the matrices on-screen and write all the results to an outfile.
Simple, right? ; )
sumx=0
sumy=0
def main():
#Matrices declaration
x=([0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0])
y=([0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0])
z=([0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0])
#file declaration
infilex=open("lab5x.dat","r")
infiley=open("lab5y.dat","r")
outfile=open("lab5.out","w")
#variable declaration
totSum=0
small=0
#call functions
loadx(infilex,x)
loady(infiley,y)
computez(x,y,z)
summation(x,y)
small=float(smallest(y))
totSum=(sumx+sumy)
outdata(outfile,x,y,z,small,totSum)
#close files
infilex.close()
infiley.close()
outfile.close()
dummy=input("Please press any key to continue")
#Functions
def loadx(file,A):
#local variable
k=0
n=0
templist=file.readline().strip("\n").split(",")
while(k<5):
j=0
while(j<3):
A[k][j]=int(templist[n])
j=j+1
n=n+1
k=k+1
def loady(file,B):
#local variable
k=0
n=0
templist=file.readline().strip("\n").split(",")
while(k<7):
j=0
while(j<3):
B[j][k]=int(templist[n])
j=j+1
n=n+1
k=k+1
def computez(A,B,C):
i=0
while(i<5):
j=0
while(j<7):
k=0
while(k<3):
C[i][j]=C[i][j]+A[i][k]*B[k][j]
k=k+1
j=j+1
i=i+1
def summation(A,B):
j=0
k=0
totSum=0
#global variable
global sumx
global sumy
while(k<5):
sumx=A[k][1]+sumx
k=k+1
while(j<7):
sumy=B[1][j]+sumy
j=j+1
def smallest(B):
k=0
small=0
while(k<7):
if small>B[0][k]:
small=B[0][k]
k=k+1
return(small)
def outdata(file,A,B,C,D,E):
#local variable
kA=0
kB=0
kC=0
global sumx
global sumy
print("OUTPUT", ("\n"))
print("------")
print("X Matrix", ("\n"))
file.write(str("OUTPUT")+"\n")
file.write("X Matrix"+"\n")
while (kA<5):
print("\n")
j=0
while(j<3):
print(A[kA][j])
file.write(str(A[kA][j])+" ")
j=j+1
kA=kA+1
file.write("\n")
file.write("\n")
print("\n")
print("Y Matrix", ("\n"))
file.write("Y Matrix"+"\n")
while(kB<3):
print("\n")
j=0
while(j<7):
print(B[kB][j]," ")
file.write(str(B[kB][j])+" ")
j=j+1
kB=kB+1
file.write("\n")
file.write("\n")
print("\n")
print("Z Matrix", ("\n"))
file.write("Z Matrix"+"\n")
while (kC<5):
j=0
while(j<7):
print(C[kC][j]," ")
file.write(str(C[kC][j])+" ")
j=j+1
kC=kC+1
print("\n")
file.write("\n")
file.write("Sumx: "+str(sumx)+"\n")
file.write("Sumy: "+str(sumy)+"\n")
file.write("Smallest: "+str(D)+"\n")
file.write("Total Sum: "+str(E))
main()
Just for fun :-)
See below for a more Pythonic implementation of the matrix problem. I've only implemented the matrix multiplication because that's the hardest:
#!/usr/bin/python
# number of rows and colums for matrix x
NROWSX=5
NCOLSX=3
# number of rows and colums for matrix y
NROWSY=3
NCOLSY=7
# class to hold matrix of any dimension
# and some matrix operations
class Matrix(object):
def __init__(self, nrows, ncols):
# define matrix (set dimensions)
self.nrows = nrows
self.ncols = ncols
# create matrix: pass a list and convert it to rows
def fill(self, values):
self.matrix = list(self.chunks(values, self.ncols))
# transpose the matrix
def transpose(self):
# serialise matrix data
__serial = []
for row in self.matrix:
__serial += row
# create new (empty) matrix
__transp = map(list, [[]] * self.ncols)
# populate matrix
for i in xrange(self.nrows):
for j in xrange(self.ncols):
__transp[j].append(__serial[i * self.ncols + j])
# done
__new = Matrix(self.ncols, self.nrows)
__new.matrix = __transp
return __new
# helper function to cut up a list in equally sized chunks
def chunks(self, l, n):
"""Yield successive n-sized chunks from l."""
for i in xrange(0, len(l), n):
yield l[i:i+n]
def __mul__(self, other):
# our ncols must equal other's nrows for multiplication to work
if (self.ncols == other.nrows):
# multiply works best on transposed matrix
other = other.transpose()
# execute multiplication serially
__serial = []
for r1 in self.matrix:
for r2 in other.matrix:
# calculate sum over row x column
s = 0
for i in (x*y for x,y in zip(r1,r2)):
s += i
__serial.append(s)
# turn data into new matrix
__new = Matrix(self.nrows, other.nrows)
__new.fill(__serial)
return __new
else:
raise ValueError, "columns and rows don't match"
def __rmul__(self, other):
# haven't done this one yet...
print '__rmul__ not available'
return None
if __name__ == "__main__":
datax = [1,3,5,7,9,0,2,4,6,8,0,1,2,3,4] # 5x3
datay = [6,8,4,0,7,1,2,2,3,7,1,0,1,8,9,6,4,5,7,9,8] # 3x7
# create and populate matrix x
mtx_x = Matrix(NROWSX, NCOLSX)
mtx_x.fill(datax)
# create and populate matrix y
mtx_y = Matrix(NROWSY, NCOLSY)
mtx_y.fill(datay)
print "\nmatrix x:"
print mtx_x.matrix
print "\nmatrix y:"
print mtx_y.matrix
# multiply both matrices
mtx_z = mtx_x * mtx_y
print "\nmatrix z:"
print mtx_z.matrix

Randomly iterating through a 2D list in Python

My first attempt to accomplish this resulted in:
def rand_Random(self):
randomRangeI = range(self.gridWidth)
shuffle(randomRangeI)
randomRangeJ = range(self.gridHeight)
shuffle(randomRangeJ)
for i in randomRangeI:
for j in randomRangeJ:
if self.grid[i][j] != 'b':
print i, j
self.grid[i][j].colour = self.rand_Land_Picker()
Which has the issue of going through one inner list at a time:
[1][1..X]
[2][1..X]
What I'd like to be able to do is iterate through the 2d array entirely at random (with no repeats).
Anyone have any solutions to this problem?
Edit: Thanks for the replies, it appears the way I view 2d arrays in my mind is different to most!
Create an array with all possible pairs of coordinates, shuffle this and iterate through as normal.
import random
coords = [(x,y) for x in range(self.gridWidth) for y in range(self.gridHeight)
random.shuffle(coords)
for i,j in coords:
if self.grid[i][j] != 'b':
print i, j
self.grid[i][j].colour = self.rand_Land_Picker()
You can consider 2D array as 1D array and randomly iterate through it.
def rand_Random(self):
randomRange = range(self.gridWidth*self.gridHeight)
shuffle(randomRange)
for index in randomRange:
i = index / self.gridWidth
j = index % self.gridWidth
if self.grid[i][j] != 'b':
print i, j
self.grid[i][j].colour = self.rand_Land_Picker()
You can do something like:
randomRange = range(w*h)
shuffle(randomRange)
for n in randomRange:
i = n/w
j = n%w
Here randomRange basically enumerates all the coordinates from 0 to w*h-1.
Even prettier, i and j, can be found in one statement:
i,j = divmod(n, w)

Categories