Skip to content

bindreams/calc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Calc

Evaluate simple mathematical expressions.

Installation

Calc is not available on PyPI, but can directly installed like this:

pip install https://github.com/andreasxp/calc/archive/refs/heads/main.zip

Examples

    >>> calc("2 + 2")
    4
    >>> calc("x^3", {"x": 1.25})
    1.953125
    >>> import math
    >>> calc("sin(pi/2)", {
    ...     "sin": math.sin,
    ...     "pi": math.pi
    ... })
    1.0

Usage

The main interface to this module is the calc function. Somewhat like eval, you can pass a string containing a mathematical expression to evaluate. Unlike builtins.eval, calc is completely safe - it supports only the operators, variables and functions you specify, and is confined to a simple set of grammar rules.

Known variables and functions can be added in the identifiers parameter. Additionally, you can specify custom unary and binary operators.
identifiers: a dict with entries {name: function or variable} - function or variable name, matched to the actual function to call or a value.
unary_operators: a dict with entries {(token, "prefix"/"postfix"): function} - a prefix/postfix token (!, -, +, ~, etc.) mapped to a function taking one argument. Postfix operators are executed before prefix operators.
binary_operators: a dict with entries {(token, precedence[, "lr"/"rl"]): function} - a token with a precedence controlling order of operations (lower number is higher precedence), optionally with right-to-left or left-to-right order of operations specified. For example, power operator ^ would be right-to-left and highest precedence, so it could be specified as ("^", 1, "rl"): lambda x, y: x**y.

An example of these parameters can be imported from this module:

default_unary_operators = {
    ("-", "prefix"): lambda x: -x,
    ("+", "prefix"): lambda x: x
}

default_binary_operators = {
    ("+", 3): operator.add,
    ("-", 3): operator.sub,
    ("*", 2): operator.mul,
    ("/", 2): operator.truediv,
    ("%", 2): math.remainder,
    ("^", 1, "rl"): operator.pow,
}

default_identifiers = {
    "min": min,
    "max": max,
    "floor": math.floor,
    "ceil": math.ceil,
    "round": round,
    "clamp": lambda val, low, high: min(max(low, val), high),
    "sin": math.sin,
    "cos": math.cos,
    "tan": math.tan,
    "asin": math.asin,
    "acos": math.acos,
    "atan": math.atan,
    "atan2": math.atan2,
}

If you need to customize the set of operators, but don't change them afterwards, it may be more efficient to create a Evaluator(unary_operators, binary_operators) instance, and use evaluator.calc(identifiers) instead of module-level calc.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages