2014-12-02 2 views
2

Я хочу проверить функцию, которая выводит заголовок в градусах, который является числом в интервале [0, 360]. Поскольку результатом является число с плавающей запятой, сравнение фактического результата с ожидаемым с помощью unittest.assertEqual() не работает. unittest.assertAlmostEqual() лучше, поскольку он обеспечивает допуск. Этот подход работает для заголовка, который не близок к 0 градусам.Python unittesting: проверьте, равны ли два угла равны

Вопрос: Каков правильный способ проверки заголовков, ожидаемое значение которых составляет 0 градусов? assertAlmostEquals() будут включать только углы, которые немного больше 0 градусов, но будут пропускать те, которые немного меньше 0, то есть 360 градусов ...

+0

Определите собственную вспомогательную функцию, которая принимает два угла и возвращает абс разности – matcheek

+0

Всякий раз, когда вы сравниваете числа с плавающей точкой, вы должны включать в себя " epsilon ', небольшое число, ниже которого вещи считаются для всех целей и целей равными нулю. Пример: 1E-6 или 1E-8 и т. Д. 'A == b, если abs (a - b) <= epsilon'. Все становится сложным, если оба значения приближаются к нулю. – Pierre

ответ

4

Вы можете использовать квадрат евклидова расстояния между двумя точками на единичном круге и закон косинусов для получения абсолютной разницы между двумя углами:

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) 

Это работает с радианами. Если угол в градусах, необходимо выполнить преобразование:

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) 
+0

Я не думаю, что это очень хорошо сохраняет различия между углами. – simonzack

+0

@SturlaMolden Концепция работает с двумя модификациями: (1) При сравнении результатов sin и cos следует установить допуск; Я закончил использование 'delta = 0.001'. (2) Если ввод задан в градусах, нужно преобразовать его в радианы с помощью 'x = math.radians (x)'. – ThS

+0

Я добавил числовую поправку, используя закон косинусов, а также ** kwargs для передачи мест аргументов аргументов, msg и delta для assertAlmostEqual. –

Смежные вопросы