Receiving PyObject instead of Sym while appending result of a sympify to an empty list!

I’m using Julia version 1.1.1 and SymPy package version 1.0.7. There is an interesting behavior that I encountered while writing some codes in Julia which I’m going to share here and ask if there is a better way to deal with it than what I came up with.

So let’s pick up a silly small example just to illustrate the issue.

using SymPy
x=symbols("x,y")
List=["x^2+y","2*x^2+y"]
f=[]
for i in List
       append!(f,sympify(i))
end
diff(f[1],x[1])

Now you get an error!

ERROR: MethodError: no method matching diff(::PyCall.PyObject, ::Sym)

The source of error is that, Julia assigned “PyObject” to entries of the list “f” instead of “Sym”! However if you were defining the list as in the following, you will get “Sym” as the type of the entries.

g=[sympify(List[1]),sympify(List[2])]

Or in the following way.

h=[sympify(List[1])]
append!(h,sympify(List[2]))

So the problem is not from “sympify” or “append!()”, but it is about the list having any “Sym” entry inside before or not, which in case of “f=”, the answer is negative. So as a solution for myself, I came up with the following.

k=[sympify("auxiliary")
for i in List
       append!(k,sympify(i))
end
deleteat!(k,1)

Now everything is fine and “diff(k[1],x[1])” doesn’t show any error.

I’m wondering why should a PyObject jump up when one is working with SymPy in Julia when the user hasn’t specify it. When you look at the output, “^” symbols also has changed to “**” which is a python syntax. I understand that SymPy is a Python package imported into Julia, but I think a Julia user has intention to do computations in Julia and seeing a PyObject instead of Sym in here is not something expected.

Is it a bug or it had a reason for some benefits? I’m just curious to know.

Finally, I will be happy to know if there is another way to avoid this problem. If there will be many lists defining in this way in a code, then I’m not sure it will be a good idea to add an an element first and then delete it at the end for each of these lists.

I just found another way to turn around this issue which is better than adding and removing an auxiliary element. To define my empty list as a one-dimensional array with entries of type Sym and no entry.

f=Array{Sym,1}()

Now everything works fine without need of an extra step in the algorithm.

for i in List
       append!(f,sympify(i))
end
diff(f[1],x[1])
1 Like