### EZmachining
![image](https://raw.githubusercontent.com/wolkolak/postfixcalc/main/icon.png)
# String Expression Calculation
The project can translate infix expressions to postfix(str to tuple with members of different types).
And can calculate if needed.
Used algorithm from **[Алгоритм сортировочной станции](https://ru.wikipedia.org/wiki/Алгоритм_сортировочной_станции)** ,
also known as **[Shunting yard algorithm](https://en.wikipedia.org/wiki/Shunting_yard_algorithm)**. I used less detailed russian wiki and had no choice but improove it a little - degree('^') handler added. Unary minus was created too - better fix negatives in postfixing than in calculating.
You can see project here https://github.com/wolkolak/postfixcalc
Initially I tried to find suitable module on PYPI but failed unfortunately:
<font color="#089F0">**Firstly**</font> expression can contain functions: <font color="#c589F0">**sin**</font>, <font color="#c589F0">**pow**</font>, <font color="#c589F0">**mod**</font>, <font color="#c589F0">**neg**</font>, etc. Most projects can't work with that.
<details>
<summary>Just why? There is no way for real expressions to not contain any functions. You need <font
color="#c589F0">sin</font> and <font color="#c589F0">cos</font> at least.</summary>
Is trigonometry only for sinners? I don't think so.
</details>
<font color="#089F0">**Secondly**</font> module should handle logic operators too: <font
color="#f03c15">**'<'**</font> , <font color="#f03c15">**'=='**</font> , <font color="#f03c15">**'AND'**</font> ,
<font color="#f03c15">**'OR'**</font> , etc. And <font color="#c589F0">**variables**</font>, too.
<font color="#089F0">**The third point**</font> - i need to create postfix expressions **tens of times**, and calculate it **thousands of times**.
Because of that postfix expressions had to be turned into **tuples**. Entire module is a part of my CNC interpreter.
<font color="#089F0">**Fourth point**</font> - I don't want to see "divided by zero error", so calculator should return None in that case.
----
To calculate infix expression You need next functions:
1. <font color="#1589F0">tokenize</font>\
a = tokenize(<font color="#089F0">'-2^ -(sin(5)*3)</font>')\
print(a)\
->><font color=gray>['-', 2.0, '^', '(', '-', '(', 'sin', '(', 5.0, ')', '*', 3.0, ')', ')']</font>'
2. <font color="#1589F0">tokensPostfixing</font>\
b = tokensPostfixing(a)\
print(b)\
--><font color=gray>(2.0, 5.0, 'sin', 3.0, '*', '_', '^', '_')</font>'
3. <font color="#1589F0">postfixTokenCalc</font>\
print(postfixTokenCalc(b, DICT_VARS=None))\
<font color="gray">-0.8342390624578879</font>\
dict_A = {'x': 5}\
print(postfixTokenCalc(('x', 1.0, '+', 6, '=='), DICT_VARS=dict_A))\
<font color="gray">True</font>
print('complex?: ', postfixTokenCalc((5, 3j, '-',)))\
<font color="gray">complex?: (5-3j)</font>
As you can see, even complex numeric type didn't break the program. For now. I do not require complex in CNC, so I run only one test with it.\
And '=' is not a mathematical or logical operator - your expression for calculation should not contain assignments in the middle(You can start from "=" though). Best time to handle assignments would be after tokenization, I believe.
If You need different operators and functions (or sin in radians for example), look at the followed dicts and modify:
* OPERATORs_DICT_math: +, -, /, *, ^
* OPERATORs_DICT_logic_L AND, NOT, OR', GT...
* OPERATORs_DICT_func_1 sqrt, pow1', abc, neg, mod, sin ... # functions with 1 arg
* OPERATORs_DICT_func_2 pow2 # functions with 2 args
* OPERATORs_DICT_compare1 <, =, > **(= should only be used as a part of '<=', '>=', '==' as explained above)**
* OPERATORs_DICT_compare2 <=, ==, <>, >=
* OPERATORs_PRECEDENCE_DICT functions and operators precedence, obviously
Also, You can use DICT_VARS to look for your variables. You can throw away some operators like 'GT' or 'EQ' - this is the same as '>' and '==' in some CNC and other languages, and not required for You, probably.
<font color="#c03c15">PS: This is my first attempt to share code with others, tell me if something wrong.</font>
Raw data
{
"_id": null,
"home_page": "https://github.com/wolkolak/postfixcalc",
"name": "token-posfix-calculation",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "python algorithm postfix calculation",
"author": "wolkolak1",
"author_email": "e.a.z.y.machining@gmail.com",
"download_url": null,
"platform": null,
"description": "### EZmachining\r\n\r\n![image](https://raw.githubusercontent.com/wolkolak/postfixcalc/main/icon.png)\r\n\r\n# String Expression Calculation\r\nThe project can translate infix expressions to postfix(str to tuple with members of different types). \r\nAnd can calculate if needed. \r\n\r\nUsed algorithm from **[\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043e\u0447\u043d\u043e\u0439 \u0441\u0442\u0430\u043d\u0446\u0438\u0438](https://ru.wikipedia.org/wiki/\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c_\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043e\u0447\u043d\u043e\u0439_\u0441\u0442\u0430\u043d\u0446\u0438\u0438)** ,\r\nalso known as **[Shunting yard algorithm](https://en.wikipedia.org/wiki/Shunting_yard_algorithm)**. I used less detailed russian wiki and had no choice but improove it a little - degree('^') handler added. Unary minus was created too - better fix negatives in postfixing than in calculating.\r\n\r\n\r\nYou can see project here https://github.com/wolkolak/postfixcalc\r\n\r\nInitially I tried to find suitable module on PYPI but failed unfortunately: \r\n\r\n<font color=\"#089F0\">**Firstly**</font> expression can contain functions: <font color=\"#c589F0\">**sin**</font>, <font color=\"#c589F0\">**pow**</font>, <font color=\"#c589F0\">**mod**</font>, <font color=\"#c589F0\">**neg**</font>, etc. Most projects can't work with that.\r\n<details> \r\n <summary>Just why? There is no way for real expressions to not contain any functions. You need <font \r\ncolor=\"#c589F0\">sin</font> and <font color=\"#c589F0\">cos</font> at least.</summary>\r\n Is trigonometry only for sinners? I don't think so.\r\n</details>\r\n\r\n<font color=\"#089F0\">**Secondly**</font> module should handle logic operators too: <font \r\ncolor=\"#f03c15\">**'<'**</font> , <font color=\"#f03c15\">**'=='**</font> , <font color=\"#f03c15\">**'AND'**</font> , \r\n<font color=\"#f03c15\">**'OR'**</font> , etc. And <font color=\"#c589F0\">**variables**</font>, too.\r\n\r\n<font color=\"#089F0\">**The third point**</font> - i need to create postfix expressions **tens of times**, and calculate it **thousands of times**.\r\nBecause of that postfix expressions had to be turned into **tuples**. Entire module is a part of my CNC interpreter.\r\n\r\n<font color=\"#089F0\">**Fourth point**</font> - I don't want to see \"divided by zero error\", so calculator should return None in that case.\r\n\r\n----\r\nTo calculate infix expression You need next functions:\r\n1. <font color=\"#1589F0\">tokenize</font>\\\r\na = tokenize(<font color=\"#089F0\">'-2^ -(sin(5)*3)</font>')\\\r\n print(a)\\\r\n->><font color=gray>['-', 2.0, '^', '(', '-', '(', 'sin', '(', 5.0, ')', '*', 3.0, ')', ')']</font>'\r\n2. <font color=\"#1589F0\">tokensPostfixing</font>\\\r\n b = tokensPostfixing(a)\\\r\n print(b)\\\r\n --><font color=gray>(2.0, 5.0, 'sin', 3.0, '*', '_', '^', '_')</font>'\r\n3. <font color=\"#1589F0\">postfixTokenCalc</font>\\\r\n print(postfixTokenCalc(b, DICT_VARS=None))\\\r\n <font color=\"gray\">-0.8342390624578879</font>\\\r\n dict_A = {'x': 5}\\\r\n print(postfixTokenCalc(('x', 1.0, '+', 6, '=='), DICT_VARS=dict_A))\\\r\n <font color=\"gray\">True</font>\r\n \r\n print('complex?: ', postfixTokenCalc((5, 3j, '-',)))\\\r\n <font color=\"gray\">complex?: (5-3j)</font>\r\n \r\n\r\nAs you can see, even complex numeric type didn't break the program. For now. I do not require complex in CNC, so I run only one test with it.\\\r\nAnd '=' is not a mathematical or logical operator - your expression for calculation should not contain assignments in the middle(You can start from \"=\" though). Best time to handle assignments would be after tokenization, I believe. \r\n\r\n\r\nIf You need different operators and functions (or sin in radians for example), look at the followed dicts and modify:\r\n\r\n* OPERATORs_DICT_math: +, -, /, *, ^\r\n* OPERATORs_DICT_logic_L AND, NOT, OR', GT...\r\n* OPERATORs_DICT_func_1 sqrt, pow1', abc, neg, mod, sin ... # functions with 1 arg\r\n* OPERATORs_DICT_func_2 pow2 # functions with 2 args\r\n* OPERATORs_DICT_compare1 <, =, > **(= should only be used as a part of '<=', '>=', '==' as explained above)**\r\n* OPERATORs_DICT_compare2 <=, ==, <>, >=\r\n* OPERATORs_PRECEDENCE_DICT functions and operators precedence, obviously\r\n\r\nAlso, You can use DICT_VARS to look for your variables. You can throw away some operators like 'GT' or 'EQ' - this is the same as '>' and '==' in some CNC and other languages, and not required for You, probably.\r\n\r\n<font color=\"#c03c15\">PS: This is my first attempt to share code with others, tell me if something wrong.</font>\r\n",
"bugtrack_url": null,
"license": null,
"summary": "Tokeniztion, posfixing and postfix calculation",
"version": "0.0",
"project_urls": {
"Homepage": "https://github.com/wolkolak/postfixcalc"
},
"split_keywords": [
"python",
"algorithm",
"postfix",
"calculation"
],
"urls": [],
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "wolkolak",
"github_project": "postfixcalc",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "token-posfix-calculation"
}