我自己正在学习编码矩阵,不幸的是,我被困在提供的文件Mat.py. Coding the Matrix的作者提供了一个包含矩阵操作类的文件。但是,当我尝试使用该文件时,我总是遇到错误:TypeError:传递给object的非空格式字符串。格式 ...如图所示。 enter image description here
该类的原始代码如下所示:
def getitem(v,d):
"Returns the value of entry d in v"
assert d in v.D
if d in v.f.keys():
return v.f[d]
else:
return 0
def setitem(v,d,val):
"Set the element of v with label d to be val"
assert d in v.D
v.f[d] = val
def equal(u,v):
"Returns true iff u is equal to v"
assert u.D == v.D
for x in u.D:
if getitem(u, x) != getitem(v, x):
return False
return True
def add(u,v):
"Returns the sum of the two vectors"
assert u.D == v.D
return Vec(u.D, { i:v[i]+u[i] for i in u.f.keys() | v.f.keys() })
def dot(u,v):
"Returns the dot product of the two vectors"
assert u.D == v.D
return sum([getitem(v,d)*getitem(u,d) for d in u.D])
def scalar_mul(v, alpha):
"Returns the scalar-vector product alpha times v"
return Vec(v.D, {i:alpha*getitem(v,i) for i in v.D})
def neg(v):
"Returns the negation of a vector"
return Vec(v.D, {i:-1*getitem(v,i) for i in v.D})
##### NO NEED TO MODIFY BELOW HERE #####
class Vec:
"""
A vector has two fields:
D - the domain (a set)
f - a dictionary mapping (some) domain elements to field elements
elements of D not appearing in f are implicitly mapped to zero
"""
def __init__(self, labels, function):
self.D = labels
self.f = function
__getitem__ = getitem
__setitem__ = setitem
__neg__ = neg
__rmul__ = scalar_mul #if left arg of * is primitive, assume it's a scalar
def __mul__(self,other):
#If other is a vector, returns the dot product of self and other
if isinstance(other, Vec):
return dot(self,other)
else:
return NotImplemented # Will cause other.__rmul__(self) to be invoked
def __truediv__(self,other): # Scalar division
return (1/other)*self
__add__ = add
def __radd__(self, other):
"Hack to allow sum(...) to work with vectors"
if other == 0:
return self
def __sub__(a,b):
"Returns a vector which is the difference of a and b."
return a+(-b)
__eq__ = equal
def __str__(v):
"pretty-printing"
try:
D_list = sorted(v.D)
except TypeError:
D_list = sorted(v.D, key=hash)
numdec = 3
wd = dict([(k,(1+max(len(str(k)), len('{0:.{1}G}'.format(v[k], numdec))))) if isinstance(v[k], int) or isinstance(v[k], float) else (k,(1+max(len(str(k)), len(str(v[k]))))) for k in D_list])
# w = 1+max([len(str(k)) for k in D_list]+[len('{0:.{1}G}'.format(value,numdec)) for value in v.f.values()])
s1 = ''.join(['{0:>{1}}'.format(k,wd[k]) for k in D_list])
s2 = ''.join(['{0:>{1}.{2}G}'.format(v[k],wd[k],numdec) if isinstance(v[k], int) or isinstance(v[k], float) else '{0:>{1}}'.format(v[k], wd[k]) for k in D_list])
return "\n" + s1 + "\n" + '-'*sum(wd.values()) +"\n" + s2
def __repr__(self):
return "Vec(" + str(self.D) + "," + str(self.f) + ")"
def copy(self):
"Don't make a new copy of the domain D"
return Vec(self.D, self.f.copy())
# from vec import Vec (commented because I pasted the class Vec above)
#Test your Mat class over R and also over GF(2). The following tests use only R.
def getitem(M, k):
"""
Returns the value of entry k in M, where k is a 2-tuple
>>> M = Mat(({1,3,5}, {'a'}), {(1,'a'):4, (5,'a'): 2})
>>> M[1,'a']
4
>>> M[3,'a']
0
"""
assert k[0] in M.D[0] and k[1] in M.D[1]
pass
def equal(A, B):
"""
Returns true iff A is equal to B.
Consider using brackets notation A[...] and B[...] in your procedure
to access entries of the input matrices. This avoids some sparsity bugs.
>>> Mat(({'a','b'}, {'A','B'}), {('a','B'):0}) == Mat(({'a','b'}, {'A','B'}), {('b','B'):0})
True
>>> A = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1})
>>> B = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1, ('b','B'):0})
>>> C = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1, ('b','B'):5})
>>> A == B
True
>>> B == A
True
>>> A == C
False
>>> C == A
False
>>> A == Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1})
True
"""
assert A.D == B.D
pass
def setitem(M, k, val):
"""
Set entry k of Mat M to val, where k is a 2-tuple.
>>> M = Mat(({'a','b','c'}, {5}), {('a', 5):3, ('b', 5):7})
>>> M['b', 5] = 9
>>> M['c', 5] = 13
>>> M == Mat(({'a','b','c'}, {5}), {('a', 5):3, ('b', 5):9, ('c',5):13})
True
Make sure your operations work with bizarre and unordered keys.
>>> N = Mat(({((),), 7}, {True, False}), {})
>>> N[(7, False)] = 1
>>> N[(((),), True)] = 2
>>> N == Mat(({((),), 7}, {True, False}), {(7,False):1, (((),), True):2})
True
"""
assert k[0] in M.D[0] and k[1] in M.D[1]
pass
def add(A, B):
"""
Return the sum of Mats A and B.
Consider using brackets notation A[...] or B[...] in your procedure
to access entries of the input matrices. This avoids some sparsity bugs.
>>> A1 = Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (6,'y'):3})
>>> A2 = Mat(({3, 6}, {'x','y'}), {(3,'y'):4})
>>> B = Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (3,'y'):4, (6,'y'):3})
>>> A1 + A2 == B
True
>>> A2 + A1 == B
True
>>> A1 == Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (6,'y'):3})
True
>>> zero = Mat(({3,6}, {'x','y'}), {})
>>> B + zero == B
True
>>> C1 = Mat(({1,3}, {2,4}), {(1,2):2, (3,4):3})
>>> C2 = Mat(({1,3}, {2,4}), {(1,4):1, (1,2):4})
>>> D = Mat(({1,3}, {2,4}), {(1,2):6, (1,4):1, (3,4):3})
>>> C1 + C2 == D
True
"""
assert A.D == B.D
pass
def scalar_mul(M, x):
"""
Returns the result of scaling M by x.
>>> M = Mat(({1,3,5}, {2,4}), {(1,2):4, (5,4):2, (3,4):3})
>>> 0*M == Mat(({1, 3, 5}, {2, 4}), {})
True
>>> 1*M == M
True
>>> 0.25*M == Mat(({1,3,5}, {2,4}), {(1,2):1.0, (5,4):0.5, (3,4):0.75})
True
"""
pass
def transpose(M):
"""
Returns the matrix that is the transpose of M.
>>> M = Mat(({0,1}, {0,1}), {(0,1):3, (1,0):2, (1,1):4})
>>> M.transpose() == Mat(({0,1}, {0,1}), {(0,1):2, (1,0):3, (1,1):4})
True
>>> M = Mat(({'x','y','z'}, {2,4}), {('x',4):3, ('x',2):2, ('y',4):4, ('z',4):5})
>>> Mt = Mat(({2,4}, {'x','y','z'}), {(4,'x'):3, (2,'x'):2, (4,'y'):4, (4,'z'):5})
>>> M.transpose() == Mt
True
"""
pass
def vector_matrix_mul(v, M):
"""
returns the product of vector v and matrix M
Consider using brackets notation v[...] in your procedure
to access entries of the input vector. This avoids some sparsity bugs.
>>> v1 = Vec({1, 2, 3}, {1: 1, 2: 8})
>>> M1 = Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7})
>>> v1*M1 == Vec({'a', 'b', 'c'},{'a': -8, 'b': 2, 'c': 0})
True
>>> v1 == Vec({1, 2, 3}, {1: 1, 2: 8})
True
>>> M1 == Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7})
True
>>> v2 = Vec({'a','b'}, {})
>>> M2 = Mat(({'a','b'}, {0, 2, 4, 6, 7}), {})
>>> v2*M2 == Vec({0, 2, 4, 6, 7},{})
True
>>> v3 = Vec({'a','b'},{'a':1,'b':1})
>>> M3 = Mat(({'a', 'b'}, {0, 1}), {('a', 1): 1, ('b', 1): 1, ('a', 0): 1, ('b', 0): 1})
>>> v3*M3 == Vec({0, 1},{0: 2, 1: 2})
True
"""
assert M.D[0] == v.D
pass
def matrix_vector_mul(M, v):
"""
Returns the product of matrix M and vector v.
Consider using brackets notation v[...] in your procedure
to access entries of the input vector. This avoids some sparsity bugs.
>>> N1 = Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1})
>>> u1 = Vec({'a', 'b'}, {'a': 1, 'b': 2})
>>> N1*u1 == Vec({1, 3, 5, 7},{1: 3, 3: 9, 5: -2, 7: 3})
True
>>> N1 == Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1})
True
>>> u1 == Vec({'a', 'b'}, {'a': 1, 'b': 2})
True
>>> N2 = Mat(({('a', 'b'), ('c', 'd')}, {1, 2, 3, 5, 8}), {})
>>> u2 = Vec({1, 2, 3, 5, 8}, {})
>>> N2*u2 == Vec({('a', 'b'), ('c', 'd')},{})
True
>>> M3 = Mat(({0,1},{'a','b'}),{(0,'a'):1, (0,'b'):1, (1,'a'):1, (1,'b'):1})
>>> v3 = Vec({'a','b'},{'a':1,'b':1})
>>> M3*v3 == Vec({0, 1},{0: 2, 1: 2})
True
"""
assert M.D[1] == v.D
pass
def matrix_matrix_mul(A, B):
"""
Returns the result of the matrix-matrix multiplication, A*B.
Consider using brackets notation A[...] and B[...] in your procedure
to access entries of the input matrices. This avoids some sparsity bugs.
>>> A = Mat(({0,1,2}, {0,1,2}), {(1,1):4, (0,0):0, (1,2):1, (1,0):5, (0,1):3, (0,2):2})
>>> B = Mat(({0,1,2}, {0,1,2}), {(1,0):5, (2,1):3, (1,1):2, (2,0):0, (0,0):1, (0,1):4})
>>> A*B == Mat(({0,1,2}, {0,1,2}), {(0,0):15, (0,1):12, (1,0):25, (1,1):31})
True
>>> C = Mat(({0,1,2}, {'a','b'}), {(0,'a'):4, (0,'b'):-3, (1,'a'):1, (2,'a'):1, (2,'b'):-2})
>>> D = Mat(({'a','b'}, {'x','y'}), {('a','x'):3, ('a','y'):-2, ('b','x'):4, ('b','y'):-1})
>>> C*D == Mat(({0,1,2}, {'x','y'}), {(0,'y'):-5, (1,'x'):3, (1,'y'):-2, (2,'x'):-5})
True
>>> M = Mat(({0, 1}, {'a', 'c', 'b'}), {})
>>> N = Mat(({'a', 'c', 'b'}, {(1, 1), (2, 2)}), {})
>>> M*N == Mat(({0,1}, {(1,1), (2,2)}), {})
True
>>> E = Mat(({'a','b'},{'A','B'}), {('a','A'):1,('a','B'):2,('b','A'):3,('b','B'):4})
>>> F = Mat(({'A','B'},{'c','d'}),{('A','d'):5})
>>> E*F == Mat(({'a', 'b'}, {'d', 'c'}), {('b', 'd'): 15, ('a', 'd'): 5})
True
>>> F.transpose()*E.transpose() == Mat(({'d', 'c'}, {'a', 'b'}), {('d', 'b'): 15, ('d', 'a'): 5})
True
"""
assert A.D[1] == B.D[0]
pass
class Mat:
def __init__(self, labels, function):
assert isinstance(labels, tuple)
assert isinstance(labels[0], set) and isinstance(labels[1], set)
assert isinstance(function, dict)
self.D = labels
self.f = function
__getitem__ = getitem
__setitem__ = setitem
transpose = transpose
def __neg__(self):
return (-1)*self
def __mul__(self,other):
if Mat == type(other):
return matrix_matrix_mul(self,other)
elif Vec == type(other):
return matrix_vector_mul(self,other)
else:
return scalar_mul(self,other)
#this will only be used if other is scalar (or not-supported). mat and vec both have __mul__ implemented
def __rmul__(self, other):
if Vec == type(other):
return vector_matrix_mul(other, self)
else: # Assume scalar
return scalar_mul(self, other)
__add__ = add
def __radd__(self, other):
"Hack to allow sum(...) to work with matrices"
if other == 0:
return self
def __sub__(a,b):
return a+(-b)
__eq__ = equal
def copy(self):
return Mat(self.D, self.f.copy())
def __str__(M, rows=None, cols=None):
"string representation for print()"
if rows == None: rows = sorted(M.D[0], key=repr)
if cols == None: cols = sorted(M.D[1], key=repr)
separator = ' | '
numdec = 3
pre = 1+max([len(str(r)) for r in rows])
colw = {col:(1+max([len(str(col))] + [len('{0:.{1}G}'.format(M[row,col],numdec)) if isinstance(M[row,col], int) or isinstance(M[row,col], float) else len(str(M[row,col])) for row in rows])) for col in cols}
s1 = ' '*(1+ pre + len(separator))
s2 = ''.join(['{0:>{1}}'.format(str(c),colw[c]) for c in cols])
s3 = ' '*(pre+len(separator)) + '-'*(sum(list(colw.values())) + 1)
s4 = ''.join(['{0:>{1}} {2}'.format(str(r), pre,separator)+''.join(['{0:>{1}.{2}G}'.format(M[r,c],colw[c],numdec) if isinstance(M[r,c], int) or isinstance(M[r,c], float) else '{0:>{1}}'.format(M[r,c], colw[c]) for c in cols])+'\n' for r in rows])
return '\n' + s1 + s2 + '\n' + s3 + '\n' + s4
def pp(self, rows, cols):
print(self.__str__(rows, cols))
def __repr__(self):
"evaluatable representation"
return "Mat(" + str(self.D) +", " + str(self.f) + ")"
def __iter__(self):
raise TypeError('%r object is not iterable' % self.__class__.__name__)
M = Mat(({'a','b'}, {'x','y','z'}), {('a','x'):1, ('a','y'):2, ('a','z'):3, ('b','x'):10, ('b','y'):20, ('b','z'):30})
print(M)
我按照Book的说明打印了这个矩阵,它应该看起来像LaTeX生成的矩阵:
M = Mat(({'a','b'}, {'x','y','z'}), {('a','x'):1, ('a','y'):2, ('a','z'):3, ('b','x'):10, ('b','y'):20, ('b','z'):30})
print(M)
它返回错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-133-8c4558fab4a8> in <module>()
----> 1 print(M)
/Users/callforsky/Coding_the_Matrix/mat.py in __str__(M, rows, cols)
259 s2 = ''.join(['{0:>{1}}'.format(str(c),colw[c]) for c in cols])
260 s3 = ' '*(pre+len(separator)) + '-'*(sum(list(colw.values())) + 1)
--> 261 s4 = ''.join(['{0:>{1}} {2}'.format(str(r), pre,separator)+''.join(['{0:>{1}.{2}G}'.format(M[r,c],colw[c],numdec) if isinstance(M[r,c], int) or isinstance(M[r,c], float) else '{0:> {1}}'.format(M[r,c], colw[c]) for c in cols])+'\n' for r in rows])
262 return '\n' + s1 + s2 + '\n' + s3 + '\n' + s4
263
/Users/callforsky/Coding_the_Matrix/mat.py in <listcomp>(.0)
259 s2 = ''.join(['{0:>{1}}'.format(str(c),colw[c]) for c in cols])
260 s3 = ' '*(pre+len(separator)) + '-'*(sum(list(colw.values())) + 1)
--> 261 s4 = ''.join(['{0:>{1}} {2}'.format(str(r), pre,separator)+''.join(['{0:>{1}.{2}G}'.format(M[r,c],colw[c],numdec) if isinstance(M[r,c], int) or isinstance(M[r,c], float) else '{0:>{1}}'.format(M[r,c], colw[c]) for c in cols])+'\n' for r in rows])
262 return '\n' + s1 + s2 + '\n' + s3 + '\n' + s4
263
/Users/callforsky/Coding_the_Matrix/mat.py in <listcomp>(.0)
259 s2 = ''.join(['{0:>{1}}'.format(str(c),colw[c]) for c in cols])
260 s3 = ' '*(pre+len(separator)) + '-'*(sum(list(colw.values())) + 1)
--> 261 s4 = ''.join(['{0:>{1}} {2}'.format(str(r), pre,separator)+''.join(['{0:>{1}.{2}G}'.format(M[r,c],colw[c],numdec) if isinstance(M[r,c], int) or isinstance(M[r,c], float) else '{0:>{1}}'.format(M[r,c], colw[c]) for c in cols])+'\n' for r in rows])
262 return '\n' + s1 + s2 + '\n' + s3 + '\n' + s4
263
TypeError: non-empty format string passed to object.__format__
我写了一封电子邮件给作者寻求帮助,但他拒绝承认这是他的代码问题。代码是用Python 3编写的,我使用的是Python 3.我试图在iPython Notebook,IDLE,Terminal甚至Code Runner中使用这个代码(是的,我使用的是Mac)。但它们都不起作用。
如果你可以帮助我,那将是一个大忙!提前感谢您提供的任何adivce。
编辑:我添加了与此类Mat相关的所有代码,应该修复所有未定义的问题。
答案 0 :(得分:0)
修改&#39; def __str __&#39;中的s4行到:
s4 = ''.join(['{0:>{1}} {2}'.format(str(r), pre,separator)+''.join(['{0:>{1}.{2}G}'.format(M[r,c],colw[c],numdec) if isinstance(M[r,c], int) or isinstance(M[r,c], float) else '{0:>{1}}'.format(str(M[r,c]), colw[c]) for c in cols])+'\n' for r in rows])
我根据Python TypeError: non-empty format string passed to object.__format__
中的对话向M [4,c]添加了一个str()这给了我输出: x y z ---------------- a |无无无 b |无无无
然后我在“get getitem&#39;”中添加了一条返回行:
return(M.f[(k[0],k[1])])
这给了我输出: x y z ---------- a | 1 2 3 b | 10 20 30
看来mat.py尚未完成。显然你需要完成这些功能。它返回None并且在__str__函数中出错了。