简体   繁体   English

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

[英]Assert two variables are almost equal in python

Here are two variables: earnings_forecast , actual_earning (numerical variables)这里有两个变量: earnings_forecastactual_earning (数值变量)

I want to assert if both these variables are equal with a difference of ±2% acceptable with respect to actual_earning variable.我想断言这两个变量是否相等,并且相对于actual_earning变量可接受 ±2% 的差异。

Suppose: earnings_forecast = 6 actual_earnings = 5.19假设: actual_earnings = 5.19 earnings_forecast = 6 actual_earnings = 5.19

I cannot use assertEqual(earnings_forecast, actual_earnings) because it will try do an exact match, instead I want to assert both these variables are almost equal with ±2% difference acceptable.我不能使用assertEqual(earnings_forecast, actual_earnings)因为它会尝试进行精确匹配,相反我想断言这两个变量几乎相等,±2% 的差异是可以接受的。

You can use the new isclose function introduced in Python 3.5您可以使用 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. PEP 485 添加了 math.isclose() 和 cmath.isclose() 函数,它们判断两个值是近似相等还是彼此“接近”。 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相对容差是 isclose 参数之间允许的最大差异,相对于较大的绝对值

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)
abs(earnings_forecast - actual_earning) < 0.01 * abs(earnings_forecast + actual_earning)

is a nice way of doing it, which gives you a good symmetric 2% difference on either side.是一种很好的方法,它可以让您在任何一侧都有很好的对称 2% 差异。 It also doesn't suffer from pitfalls that can arise of one of the values is zero.它也不会遭受由于其中一个值为零而可能出现的陷阱。

There are other definitions, but like the one above, they have their own pros and cons.还有其他定义,但与上面的定义一样,它们各有优缺点。

Simply define a new test:只需定义一个新测试:

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)

and call it with your two variables:并用你的两个变量调用它:

self.assertNearlyEqual(earnings_forecast,actual_earning)

Simple approach:简单的方法:

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

You can use a custom Testcase subclass for use in tests:您可以在测试中使用自定义Testcase子类:

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

For those who still use Python 2.x, you could also use numpy.isclose()对于那些仍然使用 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

From the documentation:从文档:

For finite values, isclose uses the following equation to test whether two floating point values are equivalent.对于有限值,isclose 使用以下等式来测试两个浮点值是否相等。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM