2013-04-10 14 views
5

Ora che la domanda di how to parse a string for magnitude and physical unit è stata risolta, la prossima domanda è: come si dovrebbe procedere meglio per riunire questi due insieme in un modo che, da un lato, non costa troppe prestazioni, ma dall'altro aggiunge una convalida dell'unità .Come decodificare tonicamente grandezza e unità fisiche?

Per chiarire cosa intendo, prendere come esempio due velocità v = 5 m/s e u = 10 mph. Lo previous question si occupa già della conversione di tutto in SI units (quindi non lo sarà crash another Mars mission a causa di che). Quindi internamente avremmo ad es. una tupla v = (5, m/s) e u = (4.4704, m/s) e la routine di output si occuperà di utilizzare le unità preferite per l'output. Durante l'applicazione di operazioni compatibili con le unità sui due, ad es. l'aggiunta o la sottrazione dei loro quadrati sono validi, altri come v - 1/u sono completi e senza senso. Ma come dovrebbe essere implementato al meglio? Alcune possibilità che ho considerato finora:

  • no. Poiché internamente vengono utilizzate solo unità SI, è essere ovvio quali unità si applicano. Ma trascurare queste informazioni è molto probabile che diventi una fonte di bug se le formule diventano più complesse
  • Sottoclasse tuple e sostituiscono tutte le operazioni valide che precedono i controlli di coerenza delle unità. Sembra divertente ...
  • Memorizza i valori come sympy.core.mul.Mul s dei tempi di magnitudine a (funzione significativa di) sympy.physics.unit.Unit, ad esempio v = 5*unit.m/unit.s. Non mi aspetto grandi prestazioni di questo, in più dovrei comunque verificare se il risultato di un'operazione è ancora del modulo magnitude * unit.
  • Utilizzare un numpy.array con una voce aggiuntiva sympy.physics.unit.Unit, che già implementa le operazioni elementwise. Questo sarebbe ancora bisogno di un controllo di un'unità di coerenza manuale dopo (il fatto che ad esempio m+m=2m sarebbe anche bisogno di essere trattati ...)
  • sottoclasse numpy.array invece di tuple, ignorare gli operatori anteponendo il controllo di coerenza unità prima chiamare il super - operatori sull'array senza l'unità. Forse qualche __getattribute__ magia potrebbe semplificare questo in quanto tutte le operazioni valide sono già implementati sia per la grandezza e l'unità ...

è una di queste soluzioni di buona/divinatorio? O quale altro modo c'è? Esiste già una libreria che tratta questo?

modifica Si noti che questo non deve essere limitato ai valori scalari; vettori, matrici (forse anche sympy.Symbol i) dovrebbero funzionare anche

risposta

1

utilizzare la libreria Magnitude:

from magnitude import mg 

m = mg(5, 'kg') 
a = mg(9.82, 'm/s2') 
f = m * a 
print f, f == mg(49.1, 'N') 

u = mg(70, 'km/h') 
g = mg(9.82, 'm/s2') 
s = (u**2)/(2*g) 
print s, s > mg(10, 'm') 

La cosa interessante accade quando v'è una mancata corrispondenza unità:

>>> m = mg(5, 'kg') 
>>> a = mg(9.82, 'm/s') 
>>> f = m * a 
>>> print f, f == mg(49.1, 'N') 
MagnitudeError: Incompatible units in comparison: [1, -2, 0, 1, 0, 0, 0, 0, 0] and [1, -1, 0, 1, 0, 0, 0, 0, 0] 

Non il migliore errore messaggio forse, ma in realtà impedisce di gestire i valori nel modo sbagliato.

+0

Sembra buono (il messaggio di errore riguarda i poteri dell'unità SI, suppongo). Può anche trattare gli array? –

+0

Intendi liste?'[mg (t, 's') * mg (70, 'km/h') per t in range (10)]' –

+0

Stavo pensando a vettori e matrici, ad es. I vettori di velocità 3D, e qualcosa come 'mg ([. 5,0,3], 'm/s')' probabilmente sembrano più belli di '[mg (.5, 'm/s'), mg (0, ' m/s '), mg (3,' m/s ')] ' –

Problemi correlati