https://github.com/bindreams/calc
https://github.com/bindreams/calc
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/bindreams/calc
- Owner: bindreams
- Created: 2021-08-22T03:10:17.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2025-03-07T15:25:54.000Z (about 1 year ago)
- Last Synced: 2025-03-07T16:27:47.671Z (about 1 year ago)
- Language: Python
- Size: 10.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 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
```python
>>> 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:
```python
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`.