Gas station without pumps

2011 December 27

Units in physics

Filed under: home school — gasstationwithoutpumps @ 12:32
Tags: , , , , , ,

The post today by A higher power — units again, triggered one of the little things that has been bugging me about how I’m teaching Physics using Matter and Interactions and VPython.  The problem is that VPython does not have any way of expressing or keeping track of units.  All the variables are just real (or complex) numbers, with no attached units.  Although that is standard practice in computer programming, it is not standard practice in physics and is pedagogically a bad idea, as debugging a hidden change of units is very difficult for students.  (The article that triggered this musing is about units to higher powers, like length6 or length4, where they come from, and how to think about them, but that is not the problem I’m interested in right now.)

I’m wondering how difficult it would be in VPython to create a new class of  objects which can be scalars or vectors with units.  It has been done in other languages in the past (see, for example, Incorporation of units into programming languages by Michael Karr and David B. Loveman, II, Communications of the ACM, Volume 21 Issue 5, May 1978 doi:10.1145/359488.359501), and is still being done in other languages.

The popular SciPy scientific Python package does not implement units—there is unit name associated with the constants in its table of constants, but it is just a string, with no attached semantics, and it is not carried with the numbers.  But there are implementations of units of measurement in Python.  There is a discussion  on bytes.com of this very question, pointing to several implementations. A couple of the implementations pointed to have dead links (http://RussP.us/scalar.htm and http://home.tiscali.be/be052320/Unum.html). The RussP code does not seem to be findable on the web (I’ve not bothered checking the Wayback Machine, since unmaintained code is not a good idea to incorporate into a project), but the Unum code seems to now be at https://bitbucket.org/kiv/unum/, where it is still actively maintained. The description at bitbucket seems promising:

Unum stands for ‘unit-numbers’. It is a Python module that allows you to define and manipulate quantities with units attached such as 60 seconds, 500 watts, 42 miles-per-hour, 100 kg per square meter, 14400 bits per second, 30 dollars, and so on. Features include exceptions for incorrect use of units, automatic and manual conversion between compatible units, easy extension to arbitrary units, and integration with other arithmetic types including Numpy arrays and standard library types like complex and fractions.Fraction.

The installation instructions for Unum claim that it can be installed with easy_install, but that was deliberately broken on Sept 4, 2011, and the installation instructions not updated to reflect the change.  Installation with the alternative instructions (downloading the tar file, untarring it, and running “python setup.py install”) does work, and Unum seems fairly solid.  It is probably dangerous to use “from unum.units import *”, since there are a lot of short names that get defined, and someone is likely to have used one of them with a different meaning already.  Using “from unum import units” is probably better, since that allows expressions like 2*units.cm, which avoids ambiguity.  One minor feature of Unum is that it keeps units with prefixes (km, cm, mm), which can be an advantage or disadvantage.  It is possible to force particular units:

sp = 10*units.km/ (5*units.h)
>>> sp
2 [km/h]
>>> sp.asNumber(units.m/units.s) *units.m/units.s
0.555555555556 [m/s]
>>> sp.asUnit(units.m/units.s)
0.555555555556 [m/s]

In the comp.lang.python Google group, Will Ware posted mks.py, a fairly minimal implementation of numbers with units.  If I’m reading the code right, there are some weird restrictions (like requiring unit-less scalars to the left of numbers with units when multiplying, so 2.7*liters is legal, but (1*liters)*2.7 is not).  This is a minimal implementation that can be used with care, but is not robust enough for use with novice programmers. Unum looks like a better bet.

Pyre does explicitly include units, but it is intended for experts to create efficient code, and the complexity of the framework is probably too much for first-time programmers.

ScientificPython looks like a competitor for SciPy, and includes an interface to VPython already.  I’ve not checked how well the Scientific.Physics.PhysicalQuantities module (which implements “physical quantities with units, including unit conversion and arithmetic operations with unit checks”) is integrated with VPython, but it looks like Konrad Hinsen has done most of the work here.  Of course, picking up the whole package may be a bit much as there is a lot of stuff here that is not relevant to a first-year physics class, so the documentation may be overwhelming.  It does seem simpler to use just a subset of this than to use Pyre, though.

I now have to decide whether to suggest to my students that they install and use Unum with their Vpython programs.  It would certainly help them keep their units straight.

8 Comments »

  1. Just some quick thoughts…

    I love letting the compiler help me avoid errors. My programing style includes many techniques that allow me to be a little lazy because I am guaranteed that the compiler will catch my flubs. This prevents lots of errors. One example I use is time classes (e.g. CSeconds, CMinutes, CHours, etc.) which makes it harder to make errors. Ever since reading an ACM lecture (I think by Edsger Dijkstra) about how the limitation to computational complexity was programers, I’ve accepted my limitations better :-)

    However, I’d worry that rather than teaching physics students to think about units more, using a language construct to manage units would create a laziness… especially since it’d probably contain conversion (e.g. I can imagine setting Velocity in ft/sec and then displaying it in meters/sec without ever thinking about the conversion, or accidentally setting Acceleration to be ft/sec and having the compiler tell me, preventing me from figuring these things out myself).

    Maybe for learning environments it’d be better just to depend on variable names…

    Distance_ft=10;
    Time_sec=8;
    Velocity_ftpersec=Distance_ft/Time_sec;

    That way, it forces the student to carefully think about the use of units, Of course, sometimes the units can be too complex to be part of a variable name…

    Comment by Ron G. — 2011 December 27 @ 13:43 | Reply

    • Ron, I understand your concern about students leaning on the computer to do unit conversions for them, and so not getting enough practice at doing unit conversions themselves. I think, though, that this is best addressed in pencil-and-paper exercises, rather than in the programming exercises.

      I think that getting the students to think of the units as an intrinsic part of the object being manipulated, rather than as a comment or naming convention, is worth the loss of practice in doing conversions manually. It is probably even worth the inefficiency that Unum adds to VPython programs. Perhaps I’ll have my son experiment with this first, before asking the other student to use it in his programs.

      Comment by gasstationwithoutpumps — 2011 December 27 @ 15:09 | Reply

  2. I truly lament that most languages don’t offer any way to express units on their values. I have seen (and built) some C++ libraries that can do this, but using them becomes somewhat clumsy lacking proper language support.

    It is far too often that when doing science programming I end up tracking down bugs to assignments which are of incompatible types. The compiler will tell you when you convert a double to a float, but in this domain it is far more important to catch a conversion from s^2 to m/s, for example.

    Such units even have great application outside of science domains. Even at the higher level a lot of defects can be attributed to doing things like assigning a “raw” string to an “html” variable. A language which offers units (or some kind of sub-typing) would be equally able to address such high-level type conversions.

    Comment by mortoray — 2011 December 27 @ 22:21 | Reply

    • Python makes it easy (though somewhat inefficient) to carry the units with the value, but does not provide any compile-time checking. It is only when you try to add or subtract units that it notices incompatible types (or if you ask for the number in a given set of units that is not compatible, like asking for a length in seconds). This delayed checking is part of the philosophy of Python, and is sometimes a real advantage, but often makes debugging difficult, as the erroneous assignment is not caught where it is made but possibly much later in some distant part of the code.

      I believe that Pyre is an attempt to provide compile-time units checking for Python programs, to get the efficiency of not needing to check units on every arithmetic operation. The setup needed by the programmer is a bit more involved than with Unum, and so is probably not suitable for first-time programmers.

      Comment by gasstationwithoutpumps — 2011 December 28 @ 00:27 | Reply

      • I’ve seen other runtime systems before as well (one was for C++). I guess if you use a language without static typing you can’t really expect static typing here. The biggest drawback, is as you say, that your incorrect assignment might not be caught until much later.

        In this case I think static checking has a huge advantage here in terms of efficiency. These checks would virtually disappear at run-time, and even the unit information itself can be made to have no cost what-so-ever. Cost is perhaps the only counter argument to such typing; static typing would pretty much eliminate that.

        In the C++ system I looked at the biggest problem was with roots and non-integral units — it simply couldn’t deal with them. A full solution would of course have to deal with such oddities, and perhaps if it cannot it may not be useful at all.

        Comment by mortoray — 2011 December 28 @ 01:25 | Reply

        • I believe that Unum handles roots, but only if the results have integer exponents. For a system that is to be used for real simulations, I agree that static type checking is preferable to runtime computation of units, and I would not use Python for the core of a simulator. When I need high efficiency in a program, I write it in C++. I have found that it is much faster to program in Python than in C++, though, despite may more years of C++ experience, so for programs where efficiency does not mater, or where the programming time far exceeds the runtime, I now prefer Python.

          Certainly for teaching first-time programmers to do tiny simulations in order to learn physics, Vpython with Unum is a better choice than C++.

          Comment by gasstationwithoutpumps — 2011 December 28 @ 08:30 | Reply

  3. […] flaws in VPython as an instructional tool for physics.  I’ve blogged about this before in Physics with Units, and I’ve done some VPython programming using Unum.  Unfortunately, the Vpython plotting and […]

    Pingback by Caballero on teaching physics with computation | Gas station without pumps — 2013 July 4 @ 10:28 | Reply

  4. […] learning calculus-based physics, and was irritated by its inability to play nicely with units (see Units in physics and Physics simulations). It would be a fairly simple modification to Vpython to allow a […]

    Pingback by Units in physics again | Gas station without pumps — 2013 August 4 @ 17:22 | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply to Units in physics again | Gas station without pumps Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: