Преобразование единиц в Python

SymPy - отличный инструмент для преобразования единиц в Python:

>>> from sympy.physics import units
>>> 12. * units.inch / units.m
0.304800000000000

Вы можете легко перевернуть свои собственные:

>>> units.BTU = 1055.05585 * units.J
>>> units.BTU
1055.05585*m**2*kg/s**2

Однако я не могу реализовать это в своем приложении, если я не могу преобразовать градусы C (абсолютный) в K в градусы F до градусов R или любую комбинацию.

Я подумал, может быть, что-то вроде этого будет работать:

units.degC = <<somefunc of units.K>>

Но ясно, что это неправильный путь. Любые предложения по чистому преобразованию единиц измерения "смещение" в SymPy?

Примечание. Я открыт для тестирования других модулей преобразования единиц, но не знаю, кроме Unum, и нашел его быть громоздким.

Изменить: Хорошо, теперь ясно, что то, что я хочу сделать, - это сначала определить, находятся ли две сравниваемые величины в одной и той же системе координат. (например, временные единицы, относящиеся к разным эпохам или часовым поясам или дБ до прямой амплитуды), сделайте соответствующее преобразование, а затем выполните преобразование. Существуют ли какие-либо общие инструменты управления системой координат? Это было бы прекрасно.

Я сделал бы предположение, что ° F и ° C всегда относятся к Δ ° F Δ ° C ​​в выражении, но относятся к абсолюту при стоянии в одиночку. Я просто задавался вопросом, есть ли способ сделать функцию units.degF и нанести на нее декоратор property(), чтобы справиться с этими двумя условиями.

Но на данный момент я установлю units.C == units.K и попытаюсь сделать это очень ясно в документации, чтобы использовать функции convertCtoK(...) и convertFtoR(...) при работе с абсолютными единицами. (Просто шучу. Нет, не хочу.)

Ответ 1

Мне лично нравится Quantities благодаря NumPy, однако он относит только относительные температуры, а не абсолютные.

Ответ 2

В документации Unum есть хорошая запись о том, почему это сложно:

Unum не может обрабатывать надежные преобразования между ° Цельсия и Кельвина. Проблема упоминается как "проблема ложного происхождения": 0 ° Цельсия определяется как 273,15 К. Это действительно особый и раздражающий случай, так как в целом значение 0 не влияет на единичное преобразование, например. 0 [м] = 0 [миль] =.... Здесь конверсия Kelvin/° Celsius характеризуется коэффициентом 1 и смещением 273,15 K. Смещение не представляется возможным в текущей версии Unum.

Кроме того, он, вероятно, никогда не будет интегрирован в будущую версию, потому что есть также концептуальная проблема: смещение должно применяться, если величина представляет абсолютную температуру, но не должна, если величина представляет собой разность температур. Например, повышение температуры на 1 градус Цельсия эквивалентно повышению на 1 К. Невозможно угадать, что находится в сознании пользователя, независимо от того, является ли это абсолютной или относительной температурой. Вопрос об абсолютных и относительных величинах не имеет значения для других единиц, поскольку ответ не влияет на правило преобразования. Unum не может провести различие между этими двумя случаями.

Довольно легко концептуально увидеть проблемы с попыткой символического преобразования абсолютной температуры символически. При любом нормальном относительном модуле (x unit) * 2 == (x * 2) unit -unit math является коммутативным. При абсолютных температурах, которые ломаются, трудно сделать что-либо более сложное, чем прямое преобразование температуры без каких-либо других измерений. Вероятно, вам лучше всего выполнять все вычисления в Кельвине и преобразовывать их в другие температурные единицы и из них только на входах и выходах вашего кода.

Ответ 3

Пример: как это работает:

>>> T(0*F) + 10*C
T(265.37222222222221*K) # or T(47767/180*K)
>>> T(0*F + 10*C)
T(283.15*K)
>>> 0*F + T(10*C)
T(283.15*K)
>>> 0*F + 10*C
10*K
>>> T(0*F) + T(10*C)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'absolute_temperature' and \
'absolute_temperature'
>>> T(0*F) - T(10*C)
T(245.37222222222223*K) # or T(44167/180*K)
>>> 0*F - 10*C
-10*K

Ответ 4

Пакет natu обрабатывает единицы измерения температуры. Например, вы можете сделать это:

>>> from natu.units import K, degC, degF
>>> T = 25*degC
>>> T/K
298.1500
>>> T/degF
77.0000
>>> 0*degC + 100*K
100.0 degC

Поддерживаются также префиксы:

>>> from natu.units import mdegC
>>> 100*mdegC/K
273.2500

natu также обрабатывает нелинейные единицы, такие как decibel, а не только с смещениями, такими как градус Цельсия и градус Фаренгейта.

Относительно первого примера, который вы указали, вы можете сделать это:

>>> from natu import units
>>> 12*units.inch/units.m
0.3048

BTU уже встроен. Вы можете изменить его дисплей на m ** 2 * кг/с ** 2, но по умолчанию natu упрощает блок до J:

>>> from natu.units import BTU
>>> BTU.display = 'm2*kg/s2'
>>> 1*BTU
1055.05585262 J