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
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
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)