实现一个 class 来表示一个线串并实现一个方法 length() ,该方法 returns (任意数字)或线段的长度之和
Implement a class for representing a linestring and implement a method length() that returns the sum of the length of (any number) or segments
我实现了 class 来定义 LineString(object)。 LineString 接受代表不同线段的任意数量的点。我需要计算每条线段的长度并将它们全部加在一起以获得线串的总长度。我看不到我的代码哪里出错了,因为我无法传递断言来测试我的长度函数是否有效。
我尝试创建一个变量而不是一个列表来计算每条线段的长度,但它仍然不起作用。
from math import sqrt
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, i, j):
self.x = self.x + i
self.y = self.y + j
class LineString(object):
def __init__(self, *coordinates):
self.coords = [Point(*p) for p in coordinates]
self.lengths = []
def __getitem__(self, key):
if type(key) == tuple:
return self.coords[key[0]][key[1]]
else:
return self.coords[key]
def move(self, delta_x, delta_y):
for self in self.coords:
self.move(delta_x, delta_y)
def length(self):
# base formula: length = sqrt((x2 - x1)**2 + (y2 - y1)**2)
points_temp = self.coords
for i in range(len(points_temp) - 1):
length = sqrt(((self.coords[i + 1].x - self.coords[i].x) ** 2) + (
(self.coords[i + 1].y - self.coords[i].y) ** 2))
self.lengths.append(length)
return sum(self.lengths)
if __name__ == '__main__':
# Tests for LineString
# ===================================
lin1 = LineString((1, 1), (0, 2)) # lin1 is an instance of LineString
assert lin1.length() == sqrt(2.0)
lin1.move(-1, -1) # Move by -1 and -1 for x and y respectively
print(lin1)
assert lin1[0].y == 0 # Inspect the y value of the start point.
# Implement this by overloading __getitem__(self, key) in your class.
lin2 = LineString((1, 1), (1, 2), (2, 2))
assert lin2.length() == 2.0
lin2.move(-1, -1) # Move by -1 and -1 for x and y respectively
assert lin2.length() == 2.0
assert lin2[-1].x == 1 # Inspect the x value of the end point.
print('Success! Line tests passed!')
倒数第二个断言总是出错。
首先推荐使用Python的单元测试框架,
https://docs.python.org/3/library/unittest.html
这样,您将使用 self.assertEqual(lin2.length(), 2.0)
,而不仅仅是说 "getting an error with the second to last assert",它不仅会打印出错误,还会打印出 lin2.length()
的实际值。
其次,您永远不应该比较双精度值是否相等 - 它们不精确,微小的错误可能会导致计算稍有偏差,从而导致相等性失败。改为使用 assertAlmostEqual - https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertAlmostEqual
但这不是这里的问题。查找错误的最简单方法是交互式地使用 Python。只需 运行 互动 shell:
lin2 = LineString((1, 1), (1, 2), (2, 2))
lin2.length()
2.0
lin2.length()
4.0
这是问题所在 - length() 函数不清除 self.lengths
字段,并且它随着每次计算而不断增长!
我实现了 class 来定义 LineString(object)。 LineString 接受代表不同线段的任意数量的点。我需要计算每条线段的长度并将它们全部加在一起以获得线串的总长度。我看不到我的代码哪里出错了,因为我无法传递断言来测试我的长度函数是否有效。
我尝试创建一个变量而不是一个列表来计算每条线段的长度,但它仍然不起作用。
from math import sqrt
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, i, j):
self.x = self.x + i
self.y = self.y + j
class LineString(object):
def __init__(self, *coordinates):
self.coords = [Point(*p) for p in coordinates]
self.lengths = []
def __getitem__(self, key):
if type(key) == tuple:
return self.coords[key[0]][key[1]]
else:
return self.coords[key]
def move(self, delta_x, delta_y):
for self in self.coords:
self.move(delta_x, delta_y)
def length(self):
# base formula: length = sqrt((x2 - x1)**2 + (y2 - y1)**2)
points_temp = self.coords
for i in range(len(points_temp) - 1):
length = sqrt(((self.coords[i + 1].x - self.coords[i].x) ** 2) + (
(self.coords[i + 1].y - self.coords[i].y) ** 2))
self.lengths.append(length)
return sum(self.lengths)
if __name__ == '__main__':
# Tests for LineString
# ===================================
lin1 = LineString((1, 1), (0, 2)) # lin1 is an instance of LineString
assert lin1.length() == sqrt(2.0)
lin1.move(-1, -1) # Move by -1 and -1 for x and y respectively
print(lin1)
assert lin1[0].y == 0 # Inspect the y value of the start point.
# Implement this by overloading __getitem__(self, key) in your class.
lin2 = LineString((1, 1), (1, 2), (2, 2))
assert lin2.length() == 2.0
lin2.move(-1, -1) # Move by -1 and -1 for x and y respectively
assert lin2.length() == 2.0
assert lin2[-1].x == 1 # Inspect the x value of the end point.
print('Success! Line tests passed!')
倒数第二个断言总是出错。
首先推荐使用Python的单元测试框架, https://docs.python.org/3/library/unittest.html
这样,您将使用 self.assertEqual(lin2.length(), 2.0)
,而不仅仅是说 "getting an error with the second to last assert",它不仅会打印出错误,还会打印出 lin2.length()
的实际值。
其次,您永远不应该比较双精度值是否相等 - 它们不精确,微小的错误可能会导致计算稍有偏差,从而导致相等性失败。改为使用 assertAlmostEqual - https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertAlmostEqual
但这不是这里的问题。查找错误的最简单方法是交互式地使用 Python。只需 运行 互动 shell:
lin2 = LineString((1, 1), (1, 2), (2, 2))
lin2.length()
2.0
lin2.length()
4.0
这是问题所在 - length() 函数不清除 self.lengths
字段,并且它随着每次计算而不断增长!