I want to test a function that outputs a heading in degrees, which is a number in the interval [0, 360). Since the result is a floating-point number, comparing the actual result against the expected with unittest.assertEqual() does not work. unittest.assertAlmostEqual() is better since it provides a tolerance. This approach works for heading that are not close to 0 degrees.
Question: What is the correct way to test for headings whose expected value is 0 degrees? assertAlmostEquals() would only include angles that are slightly larger than 0 degrees, but would miss those that are slightly smaller than 0, i.e. 360 degrees...
You can use the squared Euclidian distance between two points on the unit circle and the law of cosines to get the absolute difference between two angles:
from math import sin, cos, acos
from unittest import assertAlmostEqual
def assertAlmostEqualAngles(x, y, **kwargs):
c2 = (sin(x)-sin(y))**2 + (cos(x)-cos(y))**2
angle_diff = acos((2.0 - c2)/2.0) # a = b = 1
assertAlmostEqual(angle_diff, 0.0, **kwargs)
This works with radians. If the angle is in degrees, you must do a conversion:
from math import sin, cos, acos, radians, degrees
from unittest import assertAlmostEqual
def assertAlmostEqualAngles(x, y, **kwargs):
x,y = radians(x),radians(y)
c2 = (sin(x)-sin(y))**2 + (cos(x)-cos(y))**2
angle_diff = degrees(acos((2.0 - c2)/2.0))
assertAlmostEqual(angle_diff, 0.0, **kwargs)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With