0

I am trying to include an exec in a function which creates a variable in order to solve an equation using a simple symbol. However, since the solution is created inside an exec, it creates the error: UnboundLocalError: local variable 'sol' referenced before assignment

import sympy as sym
import sympy.parsing.latex as sym_tex # requires sympy 1.2

def symbolic_solver(equation, unknown, some_symbol='x'):   
    expr = equation.replace(unknown, some_symbol)
    eqn = sym_tex.parse_latex(expr)

    exec('%s = sym.Symbol("%s")'%(some_symbol, some_symbol))

    try: # Sometimes Sympy throws a notimplemented error when it can not solve
        exec('sol = sym.solve(eqn, %s)'%(some_symbol))
    except NotImplementedError:
        print('SymPy could not solve the equation.')
        print('Set the solution manually.')
    return sol

equation = 'm\\cdot g\\cdot h_A + \\frac{1}{2}\\cdot m\\cdot {v_A}^2 = m\\cdot g\\cdot h_B + \\frac{1}{2}\\cdot m\\cdot {v_B}^2'
unknown = 'v_B'
sol = symbolic_solver(equation, unknown)

The reason I have to replace the unknown variable in an equation is because SymPy solver can not handle variables which may have subscript, e.g. v_B. In any case, when I don't use a function, simply run it as a script it produces the following solution:

Solution symbolic: [-sqrt(2*g*h_A - 2*g*h_B + v_A**2), sqrt(2*g*h_A - 2*g*h_B + v_A**2)]
Alex Hall
  • 34,833
  • 5
  • 57
  • 89
imranal
  • 656
  • 12
  • 35

1 Answers1

3

You cannot update local variables dynamically, including with exec. See How does exec work with locals?.

All you need to do in your case is:

sol = sym.solve(eqn, sym.Symbol(some_symbol))

There is no need for exec, because there's no need to create a variable which has the same name as the symbol. Objects do not behave differently based on the names of the variables pointing to them.

Alex Hall
  • 34,833
  • 5
  • 57
  • 89