将 AsciiMath 解析为 Python 表达式
Parsing AsciiMath to Python expression
我试图通过 JSON 将 2 个函数传递给 python 脚本,以评估它们的等效性。我遇到的问题是输入采用 AsciiMath 表示法。如果格式与 Python 表达式的格式一致,似乎 sympify
从字符串中解析表达式没有问题。有没有办法将 AsciiMath 符号解析为 Python 可以解释的东西?我一直无法找到任何提供此类功能的库。
PHP:
$data = array("2*x", "x*2"); // returns true as expected
$data = array("2x", "x2"); // AsciiMath notation does not work
$result = shell_exec('python /path/check.py ' . escapeshellarg(json_encode($data)));
Python:
import sys, json
from sympy import *
# Load the json data sent from PHP
try:
data = json.loads(sys.argv[1])
except:
sys.exit(1)
x = Symbol('x')
# Convert string inputs to expressions
user_response = sympify(data[0])
correct_answer = sympify(data[1])
# Perform equivalence comparison
result = user_response == correct_answer
# Return result
print json.dumps(result)
提出这样的问题时,您应该演示问题。这就是我认为正在发生的事情。
使用一组表达式,sympify
工作正常:
In [144]: sympify('2*x')==sympify('x*2')
Out[144]: True
但是另一对:
In [145]: sympify('2x')==sympify('x2')
---------------------------------------------------------------------------
SyntaxError Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/sympy/core/sympify.py in sympify(a, locals, convert_xor, strict, rational, evaluate)
367 a = a.replace('\n', '')
--> 368 expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
369 except (TokenError, SyntaxError) as exc:
...
SympifyError: Sympify of expression 'could not parse '2x'' failed, because of exception being raised:
SyntaxError: invalid syntax (<string>, line 1)
这仅适用于“2x”字符串。对于另一个字符串:
In [146]: sympify('x2')
Out[146]: x₂
sympify
期待可以在 sympy
环境中评估的字符串
Converts an arbitrary expression to a type that can be used inside SymPy.
上面写着 arbitrary
,但是文档的限制有点多,正如所描述的那样。
It currently accepts as arguments:
- any object defined in sympy
- standard numeric python types: int, long, float, Decimal
- strings (like "0.09" or "2e-19")
- booleans, including ``None`` (will leave ``None`` unchanged)
- lists, sets or tuples containing any of the above
在问题的上下文中,这意味着使用 x
的表达式是用
定义的
x = Symbol('x')
但是使用 y
的人会有问题。
===
sympify
产生一个 sympy
表达式:
In [161]: expr = sympify('2*x')
In [162]: type(expr)
Out[162]: sympy.core.mul.Mul
然后可以以各种方式成为 'evaluated'。我可以将其描述为 'modified',除了 sympy
强调表达式是不可变的。这些动作都会产生新的表达式或值:
In [163]: expr.subs(x,21)
Out[163]: 42
In [164]: expr.diff(x)
Out[164]: 2
In [165]: expr.integrate(x)
Out[165]:
2
x
===
核心 Python 解释器也无法评估这样的表达式,
定义一个新的符号和表达式:
In [166]: y = Symbol('y')
In [167]: expr = sympify('2*y')
In [168]: expr
Out[168]: 2⋅y
将 y
重新分配为 Python 整数,不会更改 expr
的值:
In [169]: y = 21
In [170]: expr
Out[170]: 2⋅y
但它确实允许我们计算一个正则 Python 表达式:
In [171]: 2*y
Out[171]: 42
但是使用 x
符号的相同 Python 表达式会生成 sympy
表达式:
In [172]: 2*x
Out[172]: 2⋅x
===
https://docs.sympy.org/latest/modules/parsing.html
这个 parsing
模块可以处理像“2x”这样的表达式。至少文档显示:
(再次在 isympy
会话中):
In [173]: from sympy.parsing.sympy_parser import parse_expr
In [174]: from sympy.parsing.sympy_parser import parse_expr, standard_transformations
...: , implicit_multiplication_application
In [175]: transformations=(standard_transformations + (implicit_multiplication_applic
...: ation,))
In [176]: parse_expr('2x', transformations=transformations)
Out[176]: 2⋅x
In [177]: parse_expr('x2', transformations=transformations)
Out[177]: 2⋅x
所以它确实处理了你的例子,但我对 asciimatch
的了解还不够多,无法知道还有多少其他工作。
该页面还讨论了 LaTeX
解析器,https://docs.sympy.org/latest/modules/parsing.html#experimental-latex-parsing
我试图通过 JSON 将 2 个函数传递给 python 脚本,以评估它们的等效性。我遇到的问题是输入采用 AsciiMath 表示法。如果格式与 Python 表达式的格式一致,似乎 sympify
从字符串中解析表达式没有问题。有没有办法将 AsciiMath 符号解析为 Python 可以解释的东西?我一直无法找到任何提供此类功能的库。
PHP:
$data = array("2*x", "x*2"); // returns true as expected
$data = array("2x", "x2"); // AsciiMath notation does not work
$result = shell_exec('python /path/check.py ' . escapeshellarg(json_encode($data)));
Python:
import sys, json
from sympy import *
# Load the json data sent from PHP
try:
data = json.loads(sys.argv[1])
except:
sys.exit(1)
x = Symbol('x')
# Convert string inputs to expressions
user_response = sympify(data[0])
correct_answer = sympify(data[1])
# Perform equivalence comparison
result = user_response == correct_answer
# Return result
print json.dumps(result)
提出这样的问题时,您应该演示问题。这就是我认为正在发生的事情。
使用一组表达式,sympify
工作正常:
In [144]: sympify('2*x')==sympify('x*2')
Out[144]: True
但是另一对:
In [145]: sympify('2x')==sympify('x2')
---------------------------------------------------------------------------
SyntaxError Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/sympy/core/sympify.py in sympify(a, locals, convert_xor, strict, rational, evaluate)
367 a = a.replace('\n', '')
--> 368 expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
369 except (TokenError, SyntaxError) as exc:
...
SympifyError: Sympify of expression 'could not parse '2x'' failed, because of exception being raised:
SyntaxError: invalid syntax (<string>, line 1)
这仅适用于“2x”字符串。对于另一个字符串:
In [146]: sympify('x2')
Out[146]: x₂
sympify
期待可以在 sympy
环境中评估的字符串
Converts an arbitrary expression to a type that can be used inside SymPy.
上面写着 arbitrary
,但是文档的限制有点多,正如所描述的那样。
It currently accepts as arguments:
- any object defined in sympy
- standard numeric python types: int, long, float, Decimal
- strings (like "0.09" or "2e-19")
- booleans, including ``None`` (will leave ``None`` unchanged)
- lists, sets or tuples containing any of the above
在问题的上下文中,这意味着使用 x
的表达式是用
x = Symbol('x')
但是使用 y
的人会有问题。
===
sympify
产生一个 sympy
表达式:
In [161]: expr = sympify('2*x')
In [162]: type(expr)
Out[162]: sympy.core.mul.Mul
然后可以以各种方式成为 'evaluated'。我可以将其描述为 'modified',除了 sympy
强调表达式是不可变的。这些动作都会产生新的表达式或值:
In [163]: expr.subs(x,21)
Out[163]: 42
In [164]: expr.diff(x)
Out[164]: 2
In [165]: expr.integrate(x)
Out[165]:
2
x
===
核心 Python 解释器也无法评估这样的表达式,
定义一个新的符号和表达式:
In [166]: y = Symbol('y')
In [167]: expr = sympify('2*y')
In [168]: expr
Out[168]: 2⋅y
将 y
重新分配为 Python 整数,不会更改 expr
的值:
In [169]: y = 21
In [170]: expr
Out[170]: 2⋅y
但它确实允许我们计算一个正则 Python 表达式:
In [171]: 2*y
Out[171]: 42
但是使用 x
符号的相同 Python 表达式会生成 sympy
表达式:
In [172]: 2*x
Out[172]: 2⋅x
===
https://docs.sympy.org/latest/modules/parsing.html
这个 parsing
模块可以处理像“2x”这样的表达式。至少文档显示:
(再次在 isympy
会话中):
In [173]: from sympy.parsing.sympy_parser import parse_expr
In [174]: from sympy.parsing.sympy_parser import parse_expr, standard_transformations
...: , implicit_multiplication_application
In [175]: transformations=(standard_transformations + (implicit_multiplication_applic
...: ation,))
In [176]: parse_expr('2x', transformations=transformations)
Out[176]: 2⋅x
In [177]: parse_expr('x2', transformations=transformations)
Out[177]: 2⋅x
所以它确实处理了你的例子,但我对 asciimatch
的了解还不够多,无法知道还有多少其他工作。
该页面还讨论了 LaTeX
解析器,https://docs.sympy.org/latest/modules/parsing.html#experimental-latex-parsing