我目前正在针对代码战争练习python
,这是一个提示:
创建一个Vector
对象,该对象支持加,减,点积和范数。因此,例如:
a = Vector([1, 2, 3])
b = Vector([3, 4, 5])
c = Vector([5, 6, 7, 8])
a.add(b) # should return a new Vector([4, 6, 8])
a.subtract(b) # should return a new Vector([-2, -2, -2])
a.dot(b) # should return 1*3 + 2*4 + 3*5 = 26
a.norm() # should return sqrt(1^2 + 2^2 + 3^2) = sqrt(14)
a.add(c) # raises an exception
我已经编写了通过一些测试通过的加法和减法函数。但是,在运行add函数之后,我覆盖了以前的列表值“ a”时遇到了问题。当我进行减法运算时,vector
中的'a'值是根据加法函数的先前实例计算得出的总和。
我怀疑这是由于我运行了以下代码行:
return self.__class__(self.list)
导致类的实例覆盖自身。
请帮助,我相信我需要返回该类实例的副本,但不知道该怎么做。
class Vector:
def __init__(self, list):
self.list = list #[1,2]
self.copylist = list
def add(self,Vector):
try:
self.list = self.copylist
#take list from other vector
other = Vector.list
#take each value from other Vector and add it to self.list
for index,item in enumerate(Vector.list,0):
self.list[index] = item + self.list[index]
except:
print("Different size vectors")
#return the instance of a class
return self.__class__(self.list)
def subtract(self,Vector):
self.list = self.copylist
other = Vector.list
print(self.list)
print(other)
for index,item in enumerate(Vector.list,0):
self.list[index] = self.list[index] - item
return self.__class__(self.list)
def dot(self,Vector):
self.list = self.copylist
other = Vector.list
#print(self.list)
#print(other)
running_sum =0
for index,item in enumerate(Vector.list,0):
running_sum = running_sum + item * self.list[index]
#print(running_sum, " ", self.list[index], " ", item)
return running_sum
def norm(self):
running_sum = 0
for item in self.list:
running_sum += item**2
return running_sum ** 0.5
def toString(self):
return str(self.list)
`def equals(self,Vector):
return self.list == Vector.list
以下是一些测试:
a = Vector([1, 2])
b = Vector([3, 4])
test.expect(a.add(b).equals(Vector([4, 6])))
a = Vector([1, 2, 3])
b = Vector([3, 4, 5])
test.expect(a.add(b).equals(Vector([4, 6, 8])))
test.expect(a.subtract(b).equals(Vector([-2, -2, -2]))) #code fails here
test.assert_equals(a.dot(b), 26)
test.assert_equals(a.norm(), 14 ** 0.5)
答案 0 :(得分:2)
我认为您正在使这一过程变得比所需的更为复杂。您根本不应该使用类对象。您应该只使用Vector类的实例。我认为您的代码应如下所示:
class Vector:
def __init__(self, initial_elements):
self.elements = list(initial_elements) # make a copy of the incoming list of elements
def add(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
# copy our elements
r = list(self.elements)
# add the elements from the second vector
for index, item in enumerate(other.elements, 0):
r[index] += item
# return a new vector object defined by the computed elements
return Vector(r)
def subtract(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
# copy our elements
r = list(self.elements)
# subtract the elements from the second vector
for index, item in enumerate(other.elements, 0):
r[index] -= item
# return a new vector object defined by the computed elements
return Vector(r)
def dot(self, other):
running_sum = 0
for index, item in enumerate(other.elements, 0):
running_sum += item * self.elements[index]
return running_sum
def norm(self):
running_sum = 0
for item in self.elements:
running_sum += item ** 2
return running_sum ** 0.5
def toString(self):
return str(self.elements)
def equals(self, other):
return self.elements == other.elements
def test():
a = Vector([1, 2])
b = Vector([3, 4])
print(a.add(b).equals(Vector([4, 6])))
a = Vector([1, 2, 3])
b = Vector([3, 4, 5])
print(a.add(b).equals(Vector([4, 6, 8])))
print(a.subtract(b).equals(Vector([-2, -2, -2])))
print(a.dot(b) == 26)
print(a.norm() == 14 ** 0.5)
test()
结果:
True
True
True
True
True
您的代码的一般结构已经出现。
要注意的一件事是您不应该使用list
作为变量名,因为它是Python中的类型名。另外,您也不想传递Vector
作为值。您希望传递Vector
和list
的实例,这些实例的名称应与这些类型名称不冲突。
我的解决方案假定您希望Vector实例是不可变的,因此您的每个操作都将返回一个新的Vector对象。您也可以使它们不是一成不变的,例如,add
方法仅将传入向量添加到目标向量中,而无需创建新对象。我喜欢保持它们不变。最近,我越来越多地进行这种“功能风格”编程,其中对对象方法的调用不会修改目标对象(没有副作用),而只是返回一个新对象。
我喜欢您使用test
类进行测试。我选择不处理此问题,仅打印每个测试比较的结果以查看它们全部出现在True
中。我将它留给您,以将您的测试还原为使用具有expect
和assert_equals
方法的测试对象。</ p>
更新:这是编写add
和subtract
方法的更紧凑的方法:
def add(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
return Vector([self.elements[i] + other.elements[i] for i in range(len(self.elements))])
def subtract(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
return Vector([self.elements[i] - other.elements[i] for i in range(len(self.elements))])
答案 1 :(得分:0)
更改:
return self.__class__(self.list)
收件人:
return self
尽管这与
相同return Vector(self.list)
如果类更复杂,最好返回self
我认为这就是问题所在,希望对您有所帮助:)
此外,优良作法是使用其他名称。您将Vector用作类名以及函数的许多输入,这样做会遇到问题。