python - 在 python 单元测试 中,用于浮点数集,assertAlmostEqual

  显示原文与译文双语对照的内容
0 0

" assertAlmostEqual( x,y ) 中方法 Python是单元测试框架测试是否 xy大约相等假设它们浮动。

存在的问题 assertAlmostEqual()是它只适用于浮动。 我在找这样的方法 assertAlmostEqual()该操作在列表上的浮动的浮动,设置浮动的浮点数,元组,列表,字典,元组的浮动,设置浮动的列表等。

例如,让 x = 0.1234567890, y = 0.1234567891. xy几乎是相等的,因为它们都同意每一个数字最近1 。 因此 self.assertAlmostEqual(x, y)True因为 assertAlmostEqual()适用于float 。

我在找更一般 assertAlmostEquals()这也可以计算以下调用 True:

  • self.assertAlmostEqual_generic([x, x, x], [y, y, y]).
  • self.assertAlmostEqual_generic({1: x, 2: x, 3: x}, {1: y, 2: y, 3: y}).
  • self.assertAlmostEqual_generic([(x,x)], [(y,y)]).

后会出现方法或我必须自己实现它?

CLARIFICATIONS :

  • assertAlmostEquals()有一个可选的参数命名 places这数字来比较计算的差值四舍五入到小数位 places. 默认情况下, places=7,因此, self.assertAlmostEqual(0.5, 0.4)是False时 self.assertAlmostEqual(0.12345678, 0.12345679)为true 。 我推测 assertAlmostEqual_generic()应具有相同的功能。

  • 两个列表都被认为是几乎相等如果他们几乎相等数字完全相同的顺序。 确切地讲, for i in range(n): self.assertAlmostEqual(list1[i], list2[i]).

  • 同样,两个集被认为是几乎相等如果它们可以转换为约等于列表( 通过分配订单到每组) 。

  • 同样,两个字典被认为几乎相等如果key设置每个字典几乎比得上其他词典,对于每个这样的键集约等于密钥对都有一个对应的约等于值。

  • 一般情况下: 我认为两个集合几乎相等如果相等只是有一些相应的浮动这只是约等于对方 换句话说,我想真的比较对象,但较低的( 自定义) 精度进行比较时,浮动到位。

时间:原作者:5个回答

0 0

如果你不介意使用NumPy ( 你Python( x ,y ) 自带的程序),你可能希望查看 np.testing模块用于定义主要有一个 assert_almost_equal函数。

要验证的签名字节 np.testing.assert_almost_equal(actual, desired, decimal=7, err_msg='', verbose=True)

>>> x = 1.000001
>>> y = 1.000002
>>> np.testing.assert_almost_equal(x, y)
AssertionError: 
Arrays are not almost equal to 7 decimals
ACTUAL: 1.000001
DESIRED: 1.000002
>>> np.testing.assert_almost_equal(x, y, 5)
>>> np.testing.assert_almost_equal([x, x, x], [y, y, y], 5)
>>> np.testing.assert_almost_equal((x, x, x), (y, y, y), 5)
原作者:
0 0

方法如下我实现泛型is_almost_equal(first, second)函数:

首先,你需要复制该对象比较( firstsecond),但不进行精确复制: 剪切微不足道十进制数字中的任何float你遇到了对象。

既然已经的副本 firstsecond对其微不足道的十进制数字消亡,只是比较 firstsecond使用 ==运算符。

让我们假设我们有一个 cut_insignificant_digits_recursively(obj, places)函数的重复项 obj但只保留 places最重要的十进制数字中每个float的原始 obj. 这是一个工作实现的 is_almost_equals(first, second, places):

from insignificant_digit_cutter import cut_insignificant_digits_recursively
def is_almost_equal(first, second, places):
    '''returns True if first and second equal. 
    returns true if first and second aren't equal but have exactly the same
    structure and values except for a bunch of floats which are just almost
    equal (floats are almost equal if they're equal when we consider only the
    [places] most significant digits of each).'''
    if first == second: return True
    cut_first = cut_insignificant_digits_recursively(first, places)
    cut_second = cut_insignificant_digits_recursively(second, places)
    return cut_first == cut_second

这是工作的实现 cut_insignificant_digits_recursively(obj, places):

def cut_insignificant_digits(number, places):
    '''cut the least significant decimal digits of a number, 
    leave only [places] decimal digits'''
    if  type(number) != float: return number
    number_as_str = str(number)
    end_of_number = number_as_str.find('.')+places+1
    if end_of_number > len(number_as_str): return number
    return float(number_as_str[:end_of_number])
def cut_insignificant_digits_lazy(iterable, places):
    for obj in iterable:
        yield cut_insignificant_digits_recursively(obj, places)
def cut_insignificant_digits_recursively(obj, places):
    '''return a copy of obj except that every float loses its least significant 
    decimal digits remaining only [places] decimal digits'''
    t = type(obj)
    if t == float: return cut_insignificant_digits(obj, places)
    if t in (list, tuple, set):
        return t(cut_insignificant_digits_lazy(obj, places))
    if t == dict:
        return {cut_insignificant_digits_recursively(key, places):
                cut_insignificant_digits_recursively(val, places)
                for key,val in obj.items()}
    return obj

代码及其单元测试也可以这里使用: https://github .com/snakile/approximate_comparator 。 我欢迎任何改进和bug修复。

原作者:
0 0

没有这样的方法,你得自己动手。

对列表和元组的定义很明显,但请注意,你提到其他情况下不明显,所以难怪这样一个函数它未提供。 例如,是 {1.00001: 1.00002}约等于 {1.00002: 1.00001}? 处理这种情况下需要在选择时是否依赖程度左侧的键或值。 你不可能找到有意义的定义集,因为集合是无序的,所以没有对应的" 元素" 的概念。

原作者:
0 0

如果你不介意使用 numpy包然后 numpy.testing具有 assert_array_almost_equal方法。

这适用于 array_like对象,因此它能够很好地浮动,而是去不适用于设置的数组,列表和元组和字典。

这里的文档是

原作者:
0 0

你可能需要实现它自己,而其事实并设置可以遍历列表一样,字典是另一回事,你迭代其密钥没有值,第三个示例似乎对我有点不明确,你是要比较,该组中的每个值,从每组或每个值。

下面是一个简单的代码段。

def almost_equal(value_1, value_2, accuracy = 10**-8):
    return abs(value_1 - value_2) < accuracy
x = [1,2,3,4]
y = [1,2,4,5]
assert all(almost_equal(*values) for values in zip(x, y))
原作者:
...