Matrix class & Test












-2















as part of my studies I created this Matrix class. To test the results I was provided with a 'test.py' file.



My problem now is that the test file always gives me this error:



> --------------------------------------------------------------------------- AttributeError                            Traceback (most recent call
> last) <ipython-input-7-daeb08264590> in <module>()
> 6 # and then selecting matrix.py
> 7
> ----> 8 import test
>
> /home/workspace/test.py in <module>()
> 76 return True
> 77
> ---> 78 test()
>
> /home/workspace/test.py in test()
> 57 assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
> 58 """
> ---> 59 assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
> 60 assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
> 61 assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
>
> /home/workspace/test.py in equal(m1, m2)
> 68
> 69 def equal(m1, m2):
> ---> 70 if len(m1.g) != len(m2.g): return False
> 71 if len(m1.g[0]) != len(m2.g[0]): return False
> 72 for r1, r2 in zip(m1.g, m2.g):
>
> AttributeError: 'list' object has no attribute 'g'


However when testing the cases myself, it works and show the same result.



matrix.py



import math
from math import sqrt
import numbers

def zeroes(height, width):
"""
Creates a matrix of zeroes.
"""

g = [[0.0 for _ in range(width)] for __ in range(height)]
return Matrix(g)

def identity(n):
"""
Creates a n x n identity matrix.
"""
I = zeroes(n, n)
for i in range(n):
I.g[i][i] = 1.0
return I

class Matrix(object):


# Constructor
def __init__(self, grid):
self.g = grid
self.h = len(grid)
self.w = len(grid[0])

#
# Primary matrix math methods
#############################

def determinant(self):

if not self.is_square():
raise(ValueError, "Cannot calculate determinant of non-square matrix.")
if self.h > 2:
raise(NotImplementedError, "Calculating determinant not implemented for matrices largerer than 2x2.")


if self.h == 1:
return self.g[0][0]

elif self.h == 2:
return (self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])

def trace(self):


if not self.is_square():
raise(ValueError, "Cannot calculate the trace of a non-square matrix.")


sum_trace = 0

for i in range(self.h):
for j in range(self.w):
if i == j:
sum_trace = sum_trace + self.g[i][j]

return sum_trace

def inverse(self):

if not self.is_square():
raise(ValueError, "Non-square Matrix does not have an inverse.")
if self.h > 2:
raise(NotImplementedError, "inversion not implemented for matrices larger than 2x2.")

if self.h == 2:
if self.g[0][0] * self.g[1][1] == self.g[0][1] * self.g[1][0]:
return "ad = bc. Therefore Matrix does not have an inverse"
else:
det_A = 1/(self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])
inverse = [[det_A*self.g[1][1],det_A*-self.g[0][1]],[det_A*-self.g[1][0],det_A*self.g[0][0]]]
elif self.h == 1:
inverse = [[1/self.g[0][0]]]


def T(self):

matrix_transpose =

#Iterate through columns (e.g. j=0)
for j in range(self.w):
#Reset row for each itteration
new_row =
#Iterate through rows (e.g. j = 0, i loops 0;1)
for i in range(self.h):
#i = 0, j = 0; i = 1, j = 0 > new row created out of matrix columns
new_row.append(self.g[i][j])

#new_row appended to matrix_transpose
matrix_transpose.append(new_row)

return matrix_transpose

def is_square(self):
return self.h == self.w

#
# Begin Operator Overloading
############################
def __getitem__(self,idx):

return self.g[idx]

def __repr__(self):

s = ""
for row in self.g:
s += " ".join(["{} ".format(x) for x in row])
s += "n"
return s

def __add__(self,other):

if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be added if the dimensions are the same")

matrix_addition =
for i in range(self.h):
new_row =
for j in range(self.w):
addition = self.g[i][j] + other.g[i][j]
new_row.append(addition)

matrix_addition.append(new_row)

return Matrix(matrix_addition)


def __neg__(self):

for i in range(self.h):
for j in range(self.w):
self.g[i][j] *= -1
return Matrix(self.g)

def __sub__(self, other):

if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be substracted if the dimensions are the same")

matrix_substraction =
for i in range(self.h):
new_row =
for j in range(self.w):
addition = self.g[i][j] - other.g[i][j]
new_row.append(addition)

matrix_substraction.append(new_row)

return Matrix(matrix_substraction)

def __mul__(self, other):

#dot_product func
def dot_product(vector_one, vector_two):
dot_product = 0
for i in range(len(vector_one)):
dot_product += vector_one[i] * vector_two[i]

return dot_product


#get_row func
def get_row(matrix, row):
return matrix[row]

#get_column func
def get_column(matrix, column_number):
column =

for i in range(len(matrix)):
column.append(matrix[i][column_number])

return column

result =
for i in range(self.h):
row_result =
for j in range(self.w):
vector_one = get_row(self.g, i)
vector_two = get_column(other.g, j)
calulated_dot_product = dot_product(vector_one, vector_two)
row_result.append(calulated_dot_product)

result.append(row_result)

return Matrix(result)


def __rmul__(self, other):

if isinstance(other, numbers.Number):
pass

for i in range(self.h):
for j in range(self.w):
self.g[i][j] = 2 * self.g[i][j]
return Matrix(self.g)


test.py



import matrix as m

def test():
I2 = m.Matrix([
[1, 0],
[0, 1]
])
I2_neg = m.Matrix([
[-1, 0],
[0, -1]
])

zero = m.Matrix([
[0,0],
[0,0]
])

m1 = m.Matrix([
[1,2,3],
[4,5,6]
])

m2 = m.Matrix([
[7,-2],
[-3,-5],
[4,1]
])

m1_x_m2 = m.Matrix([
[ 13, -9],
[ 37, -27]])

m2_x_m1 = m.Matrix([
[ -1, 4, 9],
[-23, -31, -39],
[ 8, 13, 18]])

m1_m2_inv = m.Matrix([
[1.5, -0.5],
[2.0555556, -0.722222222]
])

top_ones = m.Matrix([
[1,1],
[0,0],
])

left_ones = m.Matrix([
[1,0],
[1,0]
])

assert equal(-I2, I2_neg), "Error in your __neg__ function"
assert equal(I2 + I2_neg, zero), "Error in your __add__ function"
assert equal(m1 * m2, m1_x_m2), "Error in your __mul__ function"
assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
assert equal(left_ones.T(), top_ones), "Error in your T function (transpose)"
assert equal(top_ones - left_ones.T(), m.zeroes(2,2)), "Error in your __sub__ function"
assert (4*m.identity(5))[0][0] == 4, "Error in your __rmul__ function"
assert (4*m.identity(5)).trace() == 20 , "Error in your trace function"

print("Congratulations! All tests pass. Your Matrix class is working as expected.")

def equal(m1, m2):
if len(m1.g) != len(m2.g): return False
if len(m1.g[0]) != len(m2.g[0]): return False
for r1, r2 in zip(m1.g, m2.g):
for v1, v2 in zip(r1, r2):
if abs(v1 - v2) > 0.0001:
return False
return True

test()


playground.py (To test it & import both files)



# Run this cell but don't modify it.

%load_ext autoreload
%autoreload 2
from matrix import Matrix, zeroes, identity

# Try running this code. You should get an assertion error.
# You will continue to get assertion errors until all the
# methods in matrix.py are correctly implemented.

# You can open matrix.py by selecting File > Open...
# and then selecting matrix.py

import test


I tried to break the problem down, so I could reduce the code I have to share here with you. But no matter what I tried to change, I got errors back from test.py. I hope anyone from you guys could look into it and maybe has an idea where the problem lies.



/Marc










share|improve this question

























  • You should show the full error and traceback. And please post code here, not as links to gists.

    – Daniel Roseman
    Jan 8 '18 at 10:05






  • 1





    Please post the code here, don't insert links. See How to create a Minimal, Complete, and Verifiable example

    – Andrea Corbellini
    Jan 8 '18 at 10:05






  • 1





    "I tried to break the problem down" - Pls continue to do that until you have narrowed it down to a size manageable enough to post all the relevant code here.

    – schwobaseggl
    Jan 8 '18 at 10:05











  • Sorry guys, I thought it get's to long when posting it here. I changed this now.

    – Marc
    Jan 8 '18 at 10:12











  • The exception is caused by your inverse() function which, apparently, is returning a list instead of a Matrix object. Problem is: in the code you posted, inverse() is not returning anything. Please make sure that the code you posted is the same code you're running

    – Andrea Corbellini
    Jan 8 '18 at 10:13


















-2















as part of my studies I created this Matrix class. To test the results I was provided with a 'test.py' file.



My problem now is that the test file always gives me this error:



> --------------------------------------------------------------------------- AttributeError                            Traceback (most recent call
> last) <ipython-input-7-daeb08264590> in <module>()
> 6 # and then selecting matrix.py
> 7
> ----> 8 import test
>
> /home/workspace/test.py in <module>()
> 76 return True
> 77
> ---> 78 test()
>
> /home/workspace/test.py in test()
> 57 assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
> 58 """
> ---> 59 assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
> 60 assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
> 61 assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
>
> /home/workspace/test.py in equal(m1, m2)
> 68
> 69 def equal(m1, m2):
> ---> 70 if len(m1.g) != len(m2.g): return False
> 71 if len(m1.g[0]) != len(m2.g[0]): return False
> 72 for r1, r2 in zip(m1.g, m2.g):
>
> AttributeError: 'list' object has no attribute 'g'


However when testing the cases myself, it works and show the same result.



matrix.py



import math
from math import sqrt
import numbers

def zeroes(height, width):
"""
Creates a matrix of zeroes.
"""

g = [[0.0 for _ in range(width)] for __ in range(height)]
return Matrix(g)

def identity(n):
"""
Creates a n x n identity matrix.
"""
I = zeroes(n, n)
for i in range(n):
I.g[i][i] = 1.0
return I

class Matrix(object):


# Constructor
def __init__(self, grid):
self.g = grid
self.h = len(grid)
self.w = len(grid[0])

#
# Primary matrix math methods
#############################

def determinant(self):

if not self.is_square():
raise(ValueError, "Cannot calculate determinant of non-square matrix.")
if self.h > 2:
raise(NotImplementedError, "Calculating determinant not implemented for matrices largerer than 2x2.")


if self.h == 1:
return self.g[0][0]

elif self.h == 2:
return (self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])

def trace(self):


if not self.is_square():
raise(ValueError, "Cannot calculate the trace of a non-square matrix.")


sum_trace = 0

for i in range(self.h):
for j in range(self.w):
if i == j:
sum_trace = sum_trace + self.g[i][j]

return sum_trace

def inverse(self):

if not self.is_square():
raise(ValueError, "Non-square Matrix does not have an inverse.")
if self.h > 2:
raise(NotImplementedError, "inversion not implemented for matrices larger than 2x2.")

if self.h == 2:
if self.g[0][0] * self.g[1][1] == self.g[0][1] * self.g[1][0]:
return "ad = bc. Therefore Matrix does not have an inverse"
else:
det_A = 1/(self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])
inverse = [[det_A*self.g[1][1],det_A*-self.g[0][1]],[det_A*-self.g[1][0],det_A*self.g[0][0]]]
elif self.h == 1:
inverse = [[1/self.g[0][0]]]


def T(self):

matrix_transpose =

#Iterate through columns (e.g. j=0)
for j in range(self.w):
#Reset row for each itteration
new_row =
#Iterate through rows (e.g. j = 0, i loops 0;1)
for i in range(self.h):
#i = 0, j = 0; i = 1, j = 0 > new row created out of matrix columns
new_row.append(self.g[i][j])

#new_row appended to matrix_transpose
matrix_transpose.append(new_row)

return matrix_transpose

def is_square(self):
return self.h == self.w

#
# Begin Operator Overloading
############################
def __getitem__(self,idx):

return self.g[idx]

def __repr__(self):

s = ""
for row in self.g:
s += " ".join(["{} ".format(x) for x in row])
s += "n"
return s

def __add__(self,other):

if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be added if the dimensions are the same")

matrix_addition =
for i in range(self.h):
new_row =
for j in range(self.w):
addition = self.g[i][j] + other.g[i][j]
new_row.append(addition)

matrix_addition.append(new_row)

return Matrix(matrix_addition)


def __neg__(self):

for i in range(self.h):
for j in range(self.w):
self.g[i][j] *= -1
return Matrix(self.g)

def __sub__(self, other):

if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be substracted if the dimensions are the same")

matrix_substraction =
for i in range(self.h):
new_row =
for j in range(self.w):
addition = self.g[i][j] - other.g[i][j]
new_row.append(addition)

matrix_substraction.append(new_row)

return Matrix(matrix_substraction)

def __mul__(self, other):

#dot_product func
def dot_product(vector_one, vector_two):
dot_product = 0
for i in range(len(vector_one)):
dot_product += vector_one[i] * vector_two[i]

return dot_product


#get_row func
def get_row(matrix, row):
return matrix[row]

#get_column func
def get_column(matrix, column_number):
column =

for i in range(len(matrix)):
column.append(matrix[i][column_number])

return column

result =
for i in range(self.h):
row_result =
for j in range(self.w):
vector_one = get_row(self.g, i)
vector_two = get_column(other.g, j)
calulated_dot_product = dot_product(vector_one, vector_two)
row_result.append(calulated_dot_product)

result.append(row_result)

return Matrix(result)


def __rmul__(self, other):

if isinstance(other, numbers.Number):
pass

for i in range(self.h):
for j in range(self.w):
self.g[i][j] = 2 * self.g[i][j]
return Matrix(self.g)


test.py



import matrix as m

def test():
I2 = m.Matrix([
[1, 0],
[0, 1]
])
I2_neg = m.Matrix([
[-1, 0],
[0, -1]
])

zero = m.Matrix([
[0,0],
[0,0]
])

m1 = m.Matrix([
[1,2,3],
[4,5,6]
])

m2 = m.Matrix([
[7,-2],
[-3,-5],
[4,1]
])

m1_x_m2 = m.Matrix([
[ 13, -9],
[ 37, -27]])

m2_x_m1 = m.Matrix([
[ -1, 4, 9],
[-23, -31, -39],
[ 8, 13, 18]])

m1_m2_inv = m.Matrix([
[1.5, -0.5],
[2.0555556, -0.722222222]
])

top_ones = m.Matrix([
[1,1],
[0,0],
])

left_ones = m.Matrix([
[1,0],
[1,0]
])

assert equal(-I2, I2_neg), "Error in your __neg__ function"
assert equal(I2 + I2_neg, zero), "Error in your __add__ function"
assert equal(m1 * m2, m1_x_m2), "Error in your __mul__ function"
assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
assert equal(left_ones.T(), top_ones), "Error in your T function (transpose)"
assert equal(top_ones - left_ones.T(), m.zeroes(2,2)), "Error in your __sub__ function"
assert (4*m.identity(5))[0][0] == 4, "Error in your __rmul__ function"
assert (4*m.identity(5)).trace() == 20 , "Error in your trace function"

print("Congratulations! All tests pass. Your Matrix class is working as expected.")

def equal(m1, m2):
if len(m1.g) != len(m2.g): return False
if len(m1.g[0]) != len(m2.g[0]): return False
for r1, r2 in zip(m1.g, m2.g):
for v1, v2 in zip(r1, r2):
if abs(v1 - v2) > 0.0001:
return False
return True

test()


playground.py (To test it & import both files)



# Run this cell but don't modify it.

%load_ext autoreload
%autoreload 2
from matrix import Matrix, zeroes, identity

# Try running this code. You should get an assertion error.
# You will continue to get assertion errors until all the
# methods in matrix.py are correctly implemented.

# You can open matrix.py by selecting File > Open...
# and then selecting matrix.py

import test


I tried to break the problem down, so I could reduce the code I have to share here with you. But no matter what I tried to change, I got errors back from test.py. I hope anyone from you guys could look into it and maybe has an idea where the problem lies.



/Marc










share|improve this question

























  • You should show the full error and traceback. And please post code here, not as links to gists.

    – Daniel Roseman
    Jan 8 '18 at 10:05






  • 1





    Please post the code here, don't insert links. See How to create a Minimal, Complete, and Verifiable example

    – Andrea Corbellini
    Jan 8 '18 at 10:05






  • 1





    "I tried to break the problem down" - Pls continue to do that until you have narrowed it down to a size manageable enough to post all the relevant code here.

    – schwobaseggl
    Jan 8 '18 at 10:05











  • Sorry guys, I thought it get's to long when posting it here. I changed this now.

    – Marc
    Jan 8 '18 at 10:12











  • The exception is caused by your inverse() function which, apparently, is returning a list instead of a Matrix object. Problem is: in the code you posted, inverse() is not returning anything. Please make sure that the code you posted is the same code you're running

    – Andrea Corbellini
    Jan 8 '18 at 10:13
















-2












-2








-2


1






as part of my studies I created this Matrix class. To test the results I was provided with a 'test.py' file.



My problem now is that the test file always gives me this error:



> --------------------------------------------------------------------------- AttributeError                            Traceback (most recent call
> last) <ipython-input-7-daeb08264590> in <module>()
> 6 # and then selecting matrix.py
> 7
> ----> 8 import test
>
> /home/workspace/test.py in <module>()
> 76 return True
> 77
> ---> 78 test()
>
> /home/workspace/test.py in test()
> 57 assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
> 58 """
> ---> 59 assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
> 60 assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
> 61 assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
>
> /home/workspace/test.py in equal(m1, m2)
> 68
> 69 def equal(m1, m2):
> ---> 70 if len(m1.g) != len(m2.g): return False
> 71 if len(m1.g[0]) != len(m2.g[0]): return False
> 72 for r1, r2 in zip(m1.g, m2.g):
>
> AttributeError: 'list' object has no attribute 'g'


However when testing the cases myself, it works and show the same result.



matrix.py



import math
from math import sqrt
import numbers

def zeroes(height, width):
"""
Creates a matrix of zeroes.
"""

g = [[0.0 for _ in range(width)] for __ in range(height)]
return Matrix(g)

def identity(n):
"""
Creates a n x n identity matrix.
"""
I = zeroes(n, n)
for i in range(n):
I.g[i][i] = 1.0
return I

class Matrix(object):


# Constructor
def __init__(self, grid):
self.g = grid
self.h = len(grid)
self.w = len(grid[0])

#
# Primary matrix math methods
#############################

def determinant(self):

if not self.is_square():
raise(ValueError, "Cannot calculate determinant of non-square matrix.")
if self.h > 2:
raise(NotImplementedError, "Calculating determinant not implemented for matrices largerer than 2x2.")


if self.h == 1:
return self.g[0][0]

elif self.h == 2:
return (self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])

def trace(self):


if not self.is_square():
raise(ValueError, "Cannot calculate the trace of a non-square matrix.")


sum_trace = 0

for i in range(self.h):
for j in range(self.w):
if i == j:
sum_trace = sum_trace + self.g[i][j]

return sum_trace

def inverse(self):

if not self.is_square():
raise(ValueError, "Non-square Matrix does not have an inverse.")
if self.h > 2:
raise(NotImplementedError, "inversion not implemented for matrices larger than 2x2.")

if self.h == 2:
if self.g[0][0] * self.g[1][1] == self.g[0][1] * self.g[1][0]:
return "ad = bc. Therefore Matrix does not have an inverse"
else:
det_A = 1/(self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])
inverse = [[det_A*self.g[1][1],det_A*-self.g[0][1]],[det_A*-self.g[1][0],det_A*self.g[0][0]]]
elif self.h == 1:
inverse = [[1/self.g[0][0]]]


def T(self):

matrix_transpose =

#Iterate through columns (e.g. j=0)
for j in range(self.w):
#Reset row for each itteration
new_row =
#Iterate through rows (e.g. j = 0, i loops 0;1)
for i in range(self.h):
#i = 0, j = 0; i = 1, j = 0 > new row created out of matrix columns
new_row.append(self.g[i][j])

#new_row appended to matrix_transpose
matrix_transpose.append(new_row)

return matrix_transpose

def is_square(self):
return self.h == self.w

#
# Begin Operator Overloading
############################
def __getitem__(self,idx):

return self.g[idx]

def __repr__(self):

s = ""
for row in self.g:
s += " ".join(["{} ".format(x) for x in row])
s += "n"
return s

def __add__(self,other):

if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be added if the dimensions are the same")

matrix_addition =
for i in range(self.h):
new_row =
for j in range(self.w):
addition = self.g[i][j] + other.g[i][j]
new_row.append(addition)

matrix_addition.append(new_row)

return Matrix(matrix_addition)


def __neg__(self):

for i in range(self.h):
for j in range(self.w):
self.g[i][j] *= -1
return Matrix(self.g)

def __sub__(self, other):

if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be substracted if the dimensions are the same")

matrix_substraction =
for i in range(self.h):
new_row =
for j in range(self.w):
addition = self.g[i][j] - other.g[i][j]
new_row.append(addition)

matrix_substraction.append(new_row)

return Matrix(matrix_substraction)

def __mul__(self, other):

#dot_product func
def dot_product(vector_one, vector_two):
dot_product = 0
for i in range(len(vector_one)):
dot_product += vector_one[i] * vector_two[i]

return dot_product


#get_row func
def get_row(matrix, row):
return matrix[row]

#get_column func
def get_column(matrix, column_number):
column =

for i in range(len(matrix)):
column.append(matrix[i][column_number])

return column

result =
for i in range(self.h):
row_result =
for j in range(self.w):
vector_one = get_row(self.g, i)
vector_two = get_column(other.g, j)
calulated_dot_product = dot_product(vector_one, vector_two)
row_result.append(calulated_dot_product)

result.append(row_result)

return Matrix(result)


def __rmul__(self, other):

if isinstance(other, numbers.Number):
pass

for i in range(self.h):
for j in range(self.w):
self.g[i][j] = 2 * self.g[i][j]
return Matrix(self.g)


test.py



import matrix as m

def test():
I2 = m.Matrix([
[1, 0],
[0, 1]
])
I2_neg = m.Matrix([
[-1, 0],
[0, -1]
])

zero = m.Matrix([
[0,0],
[0,0]
])

m1 = m.Matrix([
[1,2,3],
[4,5,6]
])

m2 = m.Matrix([
[7,-2],
[-3,-5],
[4,1]
])

m1_x_m2 = m.Matrix([
[ 13, -9],
[ 37, -27]])

m2_x_m1 = m.Matrix([
[ -1, 4, 9],
[-23, -31, -39],
[ 8, 13, 18]])

m1_m2_inv = m.Matrix([
[1.5, -0.5],
[2.0555556, -0.722222222]
])

top_ones = m.Matrix([
[1,1],
[0,0],
])

left_ones = m.Matrix([
[1,0],
[1,0]
])

assert equal(-I2, I2_neg), "Error in your __neg__ function"
assert equal(I2 + I2_neg, zero), "Error in your __add__ function"
assert equal(m1 * m2, m1_x_m2), "Error in your __mul__ function"
assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
assert equal(left_ones.T(), top_ones), "Error in your T function (transpose)"
assert equal(top_ones - left_ones.T(), m.zeroes(2,2)), "Error in your __sub__ function"
assert (4*m.identity(5))[0][0] == 4, "Error in your __rmul__ function"
assert (4*m.identity(5)).trace() == 20 , "Error in your trace function"

print("Congratulations! All tests pass. Your Matrix class is working as expected.")

def equal(m1, m2):
if len(m1.g) != len(m2.g): return False
if len(m1.g[0]) != len(m2.g[0]): return False
for r1, r2 in zip(m1.g, m2.g):
for v1, v2 in zip(r1, r2):
if abs(v1 - v2) > 0.0001:
return False
return True

test()


playground.py (To test it & import both files)



# Run this cell but don't modify it.

%load_ext autoreload
%autoreload 2
from matrix import Matrix, zeroes, identity

# Try running this code. You should get an assertion error.
# You will continue to get assertion errors until all the
# methods in matrix.py are correctly implemented.

# You can open matrix.py by selecting File > Open...
# and then selecting matrix.py

import test


I tried to break the problem down, so I could reduce the code I have to share here with you. But no matter what I tried to change, I got errors back from test.py. I hope anyone from you guys could look into it and maybe has an idea where the problem lies.



/Marc










share|improve this question
















as part of my studies I created this Matrix class. To test the results I was provided with a 'test.py' file.



My problem now is that the test file always gives me this error:



> --------------------------------------------------------------------------- AttributeError                            Traceback (most recent call
> last) <ipython-input-7-daeb08264590> in <module>()
> 6 # and then selecting matrix.py
> 7
> ----> 8 import test
>
> /home/workspace/test.py in <module>()
> 76 return True
> 77
> ---> 78 test()
>
> /home/workspace/test.py in test()
> 57 assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
> 58 """
> ---> 59 assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
> 60 assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
> 61 assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
>
> /home/workspace/test.py in equal(m1, m2)
> 68
> 69 def equal(m1, m2):
> ---> 70 if len(m1.g) != len(m2.g): return False
> 71 if len(m1.g[0]) != len(m2.g[0]): return False
> 72 for r1, r2 in zip(m1.g, m2.g):
>
> AttributeError: 'list' object has no attribute 'g'


However when testing the cases myself, it works and show the same result.



matrix.py



import math
from math import sqrt
import numbers

def zeroes(height, width):
"""
Creates a matrix of zeroes.
"""

g = [[0.0 for _ in range(width)] for __ in range(height)]
return Matrix(g)

def identity(n):
"""
Creates a n x n identity matrix.
"""
I = zeroes(n, n)
for i in range(n):
I.g[i][i] = 1.0
return I

class Matrix(object):


# Constructor
def __init__(self, grid):
self.g = grid
self.h = len(grid)
self.w = len(grid[0])

#
# Primary matrix math methods
#############################

def determinant(self):

if not self.is_square():
raise(ValueError, "Cannot calculate determinant of non-square matrix.")
if self.h > 2:
raise(NotImplementedError, "Calculating determinant not implemented for matrices largerer than 2x2.")


if self.h == 1:
return self.g[0][0]

elif self.h == 2:
return (self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])

def trace(self):


if not self.is_square():
raise(ValueError, "Cannot calculate the trace of a non-square matrix.")


sum_trace = 0

for i in range(self.h):
for j in range(self.w):
if i == j:
sum_trace = sum_trace + self.g[i][j]

return sum_trace

def inverse(self):

if not self.is_square():
raise(ValueError, "Non-square Matrix does not have an inverse.")
if self.h > 2:
raise(NotImplementedError, "inversion not implemented for matrices larger than 2x2.")

if self.h == 2:
if self.g[0][0] * self.g[1][1] == self.g[0][1] * self.g[1][0]:
return "ad = bc. Therefore Matrix does not have an inverse"
else:
det_A = 1/(self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])
inverse = [[det_A*self.g[1][1],det_A*-self.g[0][1]],[det_A*-self.g[1][0],det_A*self.g[0][0]]]
elif self.h == 1:
inverse = [[1/self.g[0][0]]]


def T(self):

matrix_transpose =

#Iterate through columns (e.g. j=0)
for j in range(self.w):
#Reset row for each itteration
new_row =
#Iterate through rows (e.g. j = 0, i loops 0;1)
for i in range(self.h):
#i = 0, j = 0; i = 1, j = 0 > new row created out of matrix columns
new_row.append(self.g[i][j])

#new_row appended to matrix_transpose
matrix_transpose.append(new_row)

return matrix_transpose

def is_square(self):
return self.h == self.w

#
# Begin Operator Overloading
############################
def __getitem__(self,idx):

return self.g[idx]

def __repr__(self):

s = ""
for row in self.g:
s += " ".join(["{} ".format(x) for x in row])
s += "n"
return s

def __add__(self,other):

if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be added if the dimensions are the same")

matrix_addition =
for i in range(self.h):
new_row =
for j in range(self.w):
addition = self.g[i][j] + other.g[i][j]
new_row.append(addition)

matrix_addition.append(new_row)

return Matrix(matrix_addition)


def __neg__(self):

for i in range(self.h):
for j in range(self.w):
self.g[i][j] *= -1
return Matrix(self.g)

def __sub__(self, other):

if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be substracted if the dimensions are the same")

matrix_substraction =
for i in range(self.h):
new_row =
for j in range(self.w):
addition = self.g[i][j] - other.g[i][j]
new_row.append(addition)

matrix_substraction.append(new_row)

return Matrix(matrix_substraction)

def __mul__(self, other):

#dot_product func
def dot_product(vector_one, vector_two):
dot_product = 0
for i in range(len(vector_one)):
dot_product += vector_one[i] * vector_two[i]

return dot_product


#get_row func
def get_row(matrix, row):
return matrix[row]

#get_column func
def get_column(matrix, column_number):
column =

for i in range(len(matrix)):
column.append(matrix[i][column_number])

return column

result =
for i in range(self.h):
row_result =
for j in range(self.w):
vector_one = get_row(self.g, i)
vector_two = get_column(other.g, j)
calulated_dot_product = dot_product(vector_one, vector_two)
row_result.append(calulated_dot_product)

result.append(row_result)

return Matrix(result)


def __rmul__(self, other):

if isinstance(other, numbers.Number):
pass

for i in range(self.h):
for j in range(self.w):
self.g[i][j] = 2 * self.g[i][j]
return Matrix(self.g)


test.py



import matrix as m

def test():
I2 = m.Matrix([
[1, 0],
[0, 1]
])
I2_neg = m.Matrix([
[-1, 0],
[0, -1]
])

zero = m.Matrix([
[0,0],
[0,0]
])

m1 = m.Matrix([
[1,2,3],
[4,5,6]
])

m2 = m.Matrix([
[7,-2],
[-3,-5],
[4,1]
])

m1_x_m2 = m.Matrix([
[ 13, -9],
[ 37, -27]])

m2_x_m1 = m.Matrix([
[ -1, 4, 9],
[-23, -31, -39],
[ 8, 13, 18]])

m1_m2_inv = m.Matrix([
[1.5, -0.5],
[2.0555556, -0.722222222]
])

top_ones = m.Matrix([
[1,1],
[0,0],
])

left_ones = m.Matrix([
[1,0],
[1,0]
])

assert equal(-I2, I2_neg), "Error in your __neg__ function"
assert equal(I2 + I2_neg, zero), "Error in your __add__ function"
assert equal(m1 * m2, m1_x_m2), "Error in your __mul__ function"
assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
assert equal(left_ones.T(), top_ones), "Error in your T function (transpose)"
assert equal(top_ones - left_ones.T(), m.zeroes(2,2)), "Error in your __sub__ function"
assert (4*m.identity(5))[0][0] == 4, "Error in your __rmul__ function"
assert (4*m.identity(5)).trace() == 20 , "Error in your trace function"

print("Congratulations! All tests pass. Your Matrix class is working as expected.")

def equal(m1, m2):
if len(m1.g) != len(m2.g): return False
if len(m1.g[0]) != len(m2.g[0]): return False
for r1, r2 in zip(m1.g, m2.g):
for v1, v2 in zip(r1, r2):
if abs(v1 - v2) > 0.0001:
return False
return True

test()


playground.py (To test it & import both files)



# Run this cell but don't modify it.

%load_ext autoreload
%autoreload 2
from matrix import Matrix, zeroes, identity

# Try running this code. You should get an assertion error.
# You will continue to get assertion errors until all the
# methods in matrix.py are correctly implemented.

# You can open matrix.py by selecting File > Open...
# and then selecting matrix.py

import test


I tried to break the problem down, so I could reduce the code I have to share here with you. But no matter what I tried to change, I got errors back from test.py. I hope anyone from you guys could look into it and maybe has an idea where the problem lies.



/Marc







python class






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 8 '18 at 10:11







Marc

















asked Jan 8 '18 at 10:02









MarcMarc

147




147













  • You should show the full error and traceback. And please post code here, not as links to gists.

    – Daniel Roseman
    Jan 8 '18 at 10:05






  • 1





    Please post the code here, don't insert links. See How to create a Minimal, Complete, and Verifiable example

    – Andrea Corbellini
    Jan 8 '18 at 10:05






  • 1





    "I tried to break the problem down" - Pls continue to do that until you have narrowed it down to a size manageable enough to post all the relevant code here.

    – schwobaseggl
    Jan 8 '18 at 10:05











  • Sorry guys, I thought it get's to long when posting it here. I changed this now.

    – Marc
    Jan 8 '18 at 10:12











  • The exception is caused by your inverse() function which, apparently, is returning a list instead of a Matrix object. Problem is: in the code you posted, inverse() is not returning anything. Please make sure that the code you posted is the same code you're running

    – Andrea Corbellini
    Jan 8 '18 at 10:13





















  • You should show the full error and traceback. And please post code here, not as links to gists.

    – Daniel Roseman
    Jan 8 '18 at 10:05






  • 1





    Please post the code here, don't insert links. See How to create a Minimal, Complete, and Verifiable example

    – Andrea Corbellini
    Jan 8 '18 at 10:05






  • 1





    "I tried to break the problem down" - Pls continue to do that until you have narrowed it down to a size manageable enough to post all the relevant code here.

    – schwobaseggl
    Jan 8 '18 at 10:05











  • Sorry guys, I thought it get's to long when posting it here. I changed this now.

    – Marc
    Jan 8 '18 at 10:12











  • The exception is caused by your inverse() function which, apparently, is returning a list instead of a Matrix object. Problem is: in the code you posted, inverse() is not returning anything. Please make sure that the code you posted is the same code you're running

    – Andrea Corbellini
    Jan 8 '18 at 10:13



















You should show the full error and traceback. And please post code here, not as links to gists.

– Daniel Roseman
Jan 8 '18 at 10:05





You should show the full error and traceback. And please post code here, not as links to gists.

– Daniel Roseman
Jan 8 '18 at 10:05




1




1





Please post the code here, don't insert links. See How to create a Minimal, Complete, and Verifiable example

– Andrea Corbellini
Jan 8 '18 at 10:05





Please post the code here, don't insert links. See How to create a Minimal, Complete, and Verifiable example

– Andrea Corbellini
Jan 8 '18 at 10:05




1




1





"I tried to break the problem down" - Pls continue to do that until you have narrowed it down to a size manageable enough to post all the relevant code here.

– schwobaseggl
Jan 8 '18 at 10:05





"I tried to break the problem down" - Pls continue to do that until you have narrowed it down to a size manageable enough to post all the relevant code here.

– schwobaseggl
Jan 8 '18 at 10:05













Sorry guys, I thought it get's to long when posting it here. I changed this now.

– Marc
Jan 8 '18 at 10:12





Sorry guys, I thought it get's to long when posting it here. I changed this now.

– Marc
Jan 8 '18 at 10:12













The exception is caused by your inverse() function which, apparently, is returning a list instead of a Matrix object. Problem is: in the code you posted, inverse() is not returning anything. Please make sure that the code you posted is the same code you're running

– Andrea Corbellini
Jan 8 '18 at 10:13







The exception is caused by your inverse() function which, apparently, is returning a list instead of a Matrix object. Problem is: in the code you posted, inverse() is not returning anything. Please make sure that the code you posted is the same code you're running

– Andrea Corbellini
Jan 8 '18 at 10:13














1 Answer
1






active

oldest

votes


















2














A quick check in that codebase reveals that the methods inverse and T of the Matrix class do not return Matrix instances, but bare grids (2d-lists); these grids, of course, have no g attribute when the equal function in the test tries to compare them with Matrix instances. Wrap the return values of these two methods into matrixes:



class Matrix(object):
def inverse(self):
# ....
# not: return inverse
return Matrix(inverse)

def T(self):
# ...
# not: return matrix_transpose
return Matrix(matrix_transpose)





share|improve this answer


























  • Hi @schwobaseggl, I think this was part of the problem! I changed that now. However I am receiving now this error message here: AssertionError: Error in your __rmul__ function

    – Marc
    Jan 8 '18 at 10:21













  • @Marc: in your __rmul__ you're doing self.g[i][j] = 2 * self.g[i][j]. You want to replace the 2 with other

    – Andrea Corbellini
    Jan 8 '18 at 10:53











  • @Marc That's another question, then ;) you should not change the question with every further step. Also, you have removed the links, but the code you posted seems incomplete

    – schwobaseggl
    Jan 8 '18 at 10:53











  • Ahh I used the 2 for testing and then forgot to change it. Thanks a lot!

    – Marc
    Jan 8 '18 at 10:58











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48147950%2fmatrix-class-test%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














A quick check in that codebase reveals that the methods inverse and T of the Matrix class do not return Matrix instances, but bare grids (2d-lists); these grids, of course, have no g attribute when the equal function in the test tries to compare them with Matrix instances. Wrap the return values of these two methods into matrixes:



class Matrix(object):
def inverse(self):
# ....
# not: return inverse
return Matrix(inverse)

def T(self):
# ...
# not: return matrix_transpose
return Matrix(matrix_transpose)





share|improve this answer


























  • Hi @schwobaseggl, I think this was part of the problem! I changed that now. However I am receiving now this error message here: AssertionError: Error in your __rmul__ function

    – Marc
    Jan 8 '18 at 10:21













  • @Marc: in your __rmul__ you're doing self.g[i][j] = 2 * self.g[i][j]. You want to replace the 2 with other

    – Andrea Corbellini
    Jan 8 '18 at 10:53











  • @Marc That's another question, then ;) you should not change the question with every further step. Also, you have removed the links, but the code you posted seems incomplete

    – schwobaseggl
    Jan 8 '18 at 10:53











  • Ahh I used the 2 for testing and then forgot to change it. Thanks a lot!

    – Marc
    Jan 8 '18 at 10:58
















2














A quick check in that codebase reveals that the methods inverse and T of the Matrix class do not return Matrix instances, but bare grids (2d-lists); these grids, of course, have no g attribute when the equal function in the test tries to compare them with Matrix instances. Wrap the return values of these two methods into matrixes:



class Matrix(object):
def inverse(self):
# ....
# not: return inverse
return Matrix(inverse)

def T(self):
# ...
# not: return matrix_transpose
return Matrix(matrix_transpose)





share|improve this answer


























  • Hi @schwobaseggl, I think this was part of the problem! I changed that now. However I am receiving now this error message here: AssertionError: Error in your __rmul__ function

    – Marc
    Jan 8 '18 at 10:21













  • @Marc: in your __rmul__ you're doing self.g[i][j] = 2 * self.g[i][j]. You want to replace the 2 with other

    – Andrea Corbellini
    Jan 8 '18 at 10:53











  • @Marc That's another question, then ;) you should not change the question with every further step. Also, you have removed the links, but the code you posted seems incomplete

    – schwobaseggl
    Jan 8 '18 at 10:53











  • Ahh I used the 2 for testing and then forgot to change it. Thanks a lot!

    – Marc
    Jan 8 '18 at 10:58














2












2








2







A quick check in that codebase reveals that the methods inverse and T of the Matrix class do not return Matrix instances, but bare grids (2d-lists); these grids, of course, have no g attribute when the equal function in the test tries to compare them with Matrix instances. Wrap the return values of these two methods into matrixes:



class Matrix(object):
def inverse(self):
# ....
# not: return inverse
return Matrix(inverse)

def T(self):
# ...
# not: return matrix_transpose
return Matrix(matrix_transpose)





share|improve this answer















A quick check in that codebase reveals that the methods inverse and T of the Matrix class do not return Matrix instances, but bare grids (2d-lists); these grids, of course, have no g attribute when the equal function in the test tries to compare them with Matrix instances. Wrap the return values of these two methods into matrixes:



class Matrix(object):
def inverse(self):
# ....
# not: return inverse
return Matrix(inverse)

def T(self):
# ...
# not: return matrix_transpose
return Matrix(matrix_transpose)






share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 8 '18 at 10:20

























answered Jan 8 '18 at 10:14









schwobasegglschwobaseggl

37.4k32442




37.4k32442













  • Hi @schwobaseggl, I think this was part of the problem! I changed that now. However I am receiving now this error message here: AssertionError: Error in your __rmul__ function

    – Marc
    Jan 8 '18 at 10:21













  • @Marc: in your __rmul__ you're doing self.g[i][j] = 2 * self.g[i][j]. You want to replace the 2 with other

    – Andrea Corbellini
    Jan 8 '18 at 10:53











  • @Marc That's another question, then ;) you should not change the question with every further step. Also, you have removed the links, but the code you posted seems incomplete

    – schwobaseggl
    Jan 8 '18 at 10:53











  • Ahh I used the 2 for testing and then forgot to change it. Thanks a lot!

    – Marc
    Jan 8 '18 at 10:58



















  • Hi @schwobaseggl, I think this was part of the problem! I changed that now. However I am receiving now this error message here: AssertionError: Error in your __rmul__ function

    – Marc
    Jan 8 '18 at 10:21













  • @Marc: in your __rmul__ you're doing self.g[i][j] = 2 * self.g[i][j]. You want to replace the 2 with other

    – Andrea Corbellini
    Jan 8 '18 at 10:53











  • @Marc That's another question, then ;) you should not change the question with every further step. Also, you have removed the links, but the code you posted seems incomplete

    – schwobaseggl
    Jan 8 '18 at 10:53











  • Ahh I used the 2 for testing and then forgot to change it. Thanks a lot!

    – Marc
    Jan 8 '18 at 10:58

















Hi @schwobaseggl, I think this was part of the problem! I changed that now. However I am receiving now this error message here: AssertionError: Error in your __rmul__ function

– Marc
Jan 8 '18 at 10:21







Hi @schwobaseggl, I think this was part of the problem! I changed that now. However I am receiving now this error message here: AssertionError: Error in your __rmul__ function

– Marc
Jan 8 '18 at 10:21















@Marc: in your __rmul__ you're doing self.g[i][j] = 2 * self.g[i][j]. You want to replace the 2 with other

– Andrea Corbellini
Jan 8 '18 at 10:53





@Marc: in your __rmul__ you're doing self.g[i][j] = 2 * self.g[i][j]. You want to replace the 2 with other

– Andrea Corbellini
Jan 8 '18 at 10:53













@Marc That's another question, then ;) you should not change the question with every further step. Also, you have removed the links, but the code you posted seems incomplete

– schwobaseggl
Jan 8 '18 at 10:53





@Marc That's another question, then ;) you should not change the question with every further step. Also, you have removed the links, but the code you posted seems incomplete

– schwobaseggl
Jan 8 '18 at 10:53













Ahh I used the 2 for testing and then forgot to change it. Thanks a lot!

– Marc
Jan 8 '18 at 10:58





Ahh I used the 2 for testing and then forgot to change it. Thanks a lot!

– Marc
Jan 8 '18 at 10:58




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48147950%2fmatrix-class-test%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)