Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python unittesting: Test whether two angles are almost equal

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...

like image 936
Thomas Schreiter Avatar asked Mar 27 '26 13:03

Thomas Schreiter


1 Answers

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)
like image 161
Sturla Molden Avatar answered Mar 29 '26 02:03

Sturla Molden