Skip to main content

A fast and secure mathematical expression evaluator.

Project description

Math Engine 0.5.0

PyPI Version License: MIT Python Versions

A fast, safe, configurable expression parser and calculator for Python.

math_engine is a powerful expression evaluation library designed for developers who need a safe, configurable, and extendable alternative to Python’s built-in eval() or other ad-hoc parsers.
It provides a complete pipeline:

  • Tokenizer
  • AST (Abstract Syntax Tree) parser
  • Evaluator (numeric + equation solver)
  • Formatter and type-safe output system
  • Support for decimal, integer, binary, octal, hexadecimal
  • Custom variables
  • Scientific functions
  • Strict error codes for reliable debugging and automated testing

This library is ideal for:

  • Developers building calculators, interpreters, scripting engines
  • Students learning compilers, math parsing, and ASTs
  • Security-sensitive applications where eval() is not acceptable
  • Anyone who needs equation solving, custom formats, and strict errors

Features

Core Features

  • Full AST-based expression parsing
  • Safe evaluation (no execution of Python code)
  • Decimal, Integer, Float, Boolean, Binary, Octal, Hexadecimal
  • Custom variables
  • Linear equation solving (x + 3 = 7)
  • Scientific functions: sin, cos, tan, log, sqrt, π, e^
  • Automatic format correction (correct_output_format)
  • Strong error handling with unique codes
  • Settings system with presets
  • Optional strict modes:
    • only_hex
    • only_binary
    • only_octal

Non-Decimal Support

  • Read binary 0b1101
  • Read octal 0o755
  • Read hexadecimal 0xFF
  • Convert results into binary/hex/octal format
  • Enforce only-hex/only-binary/only-octal mode
  • Prefix parsing (hex:, bin:, int:, str: ...)

Installation

pip install math-engine

Command Line Interface (CLI)

Math Engine works directly from your terminal! After installing via pip, you can use the command math-engine (or the short alias calc).

1. Interactive Mode (REPL)

Start the shell to calculate, manage variables, and change settings dynamically.

$ math-engine

Math Engine 0.4.0 Interactive Shell
Type 'help' for commands, 'exit' to leave.
----------------------------------------
Examples:
  >>> 3 + 3 * 4 
  15
  
  >>> hex: 255
  0xff
  
  >>> x + 5, x=10    (Inline Variables)
  15
  
  >>> set setting word_size 8
  Setting updated: word_size -> 8

2. Direct Calculation

You can also pass expressions directly (great for scripting):

$ math-engine "3 + 3"
6

$ math-engine "hex: 255"
0xff

Quick Start

Basic Evaluation

import math_engine

math_engine.evaluate("2 + 2")
# Decimal('4')

Different Output Formats

math_engine.evaluate("hex: 255")
# '0xff'

math_engine.evaluate("binary: 13")
# '0b1101'

math_engine.evaluate("octal: 64")
# '0o100'

Automatic Format Correction

import math_engine

settings = math_engine.load_all_settings()
settings["correct_output_format"] = True
math_engine.load_preset(settings)

math_engine.evaluate("bool: 3+3=6")
# True

Reset all Settings to Default

import math_engine

math_engine.reset_settings()

If a requested output type does not match the actual result, correct_output_format=True allows math_engine to fall back to a compatible type instead of raising an error.


Prefix System (Casting Syntax)

math_engine supports a powerful prefix-based casting system:

Prefix Meaning Example
dec: Decimal dec: 3/21.50
int: Integer int: 10/3 → error if non-integer
float: Float float: 1/3
bool: Boolean bool: 3 = 3
hex: Hexadecimal hex: 15
bin: Binary bin: 5
oct: Octal oct: 64
str: String str: 3+3"6"

Example:

math_engine.evaluate("hex: 3 + 3")
# '0x6'

Variables

vars = {
    "A": 10,
    "B": 5,
}

math_engine.evaluate("A + B", variables=vars)
# Decimal('15')

Alternatively, you can pass variables as keyword arguments:

math_engine.evaluate("A + B", A=10, B=5)
# Decimal('15')

Variables are mapped internally to a safe internal representation and are designed to be simple and predictable.


Scientific Functions

math_engine.evaluate("sin(30)")
math_engine.evaluate("cos(90)")
math_engine.evaluate("log(100,10)")
math_engine.evaluate("√(16)")
math_engine.evaluate("pi * 2")

All functions are processed by the internal ScientificEngine, honoring your settings (for example, use_degrees).


Linear Equation Solver

math_engine.evaluate("x + 3 = 10")
# Decimal('7')

Invalid or nonlinear equations produce errors with codes like:

  • 3005 – Non-linear equation
  • 3002 – Multiple variables
  • 3022 – One side empty

Non-Decimal Numbers (Binary, Octal, Hex)

math_engine.evaluate("0xFF + 3")
# Decimal('258')

math_engine.evaluate("0b1010 * 3")
# Decimal('30')

Non-decimal parsing respects the setting allow_non_decimal. If it is set to False, using 0b, 0o, or 0x will raise a conversion error.


Bitwise Operations & Developer Mode (v0.5.0)

Math Engine can act as a programmer's calculator. It supports standard operator precedence and bitwise logic.

New Operators

Operator Description Example Result
& Bitwise AND 3 & 1 1
| Bitwise OR 1 | 2 3
^ Bitwise XOR 3 ^ 1 2
<< Left Shift 1 << 2 4
>> Right Shift 8 >> 2 2
** Power 2 ** 3 8

Note: Since ^ is used for XOR, use ** for exponentiation (power).

Word Size & Overflow Simulation

You can simulate hardware constraints (like C++ int8, uint16, etc.) by setting a word_size.

  • word_size: 0 (Default): Python mode (arbitrary precision, no overflow).
  • word_size: 8/16/32/64: Enforces bit limits. Numbers will wrap around (overflow) accordingly.

Signed vs. Unsigned Mode

When word_size > 0, you can control how values are interpreted via signed_mode:

  • True (Default): Use Two's Complement for negative values.
  • False: Treat all values as unsigned.

Example: 8-bit Simulation

import math_engine

settings = math_engine.load_all_settings()
settings["word_size"] = 8
settings["signed_mode"] = True
math_engine.load_preset(settings)

math_engine.evaluate("127 + 1")
# In 8-bit signed arithmetic this overflows to -128
# Decimal('-128')

Hex output respects the current word size and signedness:

math_engine.evaluate("hex: -1")
# Hex representation consistent with word_size / signed_mode configuration

Force-only-hex Mode

settings = math_engine.load_all_settings()
settings["only_hex"] = True
math_engine.load_preset(settings)

math_engine.evaluate("FF + 3")
# Decimal('258')

Input validation ensures safety and prevents mixing incompatible formats in strict modes.


Bitwise & Low-Level Operations

Math Engine now includes a rich collection of low-level bit manipulation functions commonly used in systems programming, embedded development, cryptography, and hardware-oriented tools.

Bitwise functions:

  • bitand(x, y) — bitwise AND
  • bitor(x, y) — bitwise OR
  • bitxor(x, y) — bitwise XOR
  • bitnot(x) — bitwise NOT

Bit manipulation utilities:

  • setbit(x, n) — sets bit n
  • clrbit(x, n) — clears bit n
  • togbit(x, n) — toggles bit n
  • testbit(x, n) — returns 1 if bit n is set, else 0

Shift operations:

  • shl(x, n) — logical left shift
  • shr(x, n) — logical right shift

All bitwise functions:

  • respect word_size and signed_mode
  • support overflow/wrap-around behavior
  • fully support binary, hex, decimal, and octal inputs
  • participate in the AST just like standard operators
  • support underscores in non-decimal literals (0b1111_0000)

This makes Math Engine behave like a full-featured programmer’s calculator with CPU-like precision control.


Settings System

You can inspect and modify settings programmatically.

Load Current Settings

import math_engine

settings = math_engine.load_all_settings()
print(settings)

Apply a Full Preset

This is a plain Python dict (not JSON):

preset = {
    "decimal_places": 2,
    "use_degrees": False,
    "allow_augmented_assignment": True,
    "fractions": False,
    "allow_non_decimal": True,
    "debug": False,
    "correct_output_format": True,
    "default_output_format": "decimal:",
    "only_hex": False,
    "only_binary": False,
    "only_octal": False,
    # New in 0.3.0
    "word_size": 0,        # 0 = unlimited, or 8, 16, 32, 64
    "signed_mode": True,   # True = Two's Complement, False = Unsigned
}

math_engine.load_preset(preset)

Change a Single Setting

math_engine.change_setting("decimal_places", 10)

You can also read a single setting:

decimal_places = math_engine.load_one_setting("decimal_places")

Error Handling

Every error is a custom exception with:

  • Human-readable message
  • Machine-readable error code
  • Position (if applicable)
  • The original expression

Example:

import math_engine
from math_engine import error as E

try:
    math_engine.evaluate("1/0")
except E.CalculationError as e:
    print(e.code)      # 3003
    print(e.message)   # "Division by zero"
    print(e.equation)  # "1/0"

Example Error Codes

Code Meaning
3003 Division by zero
3034 Empty input
3036 Multiple = signs
3032 Multiple-character variable
8000 Conversion to int failed
8006 Output conversion error

For a complete list of all error codes and their meanings, please see the Error Codes Reference.


Testing and Reliability

math_engine is designed with testing in mind:

  • Full error-code consistency
  • Strict syntax rules
  • Unit-test friendly behavior
  • No reliance on Python’s runtime execution

Example with pytest:

import pytest
import math_engine
from math_engine import error as E

def test_division_by_zero_error_code():
    with pytest.raises(E.CalculationError) as exc:
        math_engine.evaluate("1/0")
    assert exc.value.code == "3003"

You can also test more advanced behavior (non-decimal, strict modes, bitwise operations, etc.) in the same way.


Performance

  • No use of Python eval()
  • Predictable performance through AST evaluation
  • Optimized tokenization
  • Fast conversion of non-decimal numbers

Future updates focus on:

  • Expression caching
  • Compiler-like optimizations
  • Faster scientific evaluation

Use Cases

Calculator Applications

Build full scientific or programmer calculators, both GUI and command line.

Education

Great for learning about lexers, parsers, ASTs, and expression evaluation.

Embedded Scripting

Safe math evaluation inside larger apps.

Security-Sensitive Input

Rejects arbitrary Python code and ensures controlled evaluation.

Data Processing

Conversion between hex/bin/decimal is easy and reliable.


Roadmap (Future Versions)

  • Non-decimal output formatting upgrades
  • Strict type-matching modes
  • Function overloading
  • Memory/register system
  • Speed optimization via caching
  • User-defined functions
  • Expression pre-compilation
  • Better debugging output

Changelog

See CHANGELOG.md for details.


License

MIT License


Contributing

Contributions are welcome. Feel free to submit issues or PRs on GitHub:

https://github.com/JanTeske06/math_engine


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

math_engine-0.5.0.tar.gz (36.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

math_engine-0.5.0-py3-none-any.whl (35.7 kB view details)

Uploaded Python 3

File details

Details for the file math_engine-0.5.0.tar.gz.

File metadata

  • Download URL: math_engine-0.5.0.tar.gz
  • Upload date:
  • Size: 36.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.10

File hashes

Hashes for math_engine-0.5.0.tar.gz
Algorithm Hash digest
SHA256 a624d461fe89651ae85dc5ce99007c2b360f7fdd329e1668a6a0abcb4f877075
MD5 0fb6132f13611ff439682378052bf225
BLAKE2b-256 37dce348d540ed9a00f658a3c729aa51250ba2a2ade8b7245073142eb8d1253d

See more details on using hashes here.

File details

Details for the file math_engine-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: math_engine-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 35.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.10

File hashes

Hashes for math_engine-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1964b1e143486c07110e81db150a82e367a8d907af3e7935f403bd933f86e028
MD5 95c1bcc19a57dc12703da551dbf6b665
BLAKE2b-256 7e93b5e7682937044a797b2d17dddccd1b2e599998ddf921267a6cad0bdde7d6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page