=================================================================================== Unum Change Log =================================================================================== Changes in v4.1: - To support Python 2.5 and higher, the method Unum.as was renamed to Unum.asUnit; this was necessary since "as" became a reserved word. If you are still using old versions of Python, both names are available. - In addition to unit names in uppercase, unit names in the correct case are now available. So, both "kg" and "KG" refer to the kilogram Unum, and both "eV" and "EV" refer to the electron volt Unum. - Value types are no longer automatically coerced to floats. This allows the fractions.Fraction standard library type to be used, but may introduce incompatibilities with old code from integer vs. floating point division. In Python 3.x there is no problem. - Prefixed versions of the 7 base SI units are supplied. So you can use "cm", "ns", "kA", "mK", "pmol", "Mcd", and "g" out of the box. - The licence became LGPL instead of GPL due to user requests. ----------------------------------------------------------------------------------- file : unum.py ver 4.0 ----------------------------------------------------------------------------------- Changes : * from ver 03.012 : - added GPL notice - functions 'unit', 'resetUnitConversion', 'coerceToUnum' become Unum's static methods (ubase.py changed accordingly) - use of augmented assignments in '__mul__', '__div__', '__pow__', 'matchUnits', 'strUnit' methods - use of booleans constants True and False for class attributes AUTO_NORM, UNIT_HIDE_EMPTY and for 'is_new' variable in 'normalize' method - new UNIT_SORTING parameter, used in 'strUnit' function, in order to sort the unit strings when displayed; this guarantees identical output across platforms or Python versions (non-regression tests) some test results hard-coded in utest.py have been updated accordingly - in '__init__', invert the test on 'conv' and exchange the then/else blocks accordingly - in 'asNumber', invert the test on 'other' and exchange the then/else blocks accordingly - in 'asNumber', remove the 'target' variable - Unum becomes a new-style class (inherits from 'object') - the 5 following points are entailed - in '__init__', call object.__init__(self) - remove '__coerce__' method - call to 'coerceToUnum' are now explicit for 'other' argument in '__add__', '__radd__', '__sub__', etc. - in 'coerceToUnum' method, remove the test 'type(value) is InstanceType' and the related import - in 'asNumber' : replace 'type(other) is InstanceType' by 'isinstance(other,Unum)' - in 'asNumber' : if no argument, then self is copied and normalized before getting the raw value (otherwise (M/CM).asNumber() returns 1.0 instead of 100.0) - in 'maxLevel' : replace 'max' variable by 'res' - in '__init__', 'as', 'asNumber', 'converted' : remove unusefull calls to 'str' function. - add new ERR_DUPLICATE error message, used if one attempt to create twice the same unit - in '__init__' : verify the unicity of units (message ERR_DUPLICATE) - in '__init__' : the 'conv' argument may be equal to 0 which means that a basic unit is defined; such unums are now put also in the _unitConversion dictionary, with a tuple (None,0) which means that there is no conversion and the level is 0. - in 'unit' : conv is 0 by default (instead of None), in respect to the previous change in '__init__' - in 'normalize', 'maxLevel', 'isConvertible' : updates due to the fact that '_unitConversion.has_key(...)' is now always true in respect to the previous change in '__init__' - remove '_BASIC' and '_NORMALIZED' class attributes; self._normal becomes a simple boolean - add 'fix' method to prevent implicit normalization - change 'converted' to avoid call to 'isConvertible' - remove 'isConvertible' method - in 'replaced', always return a new unum with a new unit dictionary - new 'copy' method, that copies the unit dictionary - 'checkNoUnit' and '__pow__' have no normalization side effect - in 'asNumber', use 'copy(True)' calls to get normalized copies - in 'matchUnits', use 'copy' method, remove unuseful copies of unit dictionaries - set 'ERR_PREFIX' to an empty string instead of "# UNUM ERROR : " - replace EXC_UNUM_ERROR (string exception) by DimensionError and UnumError (class exceptions); change all the raise statements accordingly; change utest.py and ucalc.py accordingly - reorganize the modules in packages - define __slots__ in Unum class; define __getstate__ and __setstate__ methods in order to keep the ability of pickling - replace '_unitConversion' by '_unitTable' - replace 'resetUnitConversion' by 'reset', add the 'unitTable' argument - streamline 'normalize', '__mul__', '__div__' methods by using 'get' on dictionaries (hence removing 'has_key()' calls) - in 'normalize' method, put a 'break' statement to avoid unnecessary comparisons of 'substitution' dictionaries - remove ERR_PREFIX class attribute and update the others ERR_... attributes accordingly - in 'unit' and '__init__' methods, add the argument 'name' to be able to associate a full name to units; this is stored as a third object in '_unitTable' tuples - in 'normalize' method, add 'forDisplay' boolean argument to prefer one single unit to no unit; in '__str__' method, 'normalize' is called with True; this solves the issue of displaying units like RAD or DEGREE * from ver 03.011 : - add new '__getitem__', '__setitem__', '__len__' methods - in '__init__', replace 'if conv:' by 'if conv is not None:' (no call to 'len()') - in 'asNumber', replace 'if other:' by 'if other is not None:' (no call to 'len()') - new 'coerceToUnum' function, called by '__coerce__' and '__setitem__' - in '__coerce__', calls 'coerceToUnum' function (factorisation) * from ver 03.01 : - normalization moved from '__pow__' to 'checkNoUnit' method (called by 'asNumber') * from ver 03.00 : - new 'unit' function to simplify definition of base units - new 'resetUnitConversion' function to clear unit conversion table - new UNIT_HIDE_EMPTY parameter to hide [] when no unit - change 'as' method, to avoid normalization of the target unit, e.g. J.as(W*H) - change ERR_EXP message - new import section, in order to import types.InstanceType - in __coerce__, use InstanceType instead of type(self) - new 'asNumber' method to get raw numbers from unums - implementation of '__float__', etc for integration with mathematical functions * from ver 02.01 : - remove LateUnum class (moved to ulate.py) - remove the 'ucoerce' method - remove 'undef' method - remove M2,MM2,... units - remove predefined unums (moved to ubase.py) - change argument order of __init__, unum's value default is 1.0 - remove unused 'max_level' class attribute - remove change history (moved to change_log.txt) - new method 'isConvertible' - replace method 'definition' by 'converted' (more flexible) - minor name changes - 'normalize' method returns self instead of nothing - the '__pow__' method normalizes the exponent before checking that it is unitless - in strUnit, exponent is always shown except if it is 1 - in strUnit, if UNIT_DIV_SEP is None then negative exponents are used - remove unused class variables ERR_UNKNOWN and ERR_DUPLICATE * from ver 02.00 : - improvements & corrections in doc strings / comments - 'checkUnit' replaced by 'matchUnits' - remove useless 'res' in __mul__ and __div__ - remove useless statement in __init__ * from ver 01.00 : - avoid useless copies of unit dictionaries - new class attribute 'NO_UNIT' to avoid copies of empty dicionaries - output message strings use '%s' to avoid concatenations - new class atribute : 'unitConversion', defined by a third argument of Unum constructor - new 'definition' method that returns the converted unum as defined in '_unitConversion' - 'checkUnit' method now does unit conversion trial - new 'normalize' method to simplify unit through conversions - bug corrrection in 'normalize' (2nd statemt : +self to make a copy) - new class attribute 'AUTO_NORM' to (des)activate normalization - new method __abs__ defined (overloading of abs() function) - method __cmp__ simplified - new method 'undef' to build unum with defined unit but undefined value - new 'LateUnum' class to define late-evaluated Unum expressions - new method 'ucoerce' required for LateUnum - new 'MILES' unit -----------------------------------------------------------------------------------