Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sympy solver bug in a for loop?

So I'm playing with Sympy in an effort to build a generic solver/generator of physics problems. One component is that I'm going for a function that will take kwargs and, according to what it got, rearrange the equation and substitute values in it. Thanks to SO, I managed to find the things I need for that.

However..... I've tried putting sympy.solve in a for loop to generate all those expressions and I've ran into.... something.

import sympy
R, U, I, eq = sympy.symbols('R U I eq')
eq = R - U/I
for x in 'RUI':
    print(x)
    print(sympy.solve(eq, x))

The output?

R
[U/I]
U
[I*R]
I
[]

However, whenever I do sympy.solve(eq, I) it works and returns [U/R].

Now, I'm guessing the issue is with sympy using I for imaginary unit and with variable hiding in blocks, but even when I transfer the symbol declaration inside the for loop (and equation as well), I still get the same problem.

I'm not sure I'll need this badly in the end, but this is interesting to say the least.

like image 870
thevoiddancer Avatar asked Mar 02 '26 21:03

thevoiddancer


1 Answers

It's more like an undocumented feature than a bug. The loop for x in 'RUI' is equivalent to for x in ['R', 'U', 'I'], meaning that x runs over one-character strings, not sympy symbols. Insert print(type(x)) in the loop to see this. And note that sympy.solve(eq, 'I') returns [].

The loop for x in [R, U, I] solves correctly for each variable. This is the right way to write this loop.

The surprising thing is that you get anything at all when passing a string as the second argument of solve. Sympy documentation does not list strings among acceptable arguments. Apparently, it tries to coerce the string to a sympy object and does not always guess your meaning correctly: works with sympy.solve(eq, 'R') but not with sympy.solve(eq, 'I')


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!