pyephem - типы широты/долготы наблюдателя

Почему было принято решение обрабатывать числовые значения широты и долготы наблюдателей как радианы, а строковые значения — как десятичные градусы?

При работе со значениями широты и долготы в Python я обычно имею дело с объектами с плавающей запятой. Если звезды выровнены правильно, там может быть объект int или два, но в основном плавающие. Я всегда наивно пишу такой код:

lat = 0.0
lon = 0.0

observer = ephem.Observer()
observer.lat = lat
observer.lon = lon
# etc... etc...

И тут я обжигаюсь. Я обжигаюсь, потому что мои значения широты и долготы указаны в десятичных градусах, а не в радианах. Обычно это плохо, потому что я в конечном итоге чешу голову, задаваясь вопросом, что я сделал неправильно. В итоге я перевожу в радианы. Теперь теоретически я мог бы сделать это, чтобы получить правильный результат:

observer = ephem.Observer()
observer.lat = str(lat)
observer.lon = str(lon)

Но это тоже кажется шатким, я думал, что мои значения должны быть в радианах! О, подождите, только если это поплавок. Я понимаю, что принимать строковые или плавающие объекты приятно, но принятие различных числовых типов на основе типов python кажется непоследовательным. Я ожидаю, что оба назначения будут принимать одни и те же числовые типы, например:

lat = lon = 0.55
observer.lat = lat  # float lat is assumed to be in radians
observer.lon = lon  # float lon is assumed to be in radians

lat = lon = '0.55'
observer.lat = lat  # string lat is assumed to be in radians
observer.lon = lon  # string lon is assumed to be in radians

Затем могут быть предоставлены операторы преобразования для десятичных градусов/дмс:

lat = '25.0'
lon = 25.0
observer.lat = ephem.to_rad(lat)
observer.lon = ephem.to_rad(lon)

Затем функция to_rad будет явно предполагать, что десятичные градусы предоставляются либо в виде объекта с плавающей запятой, либо в виде строки. На этом этапе интерфейсы будут согласованы. Я очень кратко просмотрел _libastro.c и изучил функцию to_angle, которая лежит в основе этого вопроса.

Я не могу придумать вескую причину, чтобы не реализовать это. На самом деле, я добровольно сделаю это! Но прежде чем я приступлю к этому, я знаю, что я не эксперт по libastro / pyephem, поэтому я хотел открыть этот вопрос, чтобы убедиться, что это имеет смысл. Вполне возможно, что это было сделано по очень веской причине, и я просто безнадежно запутался.

Если бы опытные пользователи или кто-то, знакомый с ядром программного обеспечения, могли бы прокомментировать, я был бы очень признателен.

Заранее спасибо!


person Joseph Armbruster    schedule 26.03.2013    source источник


Ответы (1)


Во-первых: когда вам нужно сделать явное преобразование градусов в радианы в текущей версии PyEphem, вы можете использовать константу degree, которая представляет собой один градус, измеряемый в радианах. Итак, вы можете написать что-то вроде этого:

observer.lat = 33.7 * ephem.degree

Идея заключалась в том, чтобы читатель научился воспринимать это как «33,7 умножить на один градус» — мое традиционное беспокойство по поводу имени функции, такого как to_rad(), заключается в том, что не обязательно будет ясно, из каких единиц оно преобразовывает. Если нужно было ввести функцию или метод, то имя вроде from_degrees() могло бы быть предпочтительнее, но я не уверен, что сам найду код более понятным, чем простое умножение числа на единицу degree, как показано выше.

Чтобы сделать еще один шаг назад: причина того, что радианы являются мерой угла по умолчанию, не связана с какой-либо теоретической причиной — например, тот факт, что радианы — это «естественный» способ измерения углов в математике, или тот факт, что они являются единицей измерения, ожидаемой Подпрограммы Python sin() и cos() для людей, которые используют углы PyEphem и занимаются тригонометрией, но в первую очередь потому, что это базовая единица, используемая библиотекой libastro, вокруг которой PyEphem является оболочкой. Это казалось наиболее очевидным шагом, особенно для людей, которые, возможно, уже использовали libastro в своем коде C, просто показать модули базовой библиотеки вместо того, чтобы скрывать их и всегда принудительно выполнять преобразование в каждом направлении.

Оглядываясь назад, возможно, было немного неясно, что печать угла обеспечивает удобство отображения часов (для RA) или градусов (для склонения), но как только это решение было принято — преобразование float → str перешло в часы или градусы. — тогда сама симметрия диктовала, что предоставление str должно также интерпретироваться как часы или градусы, чтобы строковые выходные и строковые входные данные были эквивалентны и в одних и тех же единицах измерения.

Следствием вашего аргумента, по-видимому, является то, что последний шаг - автоматическое преобразование str → float, если для атрибута, такого как .lat или .lon, указана строка - слишком неясен и должен быть просто отключен, поскольку предоставление строки, где число должно быть традиционно приводит к TypeError в Python, а не к волшебному тихому преобразованию. На самом деле я склонен согласиться, но я думаю, что на данный момент уже слишком поздно отключать преобразование и заставлять людей явно умножать на ephem.degree, потому что это нарушит так много существующего кода. Я хочу, чтобы PyEphem продолжал работать на людей, которые потратили время на написание программ против него.

Но я думаю, что ваша точка зрения правильная, и в моей новой skyfield библиотеке я не планирую никаких магических преобразований, с которыми вы столкнулись в PyEphem. Вместо этого, независимо от того, предоставляются ли радианы или градусы, я планирую сделать программирование явным в отношении того, что они предоставляют, и никогда не позволять им предоставлять «немаркированное» число. Вы можете проверить проект на GitHub, если хотите оценить его синтаксис по мере его развития:

https://github.com/brandon-rhodes/python-skyfield

person Brandon Rhodes    schedule 07.04.2013