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
Related
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.
for i in range(1,n):
for j in range(1, m-1):
a = np.sum(u[i][j])
print("sum = ", a)
When I run this code it just prints out the values of u[i][j] and not the sum of these values.
u[i][j] = 10.0
10.006282725965008
10.018656940304817
10.036934387954467
10.060929709315529
10.09046035701636
10.12534651637516
10.16541102945263
10.21047932258388
10.260379337282082
10.314941464408948
10.373998481509876
10.437385493214036
10.504939874602194
10.576501217447468
10.65191127923653
10.731013934881009
10.813655131031123
10.899682842905593
10.988947033554055
11.081299615470174
11.176594414475591
11.274687135796801
11.375435332258856
11.478698374521604
11.584337423285957
11.692215403399317
11.802196979791036
11.914148535170309
12.02793814942053
12.143435580625656
12.260512247665599
12.379041214319123
12.498897174814157
12.619956440766764
12.742096929451419
12.865198153346483
12.9891412109001
13.113808778462937
13.239085103335473
13.364855997878626
13.491008834637794
13.617432542431397
13.744017603356207
13.87065605066278
13.99724146745538
14.123668986171829
14.249835288799703
14.375638607786316
14.500978727600879
14.625756986908184
14.749876281314098
14.87324106664404
14.995757362716542
15.117332757574852
15.237876412140386
15.357299065252723
15.475513039061617
15.592432244737337
15.707972188466462
15.822049977701013
15.934584327629603
16.04549556784001
16.1547056491434
16.262138150531044
16.367718286235256
16.471372912866805
16.57303053660195
16.67262132039279
16.77007709117535
16.86533134705057
16.958319264413905
17.04897770500997
17.13724522288933
17.223062071245103
17.30637020910775
17.387113307876973
17.465236757670322
17.540687673468693
17.613414901039484
17.68336902261878
17.75050236233456
17.81476899135342
17.87612473273397
17.934527165970557
17.989935631211583
18.042311233137184
18.091616844481656
18.137817109186503
18.180878445170528
18.220769046703957
18.25745888637408
18.290919716630427
18.32112507089799
18.3480502642476
18.371672393612954
18.39197033754437
18.408924755489863
18.422518086594533
18.432734548009854
This code is correctly taking the sum of u[i][j], the trivial sum of one item, one cell in the two-dimensional array of numbers.
This code sums everything in the 2-d array.
a = np.sum(u)
print("sum = ", a)
This code prints the sum of each row, in turn.
for i in range(len(u)):
a = np.sum(u[i])
print("sum = ", a)
Note that your range statements are probably wrong. range(1,n) gives, if for example, n is 4, the values 1,2,3. You want range(n) , which would give 0,1,2,3. More directly,range(len(u)).
Or even better
for row in u:
a = np.sum(row)
print ("sum=", a)
I'm doing algorithm analysis in Python and in short I ran into what I suspect is a problem. I need to analyze the run time of insertion sort on sorted arrays so I have the following code
def insertionSort(arr1):
t1 = time.time();
insertion_sort.sort(arr1)
t2 = time.time();
print (len(arr1));
print (str(t2-t1));
...
print ('Insertion Sort Beginning');
for x in range(0,15):
#Creates arrays of various sizes with integers from 0-100 randomly sprawled about. They are named after the power of 10 the size is
toSort1 = [randint(0,100)] * randint(100000,10000000);
#Presorts the array, insertion sort is faster for small inputs
sorted_list = insertion_sort.sort(toSort1);
##################################
insertionSort(sorted_list);
The problem is the output of this is O(n^2)! I'm new to Python so I figure this is probably a semantics error I didn't catch. insertion_sort should be assumed to be correct, but can be reviewed here. This could only be the case if it was sorted in reverse order when it was timed but it was literally passed to the same sorter twice. How could this be?
This is a graphical representation of the output
I got linear time results with your program.
I added implementation of insertion-sort and little modification of the code as below for this tests.
from random import randint
import time
def insertion_sort(arr):
# Traverse through 1 to len(arr)
for i in range(1, len(arr)):
key = arr[i]
# Move elements of arr[0..i-1], that are
# greater than key, to one position ahead
# of their current position
j = i-1
while j >=0 and key < arr[j] :
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
def insertionSort(arr1):
t1 = time.time();
insertion_sort(arr1)
t2 = time.time();
print str(len(arr1)) + ", " + str(t2-t1)
print ('Insertion Sort Beginning');
for x in range(0,15):
#Creates arrays of various sizes with integers from 0-100 randomly sprawled about. They are named after the power of 10 the size is
toSort1 = [randint(0,100)] * randint(100000,10000000);
#Presorts the array, insertion sort is faster for small inputs
sorted_list = sorted(toSort1);
##################################
insertionSort(sorted_list);
Hope it helps!
So i'm currently working on code, which solves simple differentials. For now my code looks something like that:
deff diff():
coeffs = []
#checking a rank of a function
lvl = int(raw_input("Tell me a rank of your function: "))
if lvl == 0:
print "\nIf the rank is 0, a differential of a function will always be 0"
#Asking user to write coefficients (like 4x^2 - he writes 4)
for i in range(0, lvl):
coeff = int(raw_input("Tell me a coefficient: "))
coeffs.append(coeff)
#Printing all coefficients
print "\nSo your coefficients are: "
for item in coeffs:
print item
And so what I want to do next? I have every coefficient in my coeffs[] list. So now I want to take every single one from there and assign it to a different variable, just to make use of it. And how can I do it? I suppose I will have to use loop, but I tried to do so for hours - nothing helped me. Sooo, how can I do this? It would be like : a=coeff[0], b = coeff[1], ..., x = coeff[lvl] .
Just access the coefficients directly from the list via their indices.
If you are wanting to use the values in a different context that entails making changes to the values but you want to keep the original list unchanged then copy the list to a new list,
import copy
mutableCoeffs = copy.copy(coeffs)
You do not need new variables.
You already have all you need to compute the coefficients for the derivative function.
print "Coefficients for the derivative:"
l = len(coeffs) -1
for item in coeffs[:-1]:
print l * item
l -=1
Or if you want to put them in a new list :
deriv_coeffs = []
l = len(coeffs) -1
for item in coeffs[:-1]:
deriv_coeffs.append(l * item)
l -=1
I guess from there you want to differenciate no? So you just assign the cofficient times it rank to the index-1?
deff diff():
coeffs = []
#checking a rank of a function
lvl = int(raw_input("Tell me a rank of your function: "))
if lvl == 0:
print "\nIf the rank is 0, a differential of a function will always be 0"
#Asking user to write coefficients (like 4x^2 - he writes 4)
for i in range(0, lvl):
coeff = int(raw_input("Tell me a coefficient: "))
coeffs.append(coeff)
#Printing all coefficients
print "\nSo your coefficients are: "
for item in coeffs:
print item
answer_coeff = [0]*(lvl-1)
for i in range(0,lvl-1):
answer_coeff[i] = coeff[i+1]*(i+1)
print "The derivative is:"
string_answer = "%d" % answer_coeff[0]
for i in range(1,lvl-1):
string_answer = string_answer + (" + %d * X^%d" % (answer_coeff[i], i))
print string_answer
If you REALLY want to assign a list to variables you could do so by accessing the globals() dict. For example:
for j in len(coeffs):
globals()["elm{0}".format(j)] = coeffs[j]
Then you'll have your coefficients in the global variables elm0, elm1 and so on.
Please note that this is most probably not what you really want (but only what you asked for).
I have 1,000 objects, each object has 4 attribute lists: a list of words, images, audio files and video files.
I want to compare each object against:
a single object, Ox, from the 1,000.
every other object.
A comparison will be something like:
sum(words in common+ images in common+...).
I want an algorithm that will help me find the closest 5, say, objects to Ox and (a different?) algorithm to find the closest 5 pairs of objects
I've looked into cluster analysis and maximal matching and they don't seem to exactly fit this scenario. I don't want to use these method if something more apt exists, so does this look like a particular type of algorithm to anyone, or can anyone point me in the right direction to applying the algorithms I mentioned to this?
I made an example program for how to solve your first question. But you have to implement ho you want to compare images, audio and videos. And I assume every object has the same length for all lists. To answer your question number two it would be something similar, but with a double loop.
import numpy as np
from random import randint
class Thing:
def __init__(self, words, images, audios, videos):
self.words = words
self.images = images
self.audios = audios
self.videos = videos
def compare(self, other):
score = 0
# Assuming the attribute lists have the same length for both objects
# and that they are sorted in the same manner:
for i in range(len(self.words)):
if self.words[i] == other.words[i]:
score += 1
for i in range(len(self.images)):
if self.images[i] == other.images[i]:
score += 1
# And so one for audio and video. You have to make sure you know
# what method to use for determining when an image/audio/video are
# equal.
return score
N = 1000
things = []
words = np.random.randint(5, size=(N,5))
images = np.random.randint(5, size=(N,5))
audios = np.random.randint(5, size=(N,5))
videos = np.random.randint(5, size=(N,5))
# For testing purposes I assign each attribute to a list (array) containing
# five random integers. I don't know how you actually intend to do it.
for i in xrange(N):
things.append(Thing(words[i], images[i], audios[i], videos[i]))
# I will assume that object number 999 (i=999) is the Ox:
ox = 999
scores = np.zeros(N - 1)
for i in xrange(N - 1):
scores[i] = (things[ox].compare(things[i]))
best = np.argmax(scores)
print "The most similar thing is thing number %d." % best
print
print "Ox attributes:"
print things[ox].words
print things[ox].images
print things[ox].audios
print things[ox].videos
print
print "Best match attributes:"
print things[ox].words
print things[ox].images
print things[ox].audios
print things[ox].videos
EDIT:
Now here is the same program modified sligthly to answer your second question. It turned out to be very simple. I basically just needed to add 4 lines:
Changing scores into a (N,N) array instead of just (N).
Adding for j in xrange(N): and thus creating a double loop.
if i == j:
break
where 3. and 4. is just to make sure that I only compare each pair of things once and not twice and don't compary any things with themselves.
Then there is a few more lines of code that is needed to extract the indices of the 5 largest values in scores. I also reformated the printing so it will be easy to confirm by eye that the printed pairs are actually very similar.
Here comes the new code:
import numpy as np
class Thing:
def __init__(self, words, images, audios, videos):
self.words = words
self.images = images
self.audios = audios
self.videos = videos
def compare(self, other):
score = 0
# Assuming the attribute lists have the same length for both objects
# and that they are sorted in the same manner:
for i in range(len(self.words)):
if self.words[i] == other.words[i]:
score += 1
for i in range(len(self.images)):
if self.images[i] == other.images[i]:
score += 1
for i in range(len(self.audios)):
if self.audios[i] == other.audios[i]:
score += 1
for i in range(len(self.videos)):
if self.videos[i] == other.videos[i]:
score += 1
# You have to make sure you know what method to use for determining
# when an image/audio/video are equal.
return score
N = 1000
things = []
words = np.random.randint(5, size=(N,5))
images = np.random.randint(5, size=(N,5))
audios = np.random.randint(5, size=(N,5))
videos = np.random.randint(5, size=(N,5))
# For testing purposes I assign each attribute to a list (array) containing
# five random integers. I don't know how you actually intend to do it.
for i in xrange(N):
things.append(Thing(words[i], images[i], audios[i], videos[i]))
################################################################################
############################# This is the new part: ############################
################################################################################
scores = np.zeros((N, N))
# Scores will become a triangular matrix where scores[i, j]=value means that
# value is the number of attrributes thing[i] and thing[j] have in common.
for i in xrange(N):
for j in xrange(N):
if i == j:
break
# Break the loop here because:
# * When i==j we would compare thing[i] with itself, and we don't
# want that.
# * For every combination where j>i we would repeat all the
# comparisons for j<i and create duplicates. We don't want that.
scores[i, j] = (things[i].compare(things[j]))
# I want the 5 most similar pairs:
n = 5
# This list will contain a tuple for each of the n most similar pairs:
best_list = []
for k in xrange(n):
ij = np.argmax(scores) # Returns a single integer: ij = i*n + j
i = ij / N
j = ij % N
best_list.append((i, j))
# Erease this score so that on next iteration the second largest score
# is found:
scores[i, j] = 0
for k, (i, j) in enumerate(best_list):
# The number 1 most similar pair is the BEST match of all.
# The number N most similar pair is the WORST match of all.
print "The number %d most similar pair is thing number %d and %d." \
% (k+1, i, j)
print "Thing%4d:" % i, \
things[i].words, things[i].images, things[i].audios, things[i].videos
print "Thing%4d:" % j, \
things[j].words, things[j].images, things[j].audios, things[j].videos
print
If your comparison works with "create a sum of all features and find those which the closest sum", there is a simple trick to get close objects:
Put all objects into an array
Calculate all the sums
Sort the array by sum.
If you take any index, the objects close to it will now have a close index as well. So to find the 5 closest objects, you just need to look at index+5 to index-5 in the sorted array.