math-engine 0.3.0__tar.gz → 0.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: math-engine
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: A fast and secure mathematical expression evaluator.
5
5
  Author-email: Jan Teske <jan.teske.06@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/JanTeske06/math_engine
@@ -12,18 +12,18 @@ Requires-Python: >=3.8
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
 
15
- # Math Engine 0.3.0
15
+
16
+ # Math Engine 0.3.2
16
17
 
17
18
  [![PyPI Version](https://img.shields.io/pypi/v/math-engine.svg)](https://pypi.org/project/math-engine/)
18
19
  [![License: MIT](https://img.shields.io/pypi/l/math-engine.svg)](https://opensource.org/licenses/MIT)
19
20
  [![Python Versions](https://img.shields.io/pypi/pyversions/math-engine.svg)](https://pypi.org/project/math-engine/)
20
21
 
21
- A fast, safe, configurable expression parser and calculator for Python
22
+ A fast, safe, configurable expression parser and calculator for Python.
22
23
 
23
- **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.
24
+ **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.
24
25
  It provides a complete pipeline:
25
26
 
26
-
27
27
  * Tokenizer
28
28
  * AST (Abstract Syntax Tree) parser
29
29
  * Evaluator (numeric + equation solver)
@@ -33,7 +33,7 @@ It provides a complete pipeline:
33
33
  * Scientific functions
34
34
  * Strict error codes for reliable debugging and automated testing
35
35
 
36
- **Version 0.2.1** adds extensive non-decimal number support (hex, binary, octal), prefix-based type casting, improved settings management, and expanded error reporting.
36
+ **Version _0.3.2_** adds extensive non-decimal number support (hex, binary, octal), prefix-based type casting, improved settings management, expanded error reporting, and an optional programmer mode with bitwise operations and word-size simulation.
37
37
 
38
38
  This library is ideal for:
39
39
 
@@ -58,12 +58,11 @@ This library is ideal for:
58
58
  * Strong error handling with unique codes
59
59
  * Settings system with presets
60
60
  * Optional strict modes:
61
-
62
61
  * `only_hex`
63
62
  * `only_binary`
64
63
  * `only_octal`
65
64
 
66
- ### Non-Decimal Support (0.2.1)
65
+ ### Non-Decimal Support (0.2.1)
67
66
 
68
67
  * Read binary `0b1101`
69
68
  * Read octal `0o755`
@@ -76,9 +75,9 @@ This library is ideal for:
76
75
 
77
76
  # Installation
78
77
 
79
- ```
78
+ ```bash
80
79
  pip install math-engine
81
- ```
80
+ ````
82
81
 
83
82
  ---
84
83
 
@@ -109,11 +108,27 @@ math_engine.evaluate("octal: 64")
109
108
  ## Automatic Format Correction
110
109
 
111
110
  ```python
112
- math_engine.load_preset({"correct_output_format": True})
113
- math_engine.evaluate("boolean: 3+3=6")
111
+ import math_engine
112
+
113
+ settings = math_engine.load_all_settings()
114
+ settings["correct_output_format"] = True
115
+ math_engine.load_preset(settings)
116
+
117
+ math_engine.evaluate("bool: 3+3=6")
114
118
  # True
115
119
  ```
116
120
 
121
+ ## Reset all Settings to Default
122
+
123
+ ```python
124
+ import math_engine
125
+
126
+ reset_settings()
127
+ ```
128
+
129
+
130
+ 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.
131
+
117
132
  ---
118
133
 
119
134
  # Prefix System (Casting Syntax)
@@ -145,14 +160,21 @@ math_engine.evaluate("hex: 3 + 3")
145
160
  ```python
146
161
  vars = {
147
162
  "A": 10,
148
- "B": 5
163
+ "B": 5,
149
164
  }
150
165
 
151
- math_engine.evaluate("A + B", custom_variables=vars)
166
+ math_engine.evaluate("A + B", variables=vars)
167
+ # Decimal('15')
168
+ ```
169
+
170
+ Alternatively, you can pass variables as keyword arguments:
171
+
172
+ ```python
173
+ math_engine.evaluate("A + B", A=10, B=5)
152
174
  # Decimal('15')
153
175
  ```
154
176
 
155
- Variables must be single characters (to enforce safety and keep parsing simple).
177
+ Variables are mapped internally to a safe internal representation and are designed to be simple and predictable.
156
178
 
157
179
  ---
158
180
 
@@ -166,7 +188,7 @@ math_engine.evaluate("√(16)")
166
188
  math_engine.evaluate("pi * 2")
167
189
  ```
168
190
 
169
- All functions are processed by the internal ScientificEngine.
191
+ All functions are processed by the internal `ScientificEngine`, honoring your settings (for example, `use_degrees`).
170
192
 
171
193
  ---
172
194
 
@@ -195,58 +217,64 @@ math_engine.evaluate("0b1010 * 3")
195
217
  # Decimal('30')
196
218
  ```
197
219
 
198
- # Bitwise Operations & Developer Mode (v0.3.0)
220
+ 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.
221
+
222
+ ---
223
+
224
+ # Bitwise Operations & Developer Mode (v0.3.x)
199
225
 
200
- Math Engine now acts as a fully functional **Programmer's Calculator**. It supports standard Python operator precedence and bitwise logic.
226
+ Math Engine can act as a **programmer's calculator**. It supports standard operator precedence and bitwise logic.
201
227
 
202
228
  ### New Operators
203
229
 
204
- | Operator | Description | Example | Result |
205
- | :--- | :--- | :--- | :--- |
206
- | `&` | Bitwise AND | `3 & 1` | `1` |
207
- | `\|` | Bitwise OR | `1 \| 2` | `3` |
208
- | `^` | Bitwise XOR | `3 ^ 1` | `2` |
209
- | `<<` | Left Shift | `1 << 2` | `4` |
210
- | `>>` | Right Shift | `8 >> 2` | `2` |
211
- | `**` | Power | `2 ** 3` | `8` |
230
+ | Operator | Description | Example | Result |
231
+ | :------- | :---------- | :------- | :----- |
232
+ | `&` | Bitwise AND | `3 & 1` | `1` |
233
+ | `\|` | Bitwise OR | `1 \| 2` | `3` |
234
+ | `^` | Bitwise XOR | `3 ^ 1` | `2` |
235
+ | `<<` | Left Shift | `1 << 2` | `4` |
236
+ | `>>` | Right Shift | `8 >> 2` | `2` |
237
+ | `**` | Power | `2 ** 3` | `8` |
212
238
 
213
- > **Note:** Since `^` is now used for **XOR**, use `**` for exponentiation (power).
239
+ > Note: Since `^` is used for **XOR**, use `**` for exponentiation (power).
214
240
 
215
241
  ### Word Size & Overflow Simulation
216
242
 
217
243
  You can simulate hardware constraints (like C++ `int8`, `uint16`, etc.) by setting a `word_size`.
218
244
 
219
- * **`word_size: 0` (Default):** Python mode (Arbitrary precision, no overflow).
220
- * **`word_size: 8/16/32/64`:** Enforces bit limits. Numbers will wrap around (overflow).
245
+ * **`word_size: 0` (Default):** Python mode (arbitrary precision, no overflow).
246
+ * **`word_size: 8/16/32/64`:** Enforces bit limits. Numbers will wrap around (overflow) accordingly.
221
247
 
222
248
  ### Signed vs. Unsigned Mode
223
249
 
224
- When `word_size > 0`, you can toggle how binary data is interpreted using `signed_mode`.
250
+ When `word_size > 0`, you can control how values are interpreted via `signed_mode`:
225
251
 
226
- * **`True` (Default):** Uses **Two's Complement**. The highest bit indicates a negative number.
227
- * **`False`:** Strictly positive numbers (Unsigned).
252
+ * **`True` (Default):** Use **Two's Complement** for negative values.
253
+ * **`False`:** Treat all values as unsigned.
228
254
 
229
- **Example: 8-Bit Simulation**
255
+ **Example: 8-bit Simulation**
230
256
 
231
257
  ```python
232
- # Setup: 8-Bit Signed Mode
233
- settings = {
234
- "word_size": 8,
235
- "signed_mode": True
236
- }
258
+ import math_engine
259
+
260
+ settings = math_engine.load_all_settings()
261
+ settings["word_size"] = 8
262
+ settings["signed_mode"] = True
237
263
  math_engine.load_preset(settings)
238
264
 
239
- # Calculation: 127 + 1
240
- # Mathematically 128, but in 8-bit signed this overflows to -128.
241
265
  math_engine.evaluate("127 + 1")
266
+ # In 8-bit signed arithmetic this overflows to -128
242
267
  # Decimal('-128')
268
+ ```
243
269
 
244
- # Calculation: -1 in Hex
245
- # In 8-bit two's complement, -1 is represented as FF.
270
+ Hex output respects the current word size and signedness:
271
+
272
+ ```python
246
273
  math_engine.evaluate("hex: -1")
247
- # '-0x1' (Value is masked internally to 255)
274
+ # Hex representation consistent with word_size / signed_mode configuration
248
275
  ```
249
- ### Force-only-hex mode
276
+
277
+ ### Force-only-hex Mode
250
278
 
251
279
  ```python
252
280
  settings = math_engine.load_all_settings()
@@ -257,39 +285,58 @@ math_engine.evaluate("FF + 3")
257
285
  # Decimal('258')
258
286
  ```
259
287
 
260
- Input validation ensures safety.
288
+ Input validation ensures safety and prevents mixing incompatible formats in strict modes.
261
289
 
262
290
  ---
263
291
 
264
292
  # Settings System
265
293
 
266
- You may load presets:
294
+ You can inspect and modify settings programmatically.
295
+
296
+ ### Load Current Settings
297
+
298
+ ```python
299
+ import math_engine
300
+
301
+ settings = math_engine.load_all_settings()
302
+ print(settings)
303
+ ```
304
+
305
+ ### Apply a Full Preset
306
+
307
+ This is a plain Python `dict` (not JSON):
267
308
 
268
309
  ```python
269
310
  preset = {
270
311
  "decimal_places": 2,
271
- "use_degrees": false,
272
- "allow_augmented_assignment": true,
273
- "fractions": false,
274
- "allow_non_decimal": true,
275
- "debug": false,
276
- "correct_output_format": true,
312
+ "use_degrees": False,
313
+ "allow_augmented_assignment": True,
314
+ "fractions": False,
315
+ "allow_non_decimal": True,
316
+ "debug": False,
317
+ "correct_output_format": True,
277
318
  "default_output_format": "decimal:",
278
- "only_hex": false,
279
- "only_binary": false,
280
- "only_octal": false,
281
- # New in v0.3.0
282
- "word_size": 0, # 0 = Unlimited, or 8, 16, 32, 64
283
- "signed_mode": true, # True = Two's Complement, False = Unsigned
319
+ "only_hex": False,
320
+ "only_binary": False,
321
+ "only_octal": False,
322
+ # New in 0.3.0
323
+ "word_size": 0, # 0 = unlimited, or 8, 16, 32, 64
324
+ "signed_mode": True, # True = Two's Complement, False = Unsigned
284
325
  }
285
326
 
286
327
  math_engine.load_preset(preset)
287
328
  ```
288
329
 
289
- Or modify single settings:
330
+ ### Change a Single Setting
290
331
 
291
332
  ```python
292
- math_engine.save_setting("decimal_places", 10)
333
+ math_engine.change_setting("decimal_places", 10)
334
+ ```
335
+
336
+ You can also read a single setting:
337
+
338
+ ```python
339
+ decimal_places = math_engine.load_one_setting("decimal_places")
293
340
  ```
294
341
 
295
342
  ---
@@ -306,10 +353,15 @@ Every error is a custom exception with:
306
353
  Example:
307
354
 
308
355
  ```python
356
+ import math_engine
357
+ from math_engine import error as E
358
+
309
359
  try:
310
360
  math_engine.evaluate("1/0")
311
- except math_engine.error.CalculationError as e:
312
- print(e.code) # 3003
361
+ except E.CalculationError as e:
362
+ print(e.code) # 3003
363
+ print(e.message) # "Division by zero"
364
+ print(e.equation) # "1/0"
313
365
  ```
314
366
 
315
367
  ### Example Error Codes
@@ -323,6 +375,9 @@ except math_engine.error.CalculationError as e:
323
375
  | 8000 | Conversion to int failed |
324
376
  | 8006 | Output conversion error |
325
377
 
378
+ For a complete list of all error codes and their meanings, please see the **[Error Codes Reference](https://github.com/JanTeske06/math_engine/blob/master/ERRORS.md)**.
379
+
380
+ ---
326
381
  ---
327
382
 
328
383
  # Testing and Reliability
@@ -334,18 +389,21 @@ math_engine is designed with testing in mind:
334
389
  * Unit-test friendly behavior
335
390
  * No reliance on Python’s runtime execution
336
391
 
337
- You can easily test error codes:
392
+ Example with `pytest`:
338
393
 
339
394
  ```python
340
395
  import pytest
396
+ import math_engine
341
397
  from math_engine import error as E
342
398
 
343
- def test_div_zero():
399
+ def test_division_by_zero_error_code():
344
400
  with pytest.raises(E.CalculationError) as exc:
345
401
  math_engine.evaluate("1/0")
346
402
  assert exc.value.code == "3003"
347
403
  ```
348
404
 
405
+ You can also test more advanced behavior (non-decimal, strict modes, bitwise operations, etc.) in the same way.
406
+
349
407
  ---
350
408
 
351
409
  # Performance
@@ -367,7 +425,7 @@ Future updates focus on:
367
425
 
368
426
  ### Calculator Applications
369
427
 
370
- Build full scientific calculators, both GUI and command line.
428
+ Build full scientific or programmer calculators, both GUI and command line.
371
429
 
372
430
  ### Education
373
431
 
@@ -377,7 +435,7 @@ Great for learning about lexers, parsers, ASTs, and expression evaluation.
377
435
 
378
436
  Safe math evaluation inside larger apps.
379
437
 
380
- ### Security-sensitive Input
438
+ ### Security-Sensitive Input
381
439
 
382
440
  Rejects arbitrary Python code and ensures controlled evaluation.
383
441
 
@@ -392,7 +450,6 @@ Conversion between hex/bin/decimal is easy and reliable.
392
450
  * Non-decimal output formatting upgrades
393
451
  * Strict type-matching modes
394
452
  * Function overloading
395
- * Bitwise operators (`&`, `|`, `^`, `<<`, `>>`)
396
453
  * Memory/register system
397
454
  * Speed optimization via caching
398
455
  * User-defined functions
@@ -412,9 +469,6 @@ MIT License
412
469
  Contributions are welcome.
413
470
  Feel free to submit issues or PRs on GitHub:
414
471
 
415
- ```
472
+ ```text
416
473
  https://github.com/JanTeske06/math_engine
417
474
  ```
418
-
419
- ---
420
-
@@ -1,15 +1,15 @@
1
- # Math Engine 0.3.0
1
+
2
+ # Math Engine 0.3.2
2
3
 
3
4
  [![PyPI Version](https://img.shields.io/pypi/v/math-engine.svg)](https://pypi.org/project/math-engine/)
4
5
  [![License: MIT](https://img.shields.io/pypi/l/math-engine.svg)](https://opensource.org/licenses/MIT)
5
6
  [![Python Versions](https://img.shields.io/pypi/pyversions/math-engine.svg)](https://pypi.org/project/math-engine/)
6
7
 
7
- A fast, safe, configurable expression parser and calculator for Python
8
+ A fast, safe, configurable expression parser and calculator for Python.
8
9
 
9
- **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.
10
+ **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.
10
11
  It provides a complete pipeline:
11
12
 
12
-
13
13
  * Tokenizer
14
14
  * AST (Abstract Syntax Tree) parser
15
15
  * Evaluator (numeric + equation solver)
@@ -19,7 +19,7 @@ It provides a complete pipeline:
19
19
  * Scientific functions
20
20
  * Strict error codes for reliable debugging and automated testing
21
21
 
22
- **Version 0.2.1** adds extensive non-decimal number support (hex, binary, octal), prefix-based type casting, improved settings management, and expanded error reporting.
22
+ **Version _0.3.2_** adds extensive non-decimal number support (hex, binary, octal), prefix-based type casting, improved settings management, expanded error reporting, and an optional programmer mode with bitwise operations and word-size simulation.
23
23
 
24
24
  This library is ideal for:
25
25
 
@@ -44,12 +44,11 @@ This library is ideal for:
44
44
  * Strong error handling with unique codes
45
45
  * Settings system with presets
46
46
  * Optional strict modes:
47
-
48
47
  * `only_hex`
49
48
  * `only_binary`
50
49
  * `only_octal`
51
50
 
52
- ### Non-Decimal Support (0.2.1)
51
+ ### Non-Decimal Support (0.2.1)
53
52
 
54
53
  * Read binary `0b1101`
55
54
  * Read octal `0o755`
@@ -62,9 +61,9 @@ This library is ideal for:
62
61
 
63
62
  # Installation
64
63
 
65
- ```
64
+ ```bash
66
65
  pip install math-engine
67
- ```
66
+ ````
68
67
 
69
68
  ---
70
69
 
@@ -95,11 +94,27 @@ math_engine.evaluate("octal: 64")
95
94
  ## Automatic Format Correction
96
95
 
97
96
  ```python
98
- math_engine.load_preset({"correct_output_format": True})
99
- math_engine.evaluate("boolean: 3+3=6")
97
+ import math_engine
98
+
99
+ settings = math_engine.load_all_settings()
100
+ settings["correct_output_format"] = True
101
+ math_engine.load_preset(settings)
102
+
103
+ math_engine.evaluate("bool: 3+3=6")
100
104
  # True
101
105
  ```
102
106
 
107
+ ## Reset all Settings to Default
108
+
109
+ ```python
110
+ import math_engine
111
+
112
+ reset_settings()
113
+ ```
114
+
115
+
116
+ 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.
117
+
103
118
  ---
104
119
 
105
120
  # Prefix System (Casting Syntax)
@@ -131,14 +146,21 @@ math_engine.evaluate("hex: 3 + 3")
131
146
  ```python
132
147
  vars = {
133
148
  "A": 10,
134
- "B": 5
149
+ "B": 5,
135
150
  }
136
151
 
137
- math_engine.evaluate("A + B", custom_variables=vars)
152
+ math_engine.evaluate("A + B", variables=vars)
153
+ # Decimal('15')
154
+ ```
155
+
156
+ Alternatively, you can pass variables as keyword arguments:
157
+
158
+ ```python
159
+ math_engine.evaluate("A + B", A=10, B=5)
138
160
  # Decimal('15')
139
161
  ```
140
162
 
141
- Variables must be single characters (to enforce safety and keep parsing simple).
163
+ Variables are mapped internally to a safe internal representation and are designed to be simple and predictable.
142
164
 
143
165
  ---
144
166
 
@@ -152,7 +174,7 @@ math_engine.evaluate("√(16)")
152
174
  math_engine.evaluate("pi * 2")
153
175
  ```
154
176
 
155
- All functions are processed by the internal ScientificEngine.
177
+ All functions are processed by the internal `ScientificEngine`, honoring your settings (for example, `use_degrees`).
156
178
 
157
179
  ---
158
180
 
@@ -181,58 +203,64 @@ math_engine.evaluate("0b1010 * 3")
181
203
  # Decimal('30')
182
204
  ```
183
205
 
184
- # Bitwise Operations & Developer Mode (v0.3.0)
206
+ 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.
207
+
208
+ ---
209
+
210
+ # Bitwise Operations & Developer Mode (v0.3.x)
185
211
 
186
- Math Engine now acts as a fully functional **Programmer's Calculator**. It supports standard Python operator precedence and bitwise logic.
212
+ Math Engine can act as a **programmer's calculator**. It supports standard operator precedence and bitwise logic.
187
213
 
188
214
  ### New Operators
189
215
 
190
- | Operator | Description | Example | Result |
191
- | :--- | :--- | :--- | :--- |
192
- | `&` | Bitwise AND | `3 & 1` | `1` |
193
- | `\|` | Bitwise OR | `1 \| 2` | `3` |
194
- | `^` | Bitwise XOR | `3 ^ 1` | `2` |
195
- | `<<` | Left Shift | `1 << 2` | `4` |
196
- | `>>` | Right Shift | `8 >> 2` | `2` |
197
- | `**` | Power | `2 ** 3` | `8` |
216
+ | Operator | Description | Example | Result |
217
+ | :------- | :---------- | :------- | :----- |
218
+ | `&` | Bitwise AND | `3 & 1` | `1` |
219
+ | `\|` | Bitwise OR | `1 \| 2` | `3` |
220
+ | `^` | Bitwise XOR | `3 ^ 1` | `2` |
221
+ | `<<` | Left Shift | `1 << 2` | `4` |
222
+ | `>>` | Right Shift | `8 >> 2` | `2` |
223
+ | `**` | Power | `2 ** 3` | `8` |
198
224
 
199
- > **Note:** Since `^` is now used for **XOR**, use `**` for exponentiation (power).
225
+ > Note: Since `^` is used for **XOR**, use `**` for exponentiation (power).
200
226
 
201
227
  ### Word Size & Overflow Simulation
202
228
 
203
229
  You can simulate hardware constraints (like C++ `int8`, `uint16`, etc.) by setting a `word_size`.
204
230
 
205
- * **`word_size: 0` (Default):** Python mode (Arbitrary precision, no overflow).
206
- * **`word_size: 8/16/32/64`:** Enforces bit limits. Numbers will wrap around (overflow).
231
+ * **`word_size: 0` (Default):** Python mode (arbitrary precision, no overflow).
232
+ * **`word_size: 8/16/32/64`:** Enforces bit limits. Numbers will wrap around (overflow) accordingly.
207
233
 
208
234
  ### Signed vs. Unsigned Mode
209
235
 
210
- When `word_size > 0`, you can toggle how binary data is interpreted using `signed_mode`.
236
+ When `word_size > 0`, you can control how values are interpreted via `signed_mode`:
211
237
 
212
- * **`True` (Default):** Uses **Two's Complement**. The highest bit indicates a negative number.
213
- * **`False`:** Strictly positive numbers (Unsigned).
238
+ * **`True` (Default):** Use **Two's Complement** for negative values.
239
+ * **`False`:** Treat all values as unsigned.
214
240
 
215
- **Example: 8-Bit Simulation**
241
+ **Example: 8-bit Simulation**
216
242
 
217
243
  ```python
218
- # Setup: 8-Bit Signed Mode
219
- settings = {
220
- "word_size": 8,
221
- "signed_mode": True
222
- }
244
+ import math_engine
245
+
246
+ settings = math_engine.load_all_settings()
247
+ settings["word_size"] = 8
248
+ settings["signed_mode"] = True
223
249
  math_engine.load_preset(settings)
224
250
 
225
- # Calculation: 127 + 1
226
- # Mathematically 128, but in 8-bit signed this overflows to -128.
227
251
  math_engine.evaluate("127 + 1")
252
+ # In 8-bit signed arithmetic this overflows to -128
228
253
  # Decimal('-128')
254
+ ```
229
255
 
230
- # Calculation: -1 in Hex
231
- # In 8-bit two's complement, -1 is represented as FF.
256
+ Hex output respects the current word size and signedness:
257
+
258
+ ```python
232
259
  math_engine.evaluate("hex: -1")
233
- # '-0x1' (Value is masked internally to 255)
260
+ # Hex representation consistent with word_size / signed_mode configuration
234
261
  ```
235
- ### Force-only-hex mode
262
+
263
+ ### Force-only-hex Mode
236
264
 
237
265
  ```python
238
266
  settings = math_engine.load_all_settings()
@@ -243,39 +271,58 @@ math_engine.evaluate("FF + 3")
243
271
  # Decimal('258')
244
272
  ```
245
273
 
246
- Input validation ensures safety.
274
+ Input validation ensures safety and prevents mixing incompatible formats in strict modes.
247
275
 
248
276
  ---
249
277
 
250
278
  # Settings System
251
279
 
252
- You may load presets:
280
+ You can inspect and modify settings programmatically.
281
+
282
+ ### Load Current Settings
283
+
284
+ ```python
285
+ import math_engine
286
+
287
+ settings = math_engine.load_all_settings()
288
+ print(settings)
289
+ ```
290
+
291
+ ### Apply a Full Preset
292
+
293
+ This is a plain Python `dict` (not JSON):
253
294
 
254
295
  ```python
255
296
  preset = {
256
297
  "decimal_places": 2,
257
- "use_degrees": false,
258
- "allow_augmented_assignment": true,
259
- "fractions": false,
260
- "allow_non_decimal": true,
261
- "debug": false,
262
- "correct_output_format": true,
298
+ "use_degrees": False,
299
+ "allow_augmented_assignment": True,
300
+ "fractions": False,
301
+ "allow_non_decimal": True,
302
+ "debug": False,
303
+ "correct_output_format": True,
263
304
  "default_output_format": "decimal:",
264
- "only_hex": false,
265
- "only_binary": false,
266
- "only_octal": false,
267
- # New in v0.3.0
268
- "word_size": 0, # 0 = Unlimited, or 8, 16, 32, 64
269
- "signed_mode": true, # True = Two's Complement, False = Unsigned
305
+ "only_hex": False,
306
+ "only_binary": False,
307
+ "only_octal": False,
308
+ # New in 0.3.0
309
+ "word_size": 0, # 0 = unlimited, or 8, 16, 32, 64
310
+ "signed_mode": True, # True = Two's Complement, False = Unsigned
270
311
  }
271
312
 
272
313
  math_engine.load_preset(preset)
273
314
  ```
274
315
 
275
- Or modify single settings:
316
+ ### Change a Single Setting
276
317
 
277
318
  ```python
278
- math_engine.save_setting("decimal_places", 10)
319
+ math_engine.change_setting("decimal_places", 10)
320
+ ```
321
+
322
+ You can also read a single setting:
323
+
324
+ ```python
325
+ decimal_places = math_engine.load_one_setting("decimal_places")
279
326
  ```
280
327
 
281
328
  ---
@@ -292,10 +339,15 @@ Every error is a custom exception with:
292
339
  Example:
293
340
 
294
341
  ```python
342
+ import math_engine
343
+ from math_engine import error as E
344
+
295
345
  try:
296
346
  math_engine.evaluate("1/0")
297
- except math_engine.error.CalculationError as e:
298
- print(e.code) # 3003
347
+ except E.CalculationError as e:
348
+ print(e.code) # 3003
349
+ print(e.message) # "Division by zero"
350
+ print(e.equation) # "1/0"
299
351
  ```
300
352
 
301
353
  ### Example Error Codes
@@ -309,6 +361,9 @@ except math_engine.error.CalculationError as e:
309
361
  | 8000 | Conversion to int failed |
310
362
  | 8006 | Output conversion error |
311
363
 
364
+ For a complete list of all error codes and their meanings, please see the **[Error Codes Reference](https://github.com/JanTeske06/math_engine/blob/master/ERRORS.md)**.
365
+
366
+ ---
312
367
  ---
313
368
 
314
369
  # Testing and Reliability
@@ -320,18 +375,21 @@ math_engine is designed with testing in mind:
320
375
  * Unit-test friendly behavior
321
376
  * No reliance on Python’s runtime execution
322
377
 
323
- You can easily test error codes:
378
+ Example with `pytest`:
324
379
 
325
380
  ```python
326
381
  import pytest
382
+ import math_engine
327
383
  from math_engine import error as E
328
384
 
329
- def test_div_zero():
385
+ def test_division_by_zero_error_code():
330
386
  with pytest.raises(E.CalculationError) as exc:
331
387
  math_engine.evaluate("1/0")
332
388
  assert exc.value.code == "3003"
333
389
  ```
334
390
 
391
+ You can also test more advanced behavior (non-decimal, strict modes, bitwise operations, etc.) in the same way.
392
+
335
393
  ---
336
394
 
337
395
  # Performance
@@ -353,7 +411,7 @@ Future updates focus on:
353
411
 
354
412
  ### Calculator Applications
355
413
 
356
- Build full scientific calculators, both GUI and command line.
414
+ Build full scientific or programmer calculators, both GUI and command line.
357
415
 
358
416
  ### Education
359
417
 
@@ -363,7 +421,7 @@ Great for learning about lexers, parsers, ASTs, and expression evaluation.
363
421
 
364
422
  Safe math evaluation inside larger apps.
365
423
 
366
- ### Security-sensitive Input
424
+ ### Security-Sensitive Input
367
425
 
368
426
  Rejects arbitrary Python code and ensures controlled evaluation.
369
427
 
@@ -378,7 +436,6 @@ Conversion between hex/bin/decimal is easy and reliable.
378
436
  * Non-decimal output formatting upgrades
379
437
  * Strict type-matching modes
380
438
  * Function overloading
381
- * Bitwise operators (`&`, `|`, `^`, `<<`, `>>`)
382
439
  * Memory/register system
383
440
  * Speed optimization via caching
384
441
  * User-defined functions
@@ -398,9 +455,6 @@ MIT License
398
455
  Contributions are welcome.
399
456
  Feel free to submit issues or PRs on GitHub:
400
457
 
401
- ```
458
+ ```text
402
459
  https://github.com/JanTeske06/math_engine
403
460
  ```
404
-
405
- ---
406
-
@@ -116,7 +116,8 @@ def validate(expr: str,
116
116
  print(Equation + str(e.equation))
117
117
 
118
118
 
119
-
119
+ def reset_settings():
120
+ config_manager.reset_settings()
120
121
  #
121
122
  # if __name__ == '__main__':
122
123
  # #problem = ("x+1", x=5)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: math-engine
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: A fast and secure mathematical expression evaluator.
5
5
  Author-email: Jan Teske <jan.teske.06@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/JanTeske06/math_engine
@@ -12,18 +12,18 @@ Requires-Python: >=3.8
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
 
15
- # Math Engine 0.3.0
15
+
16
+ # Math Engine 0.3.2
16
17
 
17
18
  [![PyPI Version](https://img.shields.io/pypi/v/math-engine.svg)](https://pypi.org/project/math-engine/)
18
19
  [![License: MIT](https://img.shields.io/pypi/l/math-engine.svg)](https://opensource.org/licenses/MIT)
19
20
  [![Python Versions](https://img.shields.io/pypi/pyversions/math-engine.svg)](https://pypi.org/project/math-engine/)
20
21
 
21
- A fast, safe, configurable expression parser and calculator for Python
22
+ A fast, safe, configurable expression parser and calculator for Python.
22
23
 
23
- **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.
24
+ **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.
24
25
  It provides a complete pipeline:
25
26
 
26
-
27
27
  * Tokenizer
28
28
  * AST (Abstract Syntax Tree) parser
29
29
  * Evaluator (numeric + equation solver)
@@ -33,7 +33,7 @@ It provides a complete pipeline:
33
33
  * Scientific functions
34
34
  * Strict error codes for reliable debugging and automated testing
35
35
 
36
- **Version 0.2.1** adds extensive non-decimal number support (hex, binary, octal), prefix-based type casting, improved settings management, and expanded error reporting.
36
+ **Version _0.3.2_** adds extensive non-decimal number support (hex, binary, octal), prefix-based type casting, improved settings management, expanded error reporting, and an optional programmer mode with bitwise operations and word-size simulation.
37
37
 
38
38
  This library is ideal for:
39
39
 
@@ -58,12 +58,11 @@ This library is ideal for:
58
58
  * Strong error handling with unique codes
59
59
  * Settings system with presets
60
60
  * Optional strict modes:
61
-
62
61
  * `only_hex`
63
62
  * `only_binary`
64
63
  * `only_octal`
65
64
 
66
- ### Non-Decimal Support (0.2.1)
65
+ ### Non-Decimal Support (0.2.1)
67
66
 
68
67
  * Read binary `0b1101`
69
68
  * Read octal `0o755`
@@ -76,9 +75,9 @@ This library is ideal for:
76
75
 
77
76
  # Installation
78
77
 
79
- ```
78
+ ```bash
80
79
  pip install math-engine
81
- ```
80
+ ````
82
81
 
83
82
  ---
84
83
 
@@ -109,11 +108,27 @@ math_engine.evaluate("octal: 64")
109
108
  ## Automatic Format Correction
110
109
 
111
110
  ```python
112
- math_engine.load_preset({"correct_output_format": True})
113
- math_engine.evaluate("boolean: 3+3=6")
111
+ import math_engine
112
+
113
+ settings = math_engine.load_all_settings()
114
+ settings["correct_output_format"] = True
115
+ math_engine.load_preset(settings)
116
+
117
+ math_engine.evaluate("bool: 3+3=6")
114
118
  # True
115
119
  ```
116
120
 
121
+ ## Reset all Settings to Default
122
+
123
+ ```python
124
+ import math_engine
125
+
126
+ reset_settings()
127
+ ```
128
+
129
+
130
+ 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.
131
+
117
132
  ---
118
133
 
119
134
  # Prefix System (Casting Syntax)
@@ -145,14 +160,21 @@ math_engine.evaluate("hex: 3 + 3")
145
160
  ```python
146
161
  vars = {
147
162
  "A": 10,
148
- "B": 5
163
+ "B": 5,
149
164
  }
150
165
 
151
- math_engine.evaluate("A + B", custom_variables=vars)
166
+ math_engine.evaluate("A + B", variables=vars)
167
+ # Decimal('15')
168
+ ```
169
+
170
+ Alternatively, you can pass variables as keyword arguments:
171
+
172
+ ```python
173
+ math_engine.evaluate("A + B", A=10, B=5)
152
174
  # Decimal('15')
153
175
  ```
154
176
 
155
- Variables must be single characters (to enforce safety and keep parsing simple).
177
+ Variables are mapped internally to a safe internal representation and are designed to be simple and predictable.
156
178
 
157
179
  ---
158
180
 
@@ -166,7 +188,7 @@ math_engine.evaluate("√(16)")
166
188
  math_engine.evaluate("pi * 2")
167
189
  ```
168
190
 
169
- All functions are processed by the internal ScientificEngine.
191
+ All functions are processed by the internal `ScientificEngine`, honoring your settings (for example, `use_degrees`).
170
192
 
171
193
  ---
172
194
 
@@ -195,58 +217,64 @@ math_engine.evaluate("0b1010 * 3")
195
217
  # Decimal('30')
196
218
  ```
197
219
 
198
- # Bitwise Operations & Developer Mode (v0.3.0)
220
+ 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.
221
+
222
+ ---
223
+
224
+ # Bitwise Operations & Developer Mode (v0.3.x)
199
225
 
200
- Math Engine now acts as a fully functional **Programmer's Calculator**. It supports standard Python operator precedence and bitwise logic.
226
+ Math Engine can act as a **programmer's calculator**. It supports standard operator precedence and bitwise logic.
201
227
 
202
228
  ### New Operators
203
229
 
204
- | Operator | Description | Example | Result |
205
- | :--- | :--- | :--- | :--- |
206
- | `&` | Bitwise AND | `3 & 1` | `1` |
207
- | `\|` | Bitwise OR | `1 \| 2` | `3` |
208
- | `^` | Bitwise XOR | `3 ^ 1` | `2` |
209
- | `<<` | Left Shift | `1 << 2` | `4` |
210
- | `>>` | Right Shift | `8 >> 2` | `2` |
211
- | `**` | Power | `2 ** 3` | `8` |
230
+ | Operator | Description | Example | Result |
231
+ | :------- | :---------- | :------- | :----- |
232
+ | `&` | Bitwise AND | `3 & 1` | `1` |
233
+ | `\|` | Bitwise OR | `1 \| 2` | `3` |
234
+ | `^` | Bitwise XOR | `3 ^ 1` | `2` |
235
+ | `<<` | Left Shift | `1 << 2` | `4` |
236
+ | `>>` | Right Shift | `8 >> 2` | `2` |
237
+ | `**` | Power | `2 ** 3` | `8` |
212
238
 
213
- > **Note:** Since `^` is now used for **XOR**, use `**` for exponentiation (power).
239
+ > Note: Since `^` is used for **XOR**, use `**` for exponentiation (power).
214
240
 
215
241
  ### Word Size & Overflow Simulation
216
242
 
217
243
  You can simulate hardware constraints (like C++ `int8`, `uint16`, etc.) by setting a `word_size`.
218
244
 
219
- * **`word_size: 0` (Default):** Python mode (Arbitrary precision, no overflow).
220
- * **`word_size: 8/16/32/64`:** Enforces bit limits. Numbers will wrap around (overflow).
245
+ * **`word_size: 0` (Default):** Python mode (arbitrary precision, no overflow).
246
+ * **`word_size: 8/16/32/64`:** Enforces bit limits. Numbers will wrap around (overflow) accordingly.
221
247
 
222
248
  ### Signed vs. Unsigned Mode
223
249
 
224
- When `word_size > 0`, you can toggle how binary data is interpreted using `signed_mode`.
250
+ When `word_size > 0`, you can control how values are interpreted via `signed_mode`:
225
251
 
226
- * **`True` (Default):** Uses **Two's Complement**. The highest bit indicates a negative number.
227
- * **`False`:** Strictly positive numbers (Unsigned).
252
+ * **`True` (Default):** Use **Two's Complement** for negative values.
253
+ * **`False`:** Treat all values as unsigned.
228
254
 
229
- **Example: 8-Bit Simulation**
255
+ **Example: 8-bit Simulation**
230
256
 
231
257
  ```python
232
- # Setup: 8-Bit Signed Mode
233
- settings = {
234
- "word_size": 8,
235
- "signed_mode": True
236
- }
258
+ import math_engine
259
+
260
+ settings = math_engine.load_all_settings()
261
+ settings["word_size"] = 8
262
+ settings["signed_mode"] = True
237
263
  math_engine.load_preset(settings)
238
264
 
239
- # Calculation: 127 + 1
240
- # Mathematically 128, but in 8-bit signed this overflows to -128.
241
265
  math_engine.evaluate("127 + 1")
266
+ # In 8-bit signed arithmetic this overflows to -128
242
267
  # Decimal('-128')
268
+ ```
243
269
 
244
- # Calculation: -1 in Hex
245
- # In 8-bit two's complement, -1 is represented as FF.
270
+ Hex output respects the current word size and signedness:
271
+
272
+ ```python
246
273
  math_engine.evaluate("hex: -1")
247
- # '-0x1' (Value is masked internally to 255)
274
+ # Hex representation consistent with word_size / signed_mode configuration
248
275
  ```
249
- ### Force-only-hex mode
276
+
277
+ ### Force-only-hex Mode
250
278
 
251
279
  ```python
252
280
  settings = math_engine.load_all_settings()
@@ -257,39 +285,58 @@ math_engine.evaluate("FF + 3")
257
285
  # Decimal('258')
258
286
  ```
259
287
 
260
- Input validation ensures safety.
288
+ Input validation ensures safety and prevents mixing incompatible formats in strict modes.
261
289
 
262
290
  ---
263
291
 
264
292
  # Settings System
265
293
 
266
- You may load presets:
294
+ You can inspect and modify settings programmatically.
295
+
296
+ ### Load Current Settings
297
+
298
+ ```python
299
+ import math_engine
300
+
301
+ settings = math_engine.load_all_settings()
302
+ print(settings)
303
+ ```
304
+
305
+ ### Apply a Full Preset
306
+
307
+ This is a plain Python `dict` (not JSON):
267
308
 
268
309
  ```python
269
310
  preset = {
270
311
  "decimal_places": 2,
271
- "use_degrees": false,
272
- "allow_augmented_assignment": true,
273
- "fractions": false,
274
- "allow_non_decimal": true,
275
- "debug": false,
276
- "correct_output_format": true,
312
+ "use_degrees": False,
313
+ "allow_augmented_assignment": True,
314
+ "fractions": False,
315
+ "allow_non_decimal": True,
316
+ "debug": False,
317
+ "correct_output_format": True,
277
318
  "default_output_format": "decimal:",
278
- "only_hex": false,
279
- "only_binary": false,
280
- "only_octal": false,
281
- # New in v0.3.0
282
- "word_size": 0, # 0 = Unlimited, or 8, 16, 32, 64
283
- "signed_mode": true, # True = Two's Complement, False = Unsigned
319
+ "only_hex": False,
320
+ "only_binary": False,
321
+ "only_octal": False,
322
+ # New in 0.3.0
323
+ "word_size": 0, # 0 = unlimited, or 8, 16, 32, 64
324
+ "signed_mode": True, # True = Two's Complement, False = Unsigned
284
325
  }
285
326
 
286
327
  math_engine.load_preset(preset)
287
328
  ```
288
329
 
289
- Or modify single settings:
330
+ ### Change a Single Setting
290
331
 
291
332
  ```python
292
- math_engine.save_setting("decimal_places", 10)
333
+ math_engine.change_setting("decimal_places", 10)
334
+ ```
335
+
336
+ You can also read a single setting:
337
+
338
+ ```python
339
+ decimal_places = math_engine.load_one_setting("decimal_places")
293
340
  ```
294
341
 
295
342
  ---
@@ -306,10 +353,15 @@ Every error is a custom exception with:
306
353
  Example:
307
354
 
308
355
  ```python
356
+ import math_engine
357
+ from math_engine import error as E
358
+
309
359
  try:
310
360
  math_engine.evaluate("1/0")
311
- except math_engine.error.CalculationError as e:
312
- print(e.code) # 3003
361
+ except E.CalculationError as e:
362
+ print(e.code) # 3003
363
+ print(e.message) # "Division by zero"
364
+ print(e.equation) # "1/0"
313
365
  ```
314
366
 
315
367
  ### Example Error Codes
@@ -323,6 +375,9 @@ except math_engine.error.CalculationError as e:
323
375
  | 8000 | Conversion to int failed |
324
376
  | 8006 | Output conversion error |
325
377
 
378
+ For a complete list of all error codes and their meanings, please see the **[Error Codes Reference](https://github.com/JanTeske06/math_engine/blob/master/ERRORS.md)**.
379
+
380
+ ---
326
381
  ---
327
382
 
328
383
  # Testing and Reliability
@@ -334,18 +389,21 @@ math_engine is designed with testing in mind:
334
389
  * Unit-test friendly behavior
335
390
  * No reliance on Python’s runtime execution
336
391
 
337
- You can easily test error codes:
392
+ Example with `pytest`:
338
393
 
339
394
  ```python
340
395
  import pytest
396
+ import math_engine
341
397
  from math_engine import error as E
342
398
 
343
- def test_div_zero():
399
+ def test_division_by_zero_error_code():
344
400
  with pytest.raises(E.CalculationError) as exc:
345
401
  math_engine.evaluate("1/0")
346
402
  assert exc.value.code == "3003"
347
403
  ```
348
404
 
405
+ You can also test more advanced behavior (non-decimal, strict modes, bitwise operations, etc.) in the same way.
406
+
349
407
  ---
350
408
 
351
409
  # Performance
@@ -367,7 +425,7 @@ Future updates focus on:
367
425
 
368
426
  ### Calculator Applications
369
427
 
370
- Build full scientific calculators, both GUI and command line.
428
+ Build full scientific or programmer calculators, both GUI and command line.
371
429
 
372
430
  ### Education
373
431
 
@@ -377,7 +435,7 @@ Great for learning about lexers, parsers, ASTs, and expression evaluation.
377
435
 
378
436
  Safe math evaluation inside larger apps.
379
437
 
380
- ### Security-sensitive Input
438
+ ### Security-Sensitive Input
381
439
 
382
440
  Rejects arbitrary Python code and ensures controlled evaluation.
383
441
 
@@ -392,7 +450,6 @@ Conversion between hex/bin/decimal is easy and reliable.
392
450
  * Non-decimal output formatting upgrades
393
451
  * Strict type-matching modes
394
452
  * Function overloading
395
- * Bitwise operators (`&`, `|`, `^`, `<<`, `>>`)
396
453
  * Memory/register system
397
454
  * Speed optimization via caching
398
455
  * User-defined functions
@@ -412,9 +469,6 @@ MIT License
412
469
  Contributions are welcome.
413
470
  Feel free to submit issues or PRs on GitHub:
414
471
 
415
- ```
472
+ ```text
416
473
  https://github.com/JanTeske06/math_engine
417
474
  ```
418
-
419
- ---
420
-
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "math-engine"
8
- version = "0.3.0"
8
+ version = "0.3.2"
9
9
  authors = [
10
10
  { name="Jan Teske", email="jan.teske.06@gmail.com" },
11
11
  ]
File without changes
File without changes