Now that the question of how to parse a string for magnitude and physical unit is settled, the next question is, how should one best go on about packing these two together in a way that on the one hand does not cost too much performance but on the other hand adds a unit validation.
To make clear what I mean, take as an example two velocities v = 5 m/s
and u = 10 mph
. The previous question already takes care of converting everything to SI units (so you won't crash another Mars mission due to that). So internally one would have e.g. a tuple v = (5, m/s)
and u = (4.4704, m/s)
and the output routine would take care of using the preferred units for output. While applying unit-compatible operations on the two, e.g. addition, or subtracting their squares, are valid, others like v - 1/u
are complete and utter nonsense. But how should this best be implemented? Some possibilities that I considered so far:
tuple
and override all valid operations prepending unit consistency checks. Sounds fun...sympy.core.mul.Mul
s of the magnitude times a (meaningful function of) sympy.physics.unit.Unit
, e.g v = 5*unit.m/unit.s
. I don't expect great performance of this, plus I'd still have to check whether the result of an operation is still of the form magnitude * unit
.numpy.array
with an additional sympy.physics.unit.Unit
entry, which already implements the elementwise operations. This would still require a manual unit consistency check afterwards (the fact that e.g. m+m=2m
would also need to be treated...)numpy.array
instead of tuple
, override the operators prepending the unit consistency check before calling the super
-operators on the array without the unit. Maybe some __getattribute__
magic could simplify this since all valid operations are already implemented for both magnitude and unit...Is one of these solutions good/pythonic? Or what other way is there? Does a library that treats this already exist?
edit Note that this should not be restricted to scalar values; vectors, matrices (maybe even sympy.Symbol
s) should also work
Use the Magnitude library:
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')
The interesting thing happens when there is a unit mismatch:
>>> 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]
Not the best error message perhaps, but it effectively prevents you from handling values in the wrong way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With