Domanda

SymPy è un ottimo strumento per fare conversioni di unità in Python:

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

Puoi facilmente creare il tuo:

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

Tuttavia, non posso implementarlo nella mia applicazione se non riesco a convertire i gradi C (assoluti) in K in gradi F in gradi R, o in qualsiasi combinazione di essi.

Ho pensato che forse qualcosa del genere avrebbe funzionato:

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

Ma chiaramente questa è la strada sbagliata da percorrere. Qualche suggerimento per implementare in modo pulito le conversioni di unità di tipo "offset" in SymPy?

Nota: sono aperto a provare altri moduli di conversione di unità, ma non conosco altri oltre a Unum e l'ho trovato ingombrante.

Modifica: OK, ora è chiaro che quello che voglio fare è prima determinare se le due quantità da confrontare sono nello stesso sistema di coordinate. (come le unità di tempo che fanno riferimento a epoche o fusi orari diversi o dB ad ampiezza lineare), esegui la trasformazione appropriata, quindi esegui la conversione. Esistono strumenti generali di gestione del sistema di coordinate? Sarebbe grandioso.

Suppongo che & # 176; F e & # 176; C si riferiscano sempre a & # 916; & # 176; F & # 916; & # 176; C all'interno di un'espressione ma si riferiscano all'assoluto quando si sta in piedi solo. Mi stavo solo chiedendo se ci fosse un modo per rendere units.degF una funzione e dare uno schiaffo su una proprietà () del decoratore per far fronte a queste due condizioni.

Ma per ora, imposterò units.C == units.K e proverò a chiarire molto chiaramente nella documentazione l'uso delle funzioni convertCtoK (...) e convertFtoR (...) quando si tratta di unità assolute. (Sto scherzando. No, non lo farò.)

È stato utile?

Soluzione

Personalmente mi piace Quantities grazie alla sua NumPy integrazione, tuttavia fa solo temperature relative, non assolute.

Altri suggerimenti

La documentazione di Unum ha una buona scrittura sul perché questo è difficile:

  

Unum non è in grado di gestire in modo affidabile conversioni tra & # 176; Celsius e Kelvin. Il problema viene definito "problema di falsa origine": lo 0 ° C è definito come 273,15 K. Questo è davvero un caso speciale e fastidioso, poiché in generale il valore 0 non è influenzato dalla conversione dell'unità, ad es. 0 [m] = 0 [miglia] = .... Qui, la conversione Kelvin / & # 176; Celsius è caratterizzata da un fattore 1 e un offset di 273,15 K. L'offset non è possibile nella versione corrente di Unum.

     

Inoltre presumibilmente non verrà mai integrato in una versione futura perché esiste anche un problema concettuale: l'offset dovrebbe essere applicato se la quantità rappresenta una temperatura assoluta, ma non dovrebbe farlo se la quantità rappresenta una differenza di temperature. Ad esempio, un aumento della temperatura di 1 & # 176; Celsius equivale a un aumento di 1 K. È impossibile indovinare ciò che è nella mente dell'utente, che si tratti di una temperatura assoluta o relativa. La questione delle quantità assolute rispetto a quelle relative non è importante per le altre unità poiché la risposta non influisce sulla regola di conversione. Unum non è in grado di distinguere tra i due casi.

È abbastanza facile vedere concettualmente i problemi nel tentativo di rappresentare simbolicamente la conversione della temperatura assoluta. Con qualsiasi unità relativa normale, (x unit) * 2 == (x * 2) unit & # 8212; l'unità matematica è commutativa. Con temperature assolute, questo si rompe & # 8212; è difficile fare qualcosa di più complesso delle conversioni di temperatura diritte senza altre dimensioni dell'unità. Probabilmente è meglio mantenere tutti i calcoli in Kelvin e convertirli in e da altre unità di temperatura solo nei punti di entrata e uscita del codice.

Esempio, come potrebbe funzionare:

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

Il pacchetto natu gestisce le unità di temperatura. Ad esempio, puoi farlo:

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

Sono supportati anche i prefissi:

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

natu gestisce anche unità non lineari come decibel , non solo quelli con offset come gradi Celsius e gradi Fahrenheit .

In relazione al primo esempio che hai fornito, puoi farlo:

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

BTU è già integrato. Puoi cambiare la sua unità di visualizzazione in m ** 2 * kg / s ** 2, ma per impostazione predefinita natu semplifica l'unità in J:

>>> from natu.units import BTU
>>> BTU.display = 'm2*kg/s2'
>>> 1*BTU
1055.05585262 J
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top