断言两个变量在 python 中几乎相等

Assert two variables are almost equal in python

这里有两个变量:earnings_forecastactual_earning(数值变量)

我想断言这两个变量是否相等,相对于 actual_earning 变量可接受 ±2% 的差异。

假设: earnings_forecast = 6 actual_earnings = 5.19

我不能使用 assertEqual(earnings_forecast, actual_earnings) 因为它会尝试进行精确匹配,相反我想断言这两个变量几乎相等,可接受 ±2% 的差异。

abs(earnings_forecast - actual_earning) < 0.01 * abs(earnings_forecast + actual_earning)

是一种很好的方法,它可以让你在两边都有很好的对称 2% 的差异。它也不会遭受其中一个值为零可能出现的陷阱。

还有其他定义,但与上述定义一样,它们各有利弊。

您可以使用 Python 3.5

中引入的新 isclose 函数

PEP 485 adds the math.isclose() and cmath.isclose() functions which tell whether two values are approximately equal or “close” to each other. Whether or not two values are considered close is determined according to given absolute and relative tolerances. Relative tolerance is the maximum allowed difference between isclose arguments, relative to the larger absolute value

import math
a = 100.0
b = 102.0
c = 103.0

assert math.isclose(a,b, rel_tol=0.02)
assert math.isclose(a,c, rel_tol=0.02)

只需定义一个新测试:

def assertNearlyEqual(self,a,b,fraction=0.02,msg=None):
    if abs(a-b) > abs(fraction*a):
        if msg is None:
            self.fail("The given numbers %s and %s are not near each other."%(a,b))
        else:
            fail(msg)

并用你的两个变量调用它:

self.assertNearlyEqual(earnings_forecast,actual_earning)

简单方法:

a, b = sorted(map(float, (a, b)))
assert a + abs(a)*1.02 >= b

您可以使用自定义 Testcase 子类用于测试:

class FooTestCase(TestCase):
    def assertAlmostEqual(a, b):
        a, b = sorted(map(float, (a, b)))
        self.assertTrue(a + abs(a)*1.02 >= b)

对于那些仍然使用Python 2.x的人,您也可以使用numpy.isclose()

from numpy import isclose as isclose
a = 100.0
b = 100.01

print isclose(a,b, atol=0.02)  # True

来自文档:

For finite values, isclose uses the following equation to test whether two floating point values are equivalent.

absolute(a - b) <= (atol + rtol * absolute(b))