You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
7.9 KiB

5 months ago
from sympy.core.function import (Derivative, Function)
from sympy.core.numbers import (I, Rational, oo, pi)
from sympy.core.relational import (Eq, Ge, Gt, Le, Lt, Ne)
from sympy.core.symbol import (Symbol, symbols)
from sympy.functions.elementary.complexes import (Abs, conjugate)
from sympy.functions.elementary.exponential import (exp, log)
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.functions.elementary.trigonometric import sin
from sympy.integrals.integrals import Integral
from sympy.matrices.dense import Matrix
from sympy.series.limits import limit
from sympy.printing.python import python
from sympy.testing.pytest import raises, XFAIL
x, y = symbols('x,y')
th = Symbol('theta')
ph = Symbol('phi')
def test_python_basic():
# Simple numbers/symbols
assert python(-Rational(1)/2) == "e = Rational(-1, 2)"
assert python(-Rational(13)/22) == "e = Rational(-13, 22)"
assert python(oo) == "e = oo"
# Powers
assert python(x**2) == "x = Symbol(\'x\')\ne = x**2"
assert python(1/x) == "x = Symbol('x')\ne = 1/x"
assert python(y*x**-2) == "y = Symbol('y')\nx = Symbol('x')\ne = y/x**2"
assert python(
x**Rational(-5, 2)) == "x = Symbol('x')\ne = x**Rational(-5, 2)"
# Sums of terms
assert python(x**2 + x + 1) in [
"x = Symbol('x')\ne = 1 + x + x**2",
"x = Symbol('x')\ne = x + x**2 + 1",
"x = Symbol('x')\ne = x**2 + x + 1", ]
assert python(1 - x) in [
"x = Symbol('x')\ne = 1 - x",
"x = Symbol('x')\ne = -x + 1"]
assert python(1 - 2*x) in [
"x = Symbol('x')\ne = 1 - 2*x",
"x = Symbol('x')\ne = -2*x + 1"]
assert python(1 - Rational(3, 2)*y/x) in [
"y = Symbol('y')\nx = Symbol('x')\ne = 1 - 3/2*y/x",
"y = Symbol('y')\nx = Symbol('x')\ne = -3/2*y/x + 1",
"y = Symbol('y')\nx = Symbol('x')\ne = 1 - 3*y/(2*x)"]
# Multiplication
assert python(x/y) == "x = Symbol('x')\ny = Symbol('y')\ne = x/y"
assert python(-x/y) == "x = Symbol('x')\ny = Symbol('y')\ne = -x/y"
assert python((x + 2)/y) in [
"y = Symbol('y')\nx = Symbol('x')\ne = 1/y*(2 + x)",
"y = Symbol('y')\nx = Symbol('x')\ne = 1/y*(x + 2)",
"x = Symbol('x')\ny = Symbol('y')\ne = 1/y*(2 + x)",
"x = Symbol('x')\ny = Symbol('y')\ne = (2 + x)/y",
"x = Symbol('x')\ny = Symbol('y')\ne = (x + 2)/y"]
assert python((1 + x)*y) in [
"y = Symbol('y')\nx = Symbol('x')\ne = y*(1 + x)",
"y = Symbol('y')\nx = Symbol('x')\ne = y*(x + 1)", ]
# Check for proper placement of negative sign
assert python(-5*x/(x + 10)) == "x = Symbol('x')\ne = -5*x/(x + 10)"
assert python(1 - Rational(3, 2)*(x + 1)) in [
"x = Symbol('x')\ne = Rational(-3, 2)*x + Rational(-1, 2)",
"x = Symbol('x')\ne = -3*x/2 + Rational(-1, 2)",
"x = Symbol('x')\ne = -3*x/2 + Rational(-1, 2)"
]
def test_python_keyword_symbol_name_escaping():
# Check for escaping of keywords
assert python(
5*Symbol("lambda")) == "lambda_ = Symbol('lambda')\ne = 5*lambda_"
assert (python(5*Symbol("lambda") + 7*Symbol("lambda_")) ==
"lambda__ = Symbol('lambda')\nlambda_ = Symbol('lambda_')\ne = 7*lambda_ + 5*lambda__")
assert (python(5*Symbol("for") + Function("for_")(8)) ==
"for__ = Symbol('for')\nfor_ = Function('for_')\ne = 5*for__ + for_(8)")
def test_python_keyword_function_name_escaping():
assert python(
5*Function("for")(8)) == "for_ = Function('for')\ne = 5*for_(8)"
def test_python_relational():
assert python(Eq(x, y)) == "x = Symbol('x')\ny = Symbol('y')\ne = Eq(x, y)"
assert python(Ge(x, y)) == "x = Symbol('x')\ny = Symbol('y')\ne = x >= y"
assert python(Le(x, y)) == "x = Symbol('x')\ny = Symbol('y')\ne = x <= y"
assert python(Gt(x, y)) == "x = Symbol('x')\ny = Symbol('y')\ne = x > y"
assert python(Lt(x, y)) == "x = Symbol('x')\ny = Symbol('y')\ne = x < y"
assert python(Ne(x/(y + 1), y**2)) in [
"x = Symbol('x')\ny = Symbol('y')\ne = Ne(x/(1 + y), y**2)",
"x = Symbol('x')\ny = Symbol('y')\ne = Ne(x/(y + 1), y**2)"]
def test_python_functions():
# Simple
assert python(2*x + exp(x)) in "x = Symbol('x')\ne = 2*x + exp(x)"
assert python(sqrt(2)) == 'e = sqrt(2)'
assert python(2**Rational(1, 3)) == 'e = 2**Rational(1, 3)'
assert python(sqrt(2 + pi)) == 'e = sqrt(2 + pi)'
assert python((2 + pi)**Rational(1, 3)) == 'e = (2 + pi)**Rational(1, 3)'
assert python(2**Rational(1, 4)) == 'e = 2**Rational(1, 4)'
assert python(Abs(x)) == "x = Symbol('x')\ne = Abs(x)"
assert python(
Abs(x/(x**2 + 1))) in ["x = Symbol('x')\ne = Abs(x/(1 + x**2))",
"x = Symbol('x')\ne = Abs(x/(x**2 + 1))"]
# Univariate/Multivariate functions
f = Function('f')
assert python(f(x)) == "x = Symbol('x')\nf = Function('f')\ne = f(x)"
assert python(f(x, y)) == "x = Symbol('x')\ny = Symbol('y')\nf = Function('f')\ne = f(x, y)"
assert python(f(x/(y + 1), y)) in [
"x = Symbol('x')\ny = Symbol('y')\nf = Function('f')\ne = f(x/(1 + y), y)",
"x = Symbol('x')\ny = Symbol('y')\nf = Function('f')\ne = f(x/(y + 1), y)"]
# Nesting of square roots
assert python(sqrt((sqrt(x + 1)) + 1)) in [
"x = Symbol('x')\ne = sqrt(1 + sqrt(1 + x))",
"x = Symbol('x')\ne = sqrt(sqrt(x + 1) + 1)"]
# Nesting of powers
assert python((((x + 1)**Rational(1, 3)) + 1)**Rational(1, 3)) in [
"x = Symbol('x')\ne = (1 + (1 + x)**Rational(1, 3))**Rational(1, 3)",
"x = Symbol('x')\ne = ((x + 1)**Rational(1, 3) + 1)**Rational(1, 3)"]
# Function powers
assert python(sin(x)**2) == "x = Symbol('x')\ne = sin(x)**2"
@XFAIL
def test_python_functions_conjugates():
a, b = map(Symbol, 'ab')
assert python( conjugate(a + b*I) ) == '_ _\na - I*b'
assert python( conjugate(exp(a + b*I)) ) == ' _ _\n a - I*b\ne '
def test_python_derivatives():
# Simple
f_1 = Derivative(log(x), x, evaluate=False)
assert python(f_1) == "x = Symbol('x')\ne = Derivative(log(x), x)"
f_2 = Derivative(log(x), x, evaluate=False) + x
assert python(f_2) == "x = Symbol('x')\ne = x + Derivative(log(x), x)"
# Multiple symbols
f_3 = Derivative(log(x) + x**2, x, y, evaluate=False)
assert python(f_3) == \
"x = Symbol('x')\ny = Symbol('y')\ne = Derivative(x**2 + log(x), x, y)"
f_4 = Derivative(2*x*y, y, x, evaluate=False) + x**2
assert python(f_4) in [
"x = Symbol('x')\ny = Symbol('y')\ne = x**2 + Derivative(2*x*y, y, x)",
"x = Symbol('x')\ny = Symbol('y')\ne = Derivative(2*x*y, y, x) + x**2"]
def test_python_integrals():
# Simple
f_1 = Integral(log(x), x)
assert python(f_1) == "x = Symbol('x')\ne = Integral(log(x), x)"
f_2 = Integral(x**2, x)
assert python(f_2) == "x = Symbol('x')\ne = Integral(x**2, x)"
# Double nesting of pow
f_3 = Integral(x**(2**x), x)
assert python(f_3) == "x = Symbol('x')\ne = Integral(x**(2**x), x)"
# Definite integrals
f_4 = Integral(x**2, (x, 1, 2))
assert python(f_4) == "x = Symbol('x')\ne = Integral(x**2, (x, 1, 2))"
f_5 = Integral(x**2, (x, Rational(1, 2), 10))
assert python(
f_5) == "x = Symbol('x')\ne = Integral(x**2, (x, Rational(1, 2), 10))"
# Nested integrals
f_6 = Integral(x**2*y**2, x, y)
assert python(f_6) == "x = Symbol('x')\ny = Symbol('y')\ne = Integral(x**2*y**2, x, y)"
def test_python_matrix():
p = python(Matrix([[x**2+1, 1], [y, x+y]]))
s = "x = Symbol('x')\ny = Symbol('y')\ne = MutableDenseMatrix([[x**2 + 1, 1], [y, x + y]])"
assert p == s
def test_python_limits():
assert python(limit(x, x, oo)) == 'e = oo'
assert python(limit(x**2, x, 0)) == 'e = 0'
def test_issue_20762():
# Make sure Python removes curly braces from subscripted variables
a_b = Symbol('a_{b}')
b = Symbol('b')
expr = a_b*b
assert python(expr) == "a_b = Symbol('a_{b}')\nb = Symbol('b')\ne = a_b*b"
def test_settings():
raises(TypeError, lambda: python(x, method="garbage"))