Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python code printer #12213

Closed
Upabjojr opened this issue Feb 23, 2017 · 17 comments
Closed

Python code printer #12213

Upabjojr opened this issue Feb 23, 2017 · 17 comments
Labels

Comments

@Upabjojr
Copy link
Contributor

Upabjojr commented Feb 23, 2017

The current Python printer prints expressions in a SymPy-style.

It could be useful to have a printer that prints non-SymPy Python code, for example:

  • Mod(x, 2) as x % 2
  • And(x, y) as x and y instead of SymPy's operator overloaded x & y.

Currently:

  • str( ) is supposed to return a valid Python code that is (with some exceptions/caveats) able to reconstruct the SymPy object.
  • lambdify( ) returns a lambda objects for optimized operations.
@mohit3011
Copy link
Contributor

mohit3011 commented Feb 23, 2017

@Upabjojr , I would like to work on this issue, could you please refer the starting point

@Upabjojr
Copy link
Contributor Author

Better discuss this issue a bit before starting, especially to get an idea of what other community members think about it.

This could potentially clash with the lambdify functionality.

@mohit3011
Copy link
Contributor

Yes, you are right.

@asmeurer
Copy link
Member

Do you mean the printer in sympy.printing.python? I don't think that is used by anything, except for the python function. It isn't used by lambdify.

I agree it would be better to expand the functionality of this. It would be useful to directly codegen to Python. For instance, one could then subclass this to create a CythonPrinter.

It does tie in pretty closely with the LambdaPrinter. They should definitely share some code. I'm not entirely sure what that should look like. LambdaPrinter is constrained in that it needs to print expressions, whereas the python printer can print entire blocks of code (although most everything in Python can be represented as a single expression).

Maybe @bjodah has some ideas?

@asmeurer
Copy link
Member

And I should add that the str printer could be a superclass here, but it shouldn't be considered to be a code generation printer. Aside from what you said that it focuses on SymPy output, it also has a high focus on readability and human consumption, whereas a code generator printer doesn't have that restriction.

@moorepants
Copy link
Member

moorepants commented Feb 24, 2017

I agree this is needed. I've needed it many times and just hacked around the str printer. I think it should likely be separate than lambdify because lambdify does all these import tricks. It should just be another code printer that ties into the rest of the codegen framework.

@asmeurer
Copy link
Member

asmeurer commented Feb 24, 2017

Also, for what it's worth, the lambdify restriction that it prints an expression is not strictly needed. Right now, lambdify works like

return eval('lambda %s: %s' % (args, lambdarepr(expr)))

(roughly). But it could also work like

ns = {}
exec("""
def f(%s):
    return %s
""" % (args, lambdarepr(expr)), {})
return ns['f']

which would open up the possibility to do things like variable assignment inside of the lambdified expression. And then, in the long run, lambdify would just be a wrapper around the python printer. The LambdaRepr (expression only) printer could be kept for backwards compatibility (and it could be useful for general code printing).

@mohit3011
Copy link
Contributor

@Upabjojr , I read about Lambdify as well as about codegen. I don't know about the difficulty of this issue if it is easy to fix then I would like to work. Could you please refer to the starting point for solving this issue.

@Upabjojr
Copy link
Contributor Author

@mohit3011 , I would roughly try to see how lambdify works and figure out a way of printing the generated code instead of evaluating it. Not sure about the difficulty.

@mohit3011
Copy link
Contributor

@asmeurer , could you refer to any starting point on this issue and it's difficulty level. Thanks.

@mohit3011
Copy link
Contributor

@Upabjojr , did you look into this issue further ?

@Upabjojr
Copy link
Contributor Author

Upabjojr commented Mar 1, 2017

did you look into this issue further ?

No.

The way to go is to debug the lambdify function and see if you can reorganize the code to retrieve the expression string. If you feel like doing it, have a try!

@mohit3011
Copy link
Contributor

@Upabjojr , please have a look at #12250

@mohit3011
Copy link
Contributor

@Upabjojr , I looked into lambdify function in lambdify.py and also lambdarepr.py , but I couldn't get anything . Could you please help me

@moorepants
Copy link
Member

moorepants commented Mar 5, 2017

@mohit3011 I suggest reading the documentation on how printing works: http://docs.sympy.org/latest/modules/printing.html as a start.

@Upabjojr
Copy link
Contributor Author

Upabjojr commented Mar 7, 2017

@mohit3011 just debug the code, put some breakpoints and explore the local variables.

Once you understand how the code works, it will be easier to purpose an edit.

This was referenced Jun 25, 2017
@bjodah
Copy link
Member

bjodah commented Aug 14, 2017

Since there is a rudimentary Python code printer now (since gh-12808) should we close this issue? We can open up new issues for the new printer (wishlists and/or bug-reports)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants