Commits

committed fae6f98

.hgignore

`+syntax: glob`
`+*.pyc`

`+ipython-physics`
`+---------------`
`+`
`+This is an extension for IPython 0.11 that at the moment mainly enables easy`
`+input of physical quantities (i.e. numbers with units).  It requires the`
`+"ScientificPython" (not SciPy) package by Konrad Hinsen.`
`+`
`+Quick usage examples:`
`+`
`+  In:  1 m // cm                        # convert between units`
`+  Out: 100 cm                           # (syntax inspired by Mathematica)`
`+`
`+  In:  (1 m)/(1 s)                      # sugar for inline quantity input`
`+  Out: 1 m/s                            # in arbitrary expressions`
`+`
`+  In:  Q('1 m')/Q('1 s')                # this is the desugared form`
`+  Out: 1 m/s`
`+`
`+  In:  // furlong/fortnight             # convert units in last result`
`+  Out: 6012.8848 furlong/fortnight`
`+`
`+  In:  alpha = 90 deg                   # more sugar for assignment: no`
`+                                        # parentheses needed`
`+`
`+  In:  sin(alpha)                       # angle units work with NumPy`
`+  Out: 1.0                              # trigonometric functions`
`+`
`+  In:  %tbl sqrt(?x**2 + ?y**2) // cm   # quickly tabulate a formula:`
`+  x = 1 m                               # provide some values`
`+  y = 2 m`
`+  Out: 223.6068 cm                      # and get the result`
`+  x = 3 m                               # ... this continues as long as you`
`+  y = 4 m                               # enter new values`
`+  Out: 500 cm`
`+`
`+  In:  c0                               # important physical constants`
`+  Out: 2.9979246e+08 m/s`
`+  In:  setprec(4)                       # set the display precision`
`+  In:  c0`
`+  Out: 2.998e+08 m/s`
`+`
`+The predefined physical constants are:`
`+`
`+  c0    -- vacuum speed of light`
`+  mu0   -- magnetic constant`
`+  eps0  -- electric constant`
`+  Grav  -- Newton's constant`
`+  hpl   -- Planck's constant`
`+  hbar  -- Planck's constant / 2pi`
`+  e0    -- elementary charge`
`+  me    -- electron mass`
`+  mp    -- proton mass`
`+  mn    -- neutron mass`
`+  NA    -- Avogadro's number`
`+  kb    -- Boltzmann constant`
`+`
`+Please let me know if anything is missing.`

physics.py

` # -*- coding: utf-8 -*-`
`+"""`
`+IPython (0.11) extension for physical quantity input.`
`+See README.txt for usage examples.`
`+`
`+Author: Georg Brandl <georg@python.org>.`
`+This file has been placed in the public domain.`
`+"""`
`+`
` import re`
` import sys`
` from math import pi`
` from IPython.core import ipapi`
` `
`-from Scientific.Physics.PhysicalQuantities import PhysicalQuantity`
`+from Scientific.Physics.PhysicalQuantities import PhysicalQuantity, _addUnit`
` `
` name = r'([_a-zA-Z]\w*)'`
` number = r'(-?[\d0-9.eE]+)'`
` `
` inline_unit_re = re.compile(r'\((%s)\)' % quantity)`
` slash_conv_re = re.compile(r'^(.*?)//\s*%s\$' % unit)`
`-trailing_conv_re = re.compile(r'//\s*%s\$' % unit)`
`-nice_conv_re = re.compile(r'^(%s)\s+in\s+%s\$' % (quantity, unit))`
`+trailing_conv_re = re.compile(r'\s*//\s*%s\$' % unit)`
` nice_assign_re = re.compile(r'^%s\s*=\s*(%s)\$' % (name, quantity))`
` quantity_re = re.compile(quantity)`
` subst_re = re.compile(r'\?' + name)`
` def replace_inline(match):`
`     return 'Q(\'' + match.group(1).replace('^', '**') + '\')'`
` def replace_slash(match):`
`-    return '(' + match.group(1) + ').inUnitsOf(%r)' % str(match.group(2))`
`+    expr = match.group(1)`
`+    unit = str(match.group(2))  # PhysicalQuantity doesn't like Unicode strings`
`+    if quantity_re.match(expr):`
`+        return 'Q(\'' + expr + '\').inUnitsOf(%r)' % unit`
`+    elif not expr:`
`+        expr = '_'`
`+    return '(' + expr + ').inUnitsOf(%r)' % unit`
` def replace_conv(match):`
`     return 'Q(\'' + match.group(1).replace('^', '**') + '\').inUnitsOf(%r)' % \`
`         str(match.group(4))`
`     return '%s = Q(\'%s\')' % (match.group(1), match.group(2).replace('^', '**'))`
` `
` class QTransformer(object):`
`+    # XXX: inheriting from PrefilterTransformer as documented gives TypeErrors,`
`+    # but apparently is not needed after all`
`     priority = 99`
`     enabled = True`
`     def transform(self, line, continue_prompt):`
`         line = inline_unit_re.sub(replace_inline, line)`
`-        line = slash_conv_re.sub(replace_slash, line)`
`-        line = nice_conv_re.sub(replace_conv, line)`
`-        line = nice_assign_re.sub(replace_assign, line)`
`+        if not continue_prompt:`
`+            line = slash_conv_re.sub(replace_slash, line)`
`+            line = nice_assign_re.sub(replace_assign, line)`
`         return line`
` `
` def Q(v):`
`-    try:`
`-        return PhysicalQuantity(v)`
`-    except NameError:`
`-        raise ValueError('invalid unit %r' % v)`
`-`
`-def in_magic(shell, arg):`
`-    sys.displayhook(shell.ev('_.inUnitsOf(%r)' % str(arg)))`
`+    try: return PhysicalQuantity(v)`
`+    except NameError: raise ValueError('invalid unit in %r' % v)`
` `
` def tbl_magic(shell, arg):`
`     """tbl <expr>: Evaluate <expr> for a range of parameters, given`
`     if match:`
`         arg = arg[:match.start()]`
`         unit = match.group(1)`
`-    substs = set(subst_re.findall(arg))`
`+    substs = sorted(set(subst_re.findall(arg)))`
`     if not substs:`
`         raise ValueError('no substitutions in expr')`
`     while 1:`
`         shell.run_cell(expr, False)`
` `
` # monkey-patch a little`
`-PREC = [8]`
`+global_precision = [8]`
` PhysicalQuantity.__str__ = \`
`-    lambda self: '%.*g %s' % (PREC[0], self.value,`
`+    lambda self: '%.*g %s' % (global_precision[0], self.value,`
`                               self.unit.name().replace('**', '^'))`
` PhysicalQuantity.__repr__ = PhysicalQuantity.__str__`
` PhysicalQuantity.__truediv__ = PhysicalQuantity.__div__`
` ip.user_ns['Q'] = Q`
` ip.prefilter_manager.register_transformer(QTransformer())`
` # setter for custom precision`
`-ip.user_ns['setprec'] = lambda p: PREC.__setitem__(0, p)`
`-# quick converter`
`-ip.define_magic('in', in_magic)`
`+ip.user_ns['setprec'] = lambda p: global_precision.__setitem__(0, p)`
` # quick evaluator`
` ip.define_magic('tbl', tbl_magic)`
` `
` ip.user_ns['NA'] = Q('6.0221367e23 1/mol')`
` ip.user_ns['kb'] = Q('1.380658e-23 J/K')`
` `
`+# essential units :)`
`+_addUnit('furlong', '201.168*m', 'furlongs')`
`+_addUnit('fortnight', '1209600*s', '14 days')`
`+`
` print`
` print 'Unit calculation and physics extensions activated.'`