====================== ``grail.ucalc`` module ====================== .. include:: ..\version.h .. include:: ..\Library_Reference\lib-reference.h .. contents:: Table of Contents :backlinks: top -------- Overview -------- Allows composition and evaluations of tokenized expressions. With this module you can compose an expression and do repeated evaluations with the same expression. -------------------------- How the ucalc Module Works -------------------------- As a simple example, consider the following expression, .. Python:: expression = "$(eq)=$(CU)*.12" In this expression we are setting two tokens, :a:`$(EQ)` and :a:`$(CU)`. The :a:`$(xx)` represents a *token variable* that will be substituted with values. Lets continue with our example and substitute a value for CU, .. Python:: values = {"cu":10} variable, value = ucalc.calculate(expression, **values) At this point :a:`variable` will be equal to :a:`EQ`, and value will be equal to :a:`1.2`. Notice that token substitution is case insensitive. In fact all calculations will be done in lower-case. The :f:`calculate` function is a convenience function for manipulating the :c:`StringExpr` class. The above example could have been re-written as, .. Python:: expression = "$(eq)=$(cu)*.12" values = {"cu":10} eqn = ucalc.StringExpr(expression) for item, num in values.items(): eqn.setvalue(item, num) variable = eqn.variable() value = eqn.evaluate() In this case there is more typing, but it is a bit more efficient when you have the same expression but varying values. For example consider, .. Python:: expression = "$(eq)=(cu)*.12" values = [1.2, 31.,2.3, 5.6] eqn = ucalc.StringExpr(expression) for value in values: eqn.setvalue("cu", value) value = eqn.evaluate() In the above example we can evaluate the number :a:`1.2`, :a:`31.0`, :a:`2.3`, and :a:`5.6` on the same :c:`StringExpr` object. This is slightly faster than using the convenience :f:`calculate()` function, which would have to needless reconstruct the expression for each value that is being evaluated. --------------------- Default function list --------------------- The :c:`StringExpr` comes with a the following set of default functions and constants, * :f:`acos` * :f:`asin` * :f:`atan` * :f:`atan2` * :f:`ceil` * :f:`cos` * :f:`cosh` * :f:`e` * :f:`exp` * :f:`fabs` * :f:`floor` * :f:`fmod` * :f:`frexp` * :f:`hypot` * :f:`int` * :f:`ldexp` * :f:`log` * :f:`log10` * :f:`max` * :f:`min` * :f:`modf` * :f:`pi` * :f:`pow` * :f:`sin` * :f:`sinh` * :f:`sqrt` * :f:`tan` * :f:`tanhi` Most of the above functions and constants come from the python math library [#python-lib-math]_. The remaining functions come from Python's built-in library [#python-lib-builtin]_. ------------------------- Creating Custom Functions ------------------------- If you wish to add your own custom function to the above list, or override an existing function you can do it via the :f:`StringExpr.setfunction()` method. For example, say you have derived a much better :f:`tan()` function that you would like to use instead. Then you can do the following, .. Python:: def mytan(x): return # ... my much better tangent calculation! eqn = ucalc.StringExpr("$(eq)=tan($(a))") eqn.setvalue("a", .2) eqn.setfunction("tan", mytan) value = eqn.evaluate() In this way you have complete flexibility when using the :c:`StringExpr`. ---------------------- The calculate Function ---------------------- :df:`calculate(expression[,values])` Simplified expression calculation routine. You can use the dictionary like behavior of :a:`values` to set your expression values. This can be done in two ways, .. Python:: values = {"cu":12., "moly":.2} eqn = ucalc.calculate("$(eq)=.2*$(cu)+12.3*$(moly)", **values) or, .. Python:: eqn = ucalc.calculate("$(eq)=.2*$(cu)+12.3*$(moly)", cu=12., moly=.2) In reality you would utilize the first example most often. Arguments: :a:`expression` : string Expression you wish to evaluate. :a:`values` : variable dictionary Dictionary keywords for the values you wish to evaluate. -------------------- The StringExpr Class -------------------- class :dc:`StringExpr(expression [, funcmap])` Simple string expression and evaluation class. See `How the ucalc Module Works`_ for examples of using this class. Arguments: :a:`expression` : string Expression you wish to evaluate (must have a left-hand side). :a:`funcmap` : dictionary Name-function pairs that are used during evaluation. This defaults to the :d:`DEFAULT_FUNCTION_MAP`. :a:`values` : variable dictionary Optionally specify the values to calculate (see :f:`ucalc.calculate()` for an example). :df:`evaluate()` Substitutes and evaluates the expression. Returns: The result of calling :f:`eval()` [#python-lib-builtin]_ with the function map and the name-value pairs substituted. :df:`setfunction(name, function)` Allows extension or overriding of a function. Argument: :a:`name` : string Name of the function (as it should appear in the expression). :a:`function` : function Python function that is used when the name is encountered in the expression. :df:`setvalue(name, value)` Set the name-value pair for evaluation. Overrides previous name-value pair (see `How the ucalc Module Works`_ for some examples) Arguments: :a:`name` : string Name of the variable (for example, "CU" for replacing $(cu) in an expression). :a:`value` : The value you want to replace during evaluation. :df:`strrhs()` Returns the right-hand side after variable substitutions. For example, if your expression is, .. Python:: "$(EQ)=$(A)*$(B)" And you substituted A with 5 and B with 10, then this function would return, .. Python:: "5*10". :df:`variable() unbound StringExpr method` Returns the value of the left-hand side of the expression. For example, if the expression was, :: "$(a) = $(b)**2 + $(c)**2" This method would return the string: "a". Returns: The value on the left-hand side of the expression. ---- Data ---- :dd:`DEFAULT_FUNCTION_MAP` Dictionary of name-function pairs that will be used during expression evaluation. --------- Exception --------- exception :de:`UcalcError` Error for this module. ---------- References ---------- .. [#python-lib-builtin] "Built-in Functions". *Python Library Reference*. 21 December 2001. 12 January 2017. .. [#python-lib-math] "math -- Mathematical functions". *Python Library Reference*. 21 December 2001. 12 January 2017.