# `postfixcalc`
Simple, stupid but easy and powerful infix expression evaluator using [_postfix_](https://en.wikipedia.org/wiki/Reverse_Polish_notation) notation.
# User Guide
## How to use?
```python
from postfixcalc import Calc
```
```python
expr = "(-1) ^ 2 + 3 - 4 * 8 - 2 ^ 3"
calc = Calc(expr)
```
```python
print(calc.answer)
print(type(calc.answer))
```
-36
<class 'int'>
### Explanation
```
expression: (-1) ^ 2 + 3 - 4 * 8 - 2 ^ 3
```
which with the math operator precedence is:
```
expression: ((-1) ^ 2) + 3 - (4 * 8) - (2 ^ 3)
= (1) + 3 - (32) - (8)
= 4 - 32 - 8
= -28 - 8
= -36
```
## Initialization
```python
calc = Calc(
'(2 ^ 32) ^ (2 ^ 15) + -1',
calc_timeout=1, # timeout for the calculation (in seconds)
str_repr_timeout=1.5 # timeout to generate the string representation (in seconds)
)
```
```python
print(f"'(2 ^ 32) ^ (2 ^ 15) + -1's answer has '{len(calc.stranswer())}' digits")
```
'(2 ^ 32) ^ (2 ^ 15) + -1's answer has '315653' digits
```python
print(f'answer is: {calc.stranswer(15, 15)}')
```
answer is: 674114012549907...068940335579135
## Other Attributes
```python
from rich.pretty import Pretty
from rich import print as rprint
```
```python
rprint(calc.parsed)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.BinOp</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb65c3917b0</span><span style="font-weight: bold">></span>
</pre>
```python
rprint(calc.extracted)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">[</span>
<span style="font-weight: bold">(</span>
<span style="font-weight: bold">[</span>
<span style="font-weight: bold">(</span>
<span style="font-weight: bold">[([</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span><span style="font-weight: bold">]</span>, <span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Pow</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991120</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">32</span><span style="font-weight: bold">])]</span>,
<span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Pow</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991120</span><span style="font-weight: bold">></span>,
<span style="font-weight: bold">[([</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span><span style="font-weight: bold">]</span>, <span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Pow</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991120</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">15</span><span style="font-weight: bold">])]</span>
<span style="font-weight: bold">)</span>
<span style="font-weight: bold">]</span>,
<span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Add</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661990ee0</span><span style="font-weight: bold">></span>,
<span style="font-weight: bold">[(<</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.USub</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991540</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">1</span><span style="font-weight: bold">])]</span>
<span style="font-weight: bold">)</span>
<span style="font-weight: bold">]</span>
</pre>
```python
rprint(calc.flattened)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">(</span>
<span style="font-weight: bold">(</span>
<span style="font-weight: bold">(([</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span><span style="font-weight: bold">]</span>, <span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Pow</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991120</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">32</span><span style="font-weight: bold">])</span>,<span style="font-weight: bold">)</span>,
<span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Pow</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991120</span><span style="font-weight: bold">></span>,
<span style="font-weight: bold">(([</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span><span style="font-weight: bold">]</span>, <span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Pow</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991120</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">15</span><span style="font-weight: bold">])</span>,<span style="font-weight: bold">)</span>
<span style="font-weight: bold">)</span>,
<span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Add</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661990ee0</span><span style="font-weight: bold">></span>,
<span style="font-weight: bold">(<</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.USub</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991540</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">1</span><span style="font-weight: bold">])</span>
<span style="font-weight: bold">)</span>
</pre>
```python
rprint(calc.strparenthesized)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">(((</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span> ^ <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">32</span><span style="font-weight: bold">))</span> ^ <span style="font-weight: bold">((</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span> ^ <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">15</span><span style="font-weight: bold">)))</span> + <span style="font-weight: bold">(</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">-1</span><span style="font-weight: bold">)</span>
</pre>
```python
rprint(calc.listparenthesized)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">[</span><span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">32</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">15</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">'+'</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008000; text-decoration-color: #008000">'-1'</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span><span style="font-weight: bold">]</span>
</pre>
```python
rprint(calc.numerized)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">[</span><span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">32</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">15</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span>, <span style="color: #008000; text-decoration-color: #008000">'+'</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">-1</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span><span style="font-weight: bold">]</span>
</pre>
```python
rprint(calc.postfix)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">32</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">15</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">-1</span>, <span style="color: #008000; text-decoration-color: #008000">'+'</span><span style="font-weight: bold">]</span>
</pre>
```python
rprint(f'{calc.stranswer(15, 15)}')
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">674114012549907</span><span style="color: #808000; text-decoration-color: #808000">...</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">068940335579135</span>
</pre>
# `Calc` Documentation
**`class Calc`** _`(expr: str, calc_timeout: int | float = 0.1, str_repr_timeout: int | float = 0.2)`_
- `expr`: _infix_ math expression
- `calc_timeout`: the timeout of the math calculation, if a expression's calculation took longer than this time, it would be killed and a `TimeoutError` will be raised.
- `str_repr_timeout`: Calculating a expression like: `(2 ^ 32) ^ (2 ^ 15)` takes about a seconds, but the result has 315653 digits; so printing (getting the string representation) takes some time, this timeout is controlled by this parameter; and a `TimeoutError` will be raised.
### Properties of `Calc`
#### Important Note
All the properties of `Calc` type (except `stranswer`) are [cached properties](https://docs.python.org/3/library/functools.html#functools.cached_property). It means that they are calculated once and stored in the object and are not calculated every time you need them (if other properties and attributes are remained unchanged)
- `Calc.parsed`
Parse the object with `ast.parse` function and return the parsed expression.
Because `ast.parse` uses the grammar of Python any syntax error will be raised here!
```python
# underlying function
from postfixcalc.parser import parse
expr = '-1 ^ 2'
parsed = parse(expr)
rprint(parsed)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.UnaryOp</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb6603566b0</span><span style="font-weight: bold">></span>
</pre>
- `Calc.extracted`
Return a list of extracted numbers and operators from the [parsed object](https://docs.python.org/3/library/ast.html?highlight=ast#ast.Expr)
```python
# underlying function
from postfixcalc.parser import extract_nums_and_ops
extracted = extract_nums_and_ops(parsed)
rprint(extracted)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">[(<</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.USub</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991540</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">[([</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">1</span><span style="font-weight: bold">]</span>, <span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Pow</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991120</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span><span style="font-weight: bold">])])]</span>
</pre>
- `Calc.flattened`
Flatten the numbers and operators list, this will reduce the nested lists and tuples
```python
# underlying function
from postfixcalc.parser import flatten_nodes
flattened = flatten_nodes(extracted)
rprint(flattened)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">(<</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.USub</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991540</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">([</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">1</span><span style="font-weight: bold">]</span>, <span style="font-weight: bold"><</span><span style="color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold">ast.Pow</span><span style="color: #000000; text-decoration-color: #000000"> object at </span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">0x7fb661991120</span><span style="font-weight: bold">></span>, <span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span><span style="font-weight: bold">]))</span>
</pre>
- `Calc.strparenthesized`
Generate a _parenthesized_ version of the expression passed in initialization according to the math operator precedence
```python
# underlying function
from postfixcalc.parser import restrexpression
rprint(restrexpression(flattened))
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">-<span style="font-weight: bold">(</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">1</span> ^ <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span><span style="font-weight: bold">)</span>
</pre>
- `Calc.listparenthesized`
Return the digits and parenthesis and operators in a list that will be used to generate the postfix list
```python
# underlying function
from postfixcalc.parser import relistexpression
listed = relistexpression(flattened)
rprint(listed)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">[</span><span style="color: #008000; text-decoration-color: #008000">'-'</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">1</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span><span style="font-weight: bold">]</span>
</pre>
- `Calc.numerized`
Numerize the string numbers returned by `listparenthesized` method. In some cased like: `(-1) ^ 2)` the `listparenthesized` looks like this: `['(', '-1', ')', '^', 2]`, so we have to make those strings numbers
```python
# underlying function
from postfixcalc.parser import make_num
numerized = make_num(listed)
rprint(numerized)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">[</span><span style="color: #008000; text-decoration-color: #008000">'-'</span>, <span style="color: #008000; text-decoration-color: #008000">'('</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">1</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span>, <span style="color: #008000; text-decoration-color: #008000">')'</span><span style="font-weight: bold">]</span>
</pre>
- `Calc.postfix`
Return a list with the postfix notation of the expression
```python
# underlying function
from postfixcalc.parser import infix_to_postfix
postfixed = infix_to_postfix(numerized)
rprint(postfixed)
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="font-weight: bold">[</span><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">1</span>, <span style="color: #008080; text-decoration-color: #008080; font-weight: bold">2</span>, <span style="color: #008000; text-decoration-color: #008000">'^'</span>, <span style="color: #008000; text-decoration-color: #008000">'-'</span><span style="font-weight: bold">]</span>
</pre>
- `Calc.answer`
Calculate the answer respecting the `calc_timeout`
**IMPORTANT NOTE: DON'T CALL `print` ON THE RESULT OF THIS METHOD.**
This is because for instance calculating `(2 ^ 32) ^ (2 ^ 15)` is done under `calc_timeout` BUT generating the string
representation **WILL TAKE MUCH LONGER!!!** (it has 315653 digits)
If you want to `print` the result, use `stranswer` method
method
```python
@cached_property
def answer(self):
process = multiprocessing.Process(target=evaluate, args=(self.postfix,))
process.start()
process.join(timeout=self.calc_timeout)
if process.is_alive():
process.terminate()
raise TimeoutError(
f"Calculations of {self.strparenthesized!r} took longer than {self.calc_timeout} seconds",
) from None
return evaluate(self.postfix)
```
```python
# underlying function
from postfixcalc.pyeval import evaluate
rprint(evaluate(postfixed))
```
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="color: #008080; text-decoration-color: #008080; font-weight: bold">-1</span>
</pre>
- `Calc.stranswer`
Return the string representation of the `Calc.answer` respecting the `str_repr_timeout`
method
```python
def stranswer(
self,
beginning: Optional[int] = None,
ending: Optional[int] = None,
) -> str:
"""Return the string representation of the answer with the respect to the `str_repr_timeout`
beginning: see the first n digits of the answer: '982734...'
ending: see the last n digits of the answer: '...982734'
if both are specified: '987234...873242'
"""
process = multiprocessing.Process(target=str, args=(self.answer,))
process.start()
process.join(self.str_repr_timeout)
if process.is_alive():
process.terminate()
raise TimeoutError(
f"Generating a string representation of {self.expr!r} took longer than {self.str_repr_timeout} seconds",
) from None
try:
answer = str(self.answer)
match (beginning, ending):
case (None, None):
return answer
case (x, None):
return f"{answer[:x]}..."
case (None, x):
return f"...{answer[-x:]}"
case (x, y):
return f"{answer[:x]}...{answer[-y:]}"
case _:
raise ValueError("Confusing beginning and ending")
except ValueError:
raise TimeoutError(
f"Generating a string representation of {self.expr!r} took longer than {self.str_repr_timeout} seconds",
) from None
```
### How the answer is calculated
`Calc` type has cached properties which rely on each others returned values, it means that when we access the `Calc.answer` property this sequential method and function calls, happen:
`print(calc.answer)`
1. `calc.answer` needs the postfix: `calc.postfix` gets called
2. `calc.postfix` needs the numerized list of the digits and operators: `calc.numerized` gets called
3. `calc.numerized` needs the parenthesized list of the digits and operators: `calc.listparenthsized` gets called
4. `calc.listprenthesized` needs the flattened list of extracted nums and ops: `calc.flattened` gets called.
5. `calc.flattened` needs the extracted nums and ops: `calc.extracted` gets called.
6. `calc.extracted` needs the parsed expression of the input expression: `calc.parsed` gets called.
### Call graph for getting the answer
![myuses.svg](./docs/myuses.svg)
Raw data
{
"_id": null,
"home_page": "https://github.com/mahdihaghverdi/postfixcalc",
"name": "postfixcalc",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10,<4.0",
"maintainer_email": "",
"keywords": "parse,calculator,safe calculation,postfix",
"author": "Mahdi Haghverdi",
"author_email": "mahdihaghverdiliewpl@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/17/9c/1170dbd6bd994b0a6ce9be9ad45772b4cbc3463a596c79b70dbd0f33253f/postfixcalc-0.8.4.tar.gz",
"platform": null,
"description": "# `postfixcalc`\n\nSimple, stupid but easy and powerful infix expression evaluator using [_postfix_](https://en.wikipedia.org/wiki/Reverse_Polish_notation) notation.\n\n# User Guide\n\n## How to use?\n\n\n```python\nfrom postfixcalc import Calc\n```\n\n\n```python\nexpr = \"(-1) ^ 2 + 3 - 4 * 8 - 2 ^ 3\"\ncalc = Calc(expr)\n```\n\n\n```python\nprint(calc.answer)\nprint(type(calc.answer))\n```\n\n -36\n <class 'int'>\n\n\n### Explanation\n```\nexpression: (-1) ^ 2 + 3 - 4 * 8 - 2 ^ 3\n```\n\nwhich with the math operator precedence is:\n\n```\nexpression: ((-1) ^ 2) + 3 - (4 * 8) - (2 ^ 3)\n = (1) + 3 - (32) - (8)\n = 4 - 32 - 8\n = -28 - 8\n = -36\n```\n\n## Initialization\n\n\n```python\ncalc = Calc(\n '(2 ^ 32) ^ (2 ^ 15) + -1',\n calc_timeout=1, # timeout for the calculation (in seconds)\n str_repr_timeout=1.5 # timeout to generate the string representation (in seconds)\n)\n```\n\n\n```python\nprint(f\"'(2 ^ 32) ^ (2 ^ 15) + -1's answer has '{len(calc.stranswer())}' digits\")\n```\n\n '(2 ^ 32) ^ (2 ^ 15) + -1's answer has '315653' digits\n\n\n\n```python\nprint(f'answer is: {calc.stranswer(15, 15)}')\n```\n\n answer is: 674114012549907...068940335579135\n\n\n## Other Attributes\n\n\n```python\nfrom rich.pretty import Pretty\nfrom rich import print as rprint\n```\n\n\n```python\nrprint(calc.parsed)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.BinOp</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb65c3917b0</span><span style=\"font-weight: bold\">></span>\n</pre>\n\n\n\n\n```python\nrprint(calc.extracted)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span>\n <span style=\"font-weight: bold\">(</span>\n <span style=\"font-weight: bold\">[</span>\n <span style=\"font-weight: bold\">(</span>\n <span style=\"font-weight: bold\">[([</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">]</span>, <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Pow</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991120</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">32</span><span style=\"font-weight: bold\">])]</span>,\n <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Pow</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991120</span><span style=\"font-weight: bold\">></span>,\n <span style=\"font-weight: bold\">[([</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">]</span>, <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Pow</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991120</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">15</span><span style=\"font-weight: bold\">])]</span>\n <span style=\"font-weight: bold\">)</span>\n <span style=\"font-weight: bold\">]</span>,\n <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Add</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661990ee0</span><span style=\"font-weight: bold\">></span>,\n <span style=\"font-weight: bold\">[(<</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.USub</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991540</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span><span style=\"font-weight: bold\">])]</span>\n <span style=\"font-weight: bold\">)</span>\n<span style=\"font-weight: bold\">]</span>\n</pre>\n\n\n\n\n```python\nrprint(calc.flattened)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">(</span>\n <span style=\"font-weight: bold\">(</span>\n <span style=\"font-weight: bold\">(([</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">]</span>, <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Pow</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991120</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">32</span><span style=\"font-weight: bold\">])</span>,<span style=\"font-weight: bold\">)</span>,\n <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Pow</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991120</span><span style=\"font-weight: bold\">></span>,\n <span style=\"font-weight: bold\">(([</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">]</span>, <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Pow</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991120</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">15</span><span style=\"font-weight: bold\">])</span>,<span style=\"font-weight: bold\">)</span>\n <span style=\"font-weight: bold\">)</span>,\n <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Add</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661990ee0</span><span style=\"font-weight: bold\">></span>,\n <span style=\"font-weight: bold\">(<</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.USub</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991540</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span><span style=\"font-weight: bold\">])</span>\n<span style=\"font-weight: bold\">)</span>\n</pre>\n\n\n\n\n```python\nrprint(calc.strparenthesized)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">(((</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span> ^ <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">32</span><span style=\"font-weight: bold\">))</span> ^ <span style=\"font-weight: bold\">((</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span> ^ <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">15</span><span style=\"font-weight: bold\">)))</span> + <span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">-1</span><span style=\"font-weight: bold\">)</span>\n</pre>\n\n\n\n\n```python\nrprint(calc.listparenthesized)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">32</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">15</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'+'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'-1'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span><span style=\"font-weight: bold\">]</span>\n</pre>\n\n\n\n\n```python\nrprint(calc.numerized)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">32</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">15</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'+'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">-1</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span><span style=\"font-weight: bold\">]</span>\n</pre>\n\n\n\n\n```python\nrprint(calc.postfix)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">32</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">15</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">-1</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'+'</span><span style=\"font-weight: bold\">]</span>\n</pre>\n\n\n\n\n```python\nrprint(f'{calc.stranswer(15, 15)}')\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">674114012549907</span><span style=\"color: #808000; text-decoration-color: #808000\">...</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">068940335579135</span>\n</pre>\n\n\n\n# `Calc` Documentation\n\n**`class Calc`** _`(expr: str, calc_timeout: int | float = 0.1, str_repr_timeout: int | float = 0.2)`_\n\n- `expr`: _infix_ math expression\n\n- `calc_timeout`: the timeout of the math calculation, if a expression's calculation took longer than this time, it would be killed and a `TimeoutError` will be raised.\n\n- `str_repr_timeout`: Calculating a expression like: `(2 ^ 32) ^ (2 ^ 15)` takes about a seconds, but the result has 315653 digits; so printing (getting the string representation) takes some time, this timeout is controlled by this parameter; and a `TimeoutError` will be raised.\n\n### Properties of `Calc`\n\n#### Important Note\n\nAll the properties of `Calc` type (except `stranswer`) are [cached properties](https://docs.python.org/3/library/functools.html#functools.cached_property). It means that they are calculated once and stored in the object and are not calculated every time you need them (if other properties and attributes are remained unchanged)\n\n- `Calc.parsed`\n\nParse the object with `ast.parse` function and return the parsed expression.\nBecause `ast.parse` uses the grammar of Python any syntax error will be raised here!\n\n\n```python\n# underlying function\n\nfrom postfixcalc.parser import parse\n\nexpr = '-1 ^ 2'\nparsed = parse(expr)\n\nrprint(parsed)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.UnaryOp</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb6603566b0</span><span style=\"font-weight: bold\">></span>\n</pre>\n\n\n\n- `Calc.extracted`\n\nReturn a list of extracted numbers and operators from the [parsed object](https://docs.python.org/3/library/ast.html?highlight=ast#ast.Expr)\n\n\n```python\n# underlying function\nfrom postfixcalc.parser import extract_nums_and_ops\n\nextracted = extract_nums_and_ops(parsed)\nrprint(extracted)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[(<</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.USub</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991540</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">[([</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span><span style=\"font-weight: bold\">]</span>, <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Pow</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991120</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">])])]</span>\n</pre>\n\n\n\n- `Calc.flattened`\n\nFlatten the numbers and operators list, this will reduce the nested lists and tuples\n\n\n```python\n# underlying function\nfrom postfixcalc.parser import flatten_nodes\n\nflattened = flatten_nodes(extracted)\nrprint(flattened)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">(<</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.USub</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991540</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">([</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span><span style=\"font-weight: bold\">]</span>, <span style=\"font-weight: bold\"><</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">ast.Pow</span><span style=\"color: #000000; text-decoration-color: #000000\"> object at </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0x7fb661991120</span><span style=\"font-weight: bold\">></span>, <span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">]))</span>\n</pre>\n\n\n\n- `Calc.strparenthesized`\n\nGenerate a _parenthesized_ version of the expression passed in initialization according to the math operator precedence\n\n\n```python\n# underlying function\nfrom postfixcalc.parser import restrexpression\n\nrprint(restrexpression(flattened))\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">-<span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span> ^ <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">)</span>\n</pre>\n\n\n\n- `Calc.listparenthesized`\n\nReturn the digits and parenthesis and operators in a list that will be used to generate the postfix list\n\n\n```python\n# underlying function\nfrom postfixcalc.parser import relistexpression\n\nlisted = relistexpression(flattened)\nrprint(listed)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'-'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span><span style=\"font-weight: bold\">]</span>\n</pre>\n\n\n\n- `Calc.numerized`\n\nNumerize the string numbers returned by `listparenthesized` method. In some cased like: `(-1) ^ 2)` the `listparenthesized` looks like this: `['(', '-1', ')', '^', 2]`, so we have to make those strings numbers\n\n\n```python\n# underlying function\nfrom postfixcalc.parser import make_num\n\nnumerized = make_num(listed)\nrprint(numerized)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'-'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'('</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008000; text-decoration-color: #008000\">')'</span><span style=\"font-weight: bold\">]</span>\n</pre>\n\n\n\n- `Calc.postfix`\n\nReturn a list with the postfix notation of the expression\n\n\n```python\n# underlying function\nfrom postfixcalc.parser import infix_to_postfix\n\npostfixed = infix_to_postfix(numerized)\nrprint(postfixed)\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'^'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'-'</span><span style=\"font-weight: bold\">]</span>\n</pre>\n\n\n\n- `Calc.answer`\n\nCalculate the answer respecting the `calc_timeout`\n\n**IMPORTANT NOTE: DON'T CALL `print` ON THE RESULT OF THIS METHOD.**\n\nThis is because for instance calculating `(2 ^ 32) ^ (2 ^ 15)` is done under `calc_timeout` BUT generating the string\nrepresentation **WILL TAKE MUCH LONGER!!!** (it has 315653 digits)\n\nIf you want to `print` the result, use `stranswer` method\n\nmethod\n```python\n@cached_property\ndef answer(self):\n process = multiprocessing.Process(target=evaluate, args=(self.postfix,))\n process.start()\n process.join(timeout=self.calc_timeout)\n if process.is_alive():\n process.terminate()\n raise TimeoutError(\n f\"Calculations of {self.strparenthesized!r} took longer than {self.calc_timeout} seconds\",\n ) from None\n return evaluate(self.postfix)\n```\n\n\n```python\n# underlying function\nfrom postfixcalc.pyeval import evaluate\n\nrprint(evaluate(postfixed))\n```\n\n\n<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">-1</span>\n</pre>\n\n\n\n- `Calc.stranswer`\n\nReturn the string representation of the `Calc.answer` respecting the `str_repr_timeout`\n\nmethod\n\n```python\ndef stranswer(\n self,\n beginning: Optional[int] = None,\n ending: Optional[int] = None,\n) -> str:\n \"\"\"Return the string representation of the answer with the respect to the `str_repr_timeout`\n\n beginning: see the first n digits of the answer: '982734...'\n ending: see the last n digits of the answer: '...982734'\n\n if both are specified: '987234...873242'\n \"\"\"\n process = multiprocessing.Process(target=str, args=(self.answer,))\n process.start()\n process.join(self.str_repr_timeout)\n if process.is_alive():\n process.terminate()\n raise TimeoutError(\n f\"Generating a string representation of {self.expr!r} took longer than {self.str_repr_timeout} seconds\",\n ) from None\n try:\n answer = str(self.answer)\n match (beginning, ending):\n case (None, None):\n return answer\n case (x, None):\n return f\"{answer[:x]}...\"\n case (None, x):\n return f\"...{answer[-x:]}\"\n case (x, y):\n return f\"{answer[:x]}...{answer[-y:]}\"\n case _:\n raise ValueError(\"Confusing beginning and ending\")\n except ValueError:\n raise TimeoutError(\n f\"Generating a string representation of {self.expr!r} took longer than {self.str_repr_timeout} seconds\",\n ) from None\n```\n\n### How the answer is calculated\n\n`Calc` type has cached properties which rely on each others returned values, it means that when we access the `Calc.answer` property this sequential method and function calls, happen:\n\n\n`print(calc.answer)`\n 1. `calc.answer` needs the postfix: `calc.postfix` gets called\n 2. `calc.postfix` needs the numerized list of the digits and operators: `calc.numerized` gets called\n 3. `calc.numerized` needs the parenthesized list of the digits and operators: `calc.listparenthsized` gets called\n 4. `calc.listprenthesized` needs the flattened list of extracted nums and ops: `calc.flattened` gets called.\n 5. `calc.flattened` needs the extracted nums and ops: `calc.extracted` gets called.\n 6. `calc.extracted` needs the parsed expression of the input expression: `calc.parsed` gets called.\n\n### Call graph for getting the answer\n\n![myuses.svg](./docs/myuses.svg)\n",
"bugtrack_url": null,
"license": "LICENSE",
"summary": "the stupid postfix evaluator",
"version": "0.8.4",
"split_keywords": [
"parse",
"calculator",
"safe calculation",
"postfix"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "086456815ce8ff865c74cdf76055a6f0cf6ff562c041b2edcde1b634ad93e357",
"md5": "cb936401d5aeae58e71d17fed103b07e",
"sha256": "052da553942f5a8fb5dda6174126c5f596845f6802d3be2ca7631ca532fa0c71"
},
"downloads": -1,
"filename": "postfixcalc-0.8.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "cb936401d5aeae58e71d17fed103b07e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10,<4.0",
"size": 13094,
"upload_time": "2023-01-03T12:23:21",
"upload_time_iso_8601": "2023-01-03T12:23:21.924821Z",
"url": "https://files.pythonhosted.org/packages/08/64/56815ce8ff865c74cdf76055a6f0cf6ff562c041b2edcde1b634ad93e357/postfixcalc-0.8.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "179c1170dbd6bd994b0a6ce9be9ad45772b4cbc3463a596c79b70dbd0f33253f",
"md5": "8a8f73965f79f614c40276df27f9a5ba",
"sha256": "9604f4edbee4c8f9f2cb7c65ccbb4d76e882d05ebc8007011902057df1ea0375"
},
"downloads": -1,
"filename": "postfixcalc-0.8.4.tar.gz",
"has_sig": false,
"md5_digest": "8a8f73965f79f614c40276df27f9a5ba",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10,<4.0",
"size": 15578,
"upload_time": "2023-01-03T12:23:24",
"upload_time_iso_8601": "2023-01-03T12:23:24.075464Z",
"url": "https://files.pythonhosted.org/packages/17/9c/1170dbd6bd994b0a6ce9be9ad45772b4cbc3463a596c79b70dbd0f33253f/postfixcalc-0.8.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-01-03 12:23:24",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "mahdihaghverdi",
"github_project": "postfixcalc",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "postfixcalc"
}