Conversão de unidades em python
-
06-07-2019 - |
Pergunta
Simpy é uma ótima ferramenta para fazer conversões de unidades no Python:
>>> from sympy.physics import units
>>> 12. * units.inch / units.m
0.304800000000000
Você pode rolar facilmente o seu próprio:
>>> units.BTU = 1055.05585 * units.J
>>> units.BTU
1055.05585*m**2*kg/s**2
No entanto, não posso implementar isso no meu aplicativo, a menos que possa converter graus C (absoluto) em K a graus F a graus r, ou qualquer combinação dele.
Eu pensei que talvez algo assim funcionasse:
units.degC = <<somefunc of units.K>>
Mas claramente esse é o caminho errado a seguir. Alguma sugestão para a implementação de conversões de unidades do tipo "Offset" de forma limpa no Sympy?
Nota: Estou aberto a experimentar outros módulos de conversão de unidades, mas não conheço nenhum além Unum, e achei que era complicado.
EDIT: OK, agora está claro que o que eu quero fazer é primeiro determinar se as duas quantidades a serem comparadas estão no mesmo sistema de coordenadas. (Como as unidades de tempo referem -se a diferentes épocas ou fusos horários ou DB para amplitude reta), faça a transformação apropriada e faça a conversão. Existem ferramentas gerais de gerenciamento de sistema de coordenadas? Isso seria bom.
Eu assumia que ° F e ° C sempre se referiram a δ ° F δ ° C dentro de uma expressão, mas me referiram ao absoluto quando estão sozinhos. Eu só estava me perguntando se havia uma maneira de fazer units.degF
uma função e tapa um decorador property()
nele para lidar com essas duas condições.
Mas por enquanto, eu vou definir units.C == units.K
e tente deixar muito claro na documentação para usar funções convertCtoK(...)
e convertFtoR(...)
Ao lidar com unidades absolutas. (Apenas brincando. Não, não vou.)
Solução
Eu pessoalmente gosto Quantidades Graças ao seu Numpy A integração, no entanto, apenas faz temperaturas relativas, não absolutas.
Outras dicas
A documentação Unum tem uma boa redação sobre por que isso é difícil:
A UNUM é incapaz de lidar com conversões de maneira confiável entre ° Celsius e Kelvin. A questão é referida como o 'problema de origem falsa': o 0 ° Celsius é definido como 273,15 K. Este é realmente um caso especial e irritante, pois em geral o valor 0 não é afetado pela conversão da unidade, por exemplo, 0 [M] = 0 [Miles] = .... Aqui, a conversão Kelvin/° Celsius é caracterizada por um fator 1 e um deslocamento de 273,15 K. O deslocamento não é viável na versão atual do Unum.
Além disso, presumivelmente nunca será integrado em uma versão futura, porque também existe um problema conceitual: o deslocamento deve ser aplicado se a quantidade representar uma temperatura absoluta, mas não deveria se a quantidade representar uma diferença de temperaturas. Por exemplo, um aumento de temperatura de 1 ° Celsius é equivalente a um aumento de 1 K. É impossível adivinhar o que está na mente do usuário, seja uma temperatura absoluta ou relativa. A questão das quantidades absolutas vs relativas não é importante para outras unidades, pois a resposta não afeta a regra de conversão. A UNUM é incapaz de fazer a distinção entre os dois casos.
É muito fácil ver conceitualmente os problemas com a tentativa de representar a conversão de temperatura absoluta simbolicamente. Com qualquer unidade relativa normal, (x unit) * 2 == (x * 2) unit
- A unidade de matemática é comutativa. Com temperaturas absolutas, isso quebra - é difícil fazer algo mais complexo do que conversões de temperatura reta, sem outras dimensões unitárias. Você provavelmente é melhor manter todos os cálculos em Kelvin e converter para e para outras unidades de temperatura apenas nos pontos de entrada e saída do seu código.
Exemplo, como poderia funcionar:
>>> 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
o Natu O pacote lida com unidades de temperatura. Por exemplo, você pode fazer isso:
>>> 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
Os prefixos também são suportados:
>>> from natu.units import mdegC
>>> 100*mdegC/K
273.2500
Natu também lida com unidades não lineares, como o decibel, não apenas aqueles com compensações como Graus Celsius e grau Fahrenheit.
Relacionado ao primeiro exemplo que você deu, você pode fazer isso:
>>> from natu import units
>>> 12*units.inch/units.m
0.3048
Btu já está embutido. Você pode alterar sua unidade de exibição para M ** 2*kg/s ** 2, mas por padrão Natu simplifica a unidade para J:
>>> from natu.units import BTU
>>> BTU.display = 'm2*kg/s2'
>>> 1*BTU
1055.05585262 J