### 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": "postfixcalc-advanced",
"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": "https://files.pythonhosted.org/packages/cd/8b/21c49339b2c6099558597bb998c25ef86f5ac0792a5084a84aff0431392d/postfixcalc_advanced-0.1.tar.gz",
"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.1",
"project_urls": {
"Homepage": "https://github.com/wolkolak/postfixcalc"
},
"split_keywords": [
"python",
"algorithm",
"postfix",
"calculation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "da4ee4e4ad5b41ef9bb1961bc74dc478da5a9a08068477ea137ed8cad54e9471",
"md5": "e98d6329165a6a47a4cfa1beb65ca618",
"sha256": "f2bacc72c1c657c30eacd920bb8d26496e5e1c414145b40d9ffd8ea308a0c5de"
},
"downloads": -1,
"filename": "postfixcalc_advanced-0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e98d6329165a6a47a4cfa1beb65ca618",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 13388,
"upload_time": "2024-03-23T09:30:24",
"upload_time_iso_8601": "2024-03-23T09:30:24.374680Z",
"url": "https://files.pythonhosted.org/packages/da/4e/e4e4ad5b41ef9bb1961bc74dc478da5a9a08068477ea137ed8cad54e9471/postfixcalc_advanced-0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "cd8b21c49339b2c6099558597bb998c25ef86f5ac0792a5084a84aff0431392d",
"md5": "8a629d34257e02dcbf9c93ad80f86d34",
"sha256": "a3e1b9eb28e65424d2c5887e81dfc180ab394f7ea72f76a6408d7bca1fc2c0a4"
},
"downloads": -1,
"filename": "postfixcalc_advanced-0.1.tar.gz",
"has_sig": false,
"md5_digest": "8a629d34257e02dcbf9c93ad80f86d34",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 8856,
"upload_time": "2024-03-23T09:30:25",
"upload_time_iso_8601": "2024-03-23T09:30:25.819770Z",
"url": "https://files.pythonhosted.org/packages/cd/8b/21c49339b2c6099558597bb998c25ef86f5ac0792a5084a84aff0431392d/postfixcalc_advanced-0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-03-23 09:30:25",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "wolkolak",
"github_project": "postfixcalc",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "postfixcalc-advanced"
}