postfixcalc-advanced


Namepostfixcalc-advanced JSON
Version 0.1 PyPI version JSON
download
home_pagehttps://github.com/wolkolak/postfixcalc
SummaryTokeniztion, posfixing and postfix calculation
upload_time2024-03-23 09:30:25
maintainerNone
docs_urlNone
authorwolkolak1
requires_pythonNone
licenseNone
keywords python algorithm postfix calculation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ### 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: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  +, -, /, *, ^
* OPERATORs_DICT_logic_L &nbsp; &nbsp;  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND, NOT, OR', GT...
* OPERATORs_DICT_func_1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sqrt, pow1', abc, neg, mod, sin ...  &nbsp; &nbsp; &nbsp;  # functions with 1 arg
* OPERATORs_DICT_func_2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pow2  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # functions with 2 args
* OPERATORs_DICT_compare1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <, =, >  **(= should only be used as a part of '<=', '>=', '==' as explained above)**
* OPERATORs_DICT_compare2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <=, ==, <>, >=
* OPERATORs_PRECEDENCE_DICT &nbsp; &nbsp; &nbsp; 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: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  +, -, /, *, ^\r\n* OPERATORs_DICT_logic_L &nbsp; &nbsp;  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND, NOT, OR', GT...\r\n* OPERATORs_DICT_func_1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sqrt, pow1', abc, neg, mod, sin ...  &nbsp; &nbsp; &nbsp;  # functions with 1 arg\r\n* OPERATORs_DICT_func_2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pow2  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # functions with 2 args\r\n* OPERATORs_DICT_compare1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <, =, >  **(= should only be used as a part of '<=', '>=', '==' as explained above)**\r\n* OPERATORs_DICT_compare2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <=, ==, <>, >=\r\n* OPERATORs_PRECEDENCE_DICT &nbsp; &nbsp; &nbsp; 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"
}
        
Elapsed time: 0.21371s