On Fri, Jun 20, 2008 at 11:49 AM, Riccardo Gori <[EMAIL PROTECTED]> wrote: > > On Friday 20 June 2008 10:31:15 Ondrej Certik wrote: >> On Thu, Jun 19, 2008 at 3:20 PM, Riccardo Gori <[EMAIL PROTECTED]> wrote: >> > Hello, >> > I'm working at fixing issue 888. It is easy to fix but I don't understand >> > why in sympy/utilities/lambdify.py I found that lambdastr function does >> > use __str__ for expr. >> > >> > def lambdastr(args, expr): >> > """ >> > Returns a string that can be evaluated to a lambda function. >> > >> > >>> from sympy import symbols >> > >>> x,y,z = symbols('xyz') >> > >>> lambdastr(x, x**2) >> > >> > 'lambda x: (x**2)' >> > >> > >>> lambdastr((x,y,z), [z,y,x]) >> > >> > 'lambda x,y,z: ([z, y, x])' >> > """ >> > # Transform everything to strings. >> > expr = str(expr) >> > if isinstance(args, str): >> > pass >> > elif hasattr(args, "__iter__"): >> > args = ",".join(str(a) for a in args) >> > else: >> > args = str(args) >> > >> > return "lambda %s: (%s)" % (args, expr) >> > >> > But in python doc we can read: >> > >> > (http://docs.python.org/ref/customization.html) >> > ################################ >> > __repr__( self) >> > Called by the repr() built-in function and by string conversions >> > (reverse quotes) to compute the ``official'' string representation of an >> > object. If at all possible, this should look like a valid Python >> > expression that could be used to recreate an object with the same value >> > (given an appropriate environment). If this is not possible, a string of >> > the form "<...some useful description...>" should be returned. The return >> > value must be a string object. If a class defines __repr__() but not >> > __str__(), then __repr__() is also used when an ``informal'' string >> > representation of instances of that class is required. >> > >> > This is typically used for debugging, so it is important that the >> > representation is information-rich and unambiguous. >> > >> > __str__( self) >> > Called by the str() built-in function and by the print statement to >> > compute the ``informal'' string representation of an object. This differs >> > from __repr__() in that it does not have to be a valid Python expression: >> > a more convenient or concise representation may be used instead. The >> > return value must be a string object. >> > ################################ >> > >> > As I understand __repr__ should be used to have a pythonic valid >> > expression and __str__ should be a normal string. But sympy Basic >> > __repr__ >> > implementation returns unicode text with repr_level_2 so we can't use it >> > in eval(). >> > >> > This is also discussed in issue 697. >> > >> > I suggest to change this behaviour, so we can make lambdify more robust. >> > Is someone working at this? >> >> Hi Riccardo, >> >> sorry for a late reply, I am at a PMAA08[1] conference now, so I get >> to emails sporadically. >> >> please go ahead and fix the __repr__ and __str__ methods. As you >> rightly cited, let's follow the python policy, i.e. __repr__ to be >> something evaluable (or at least something that sympify can handle) >> and __str__ a normal string. And get rid of set_repr_level() >> completely. Let's use >> >> pprint >> >> for nice unicdoe asciiart printing and other methods for other style >> of printing. >> >> The only thing I am not sure now -- what should be the difference >> between __str__ and __repr__ then? I know we discussed it in the >> issues, but I don't think we came to a conclusion. I think the __str__ >> should return a good looking string, but this behaviour should not >> change using some global state (set_repr_level). Then there should be >> functions like pprint, or print_tree or print_unicode to do other >> kinds of printing. And as to __repr__, I know it should be something >> evaluable, but the quesiton is, whether >> >> (sympify(1)/2).__repr__ >> >> should return "1/2" or "sympify(1)/2" (or something else). Note, that >> in isympy, we use the "pprint" method, so the comfort way of using >> sympy will not change by how __repr__ looks like. If you use regular >> python shell, you can also easily hook up pprint, e.g. >> >> >>> from sympy import pprint >> >>> import sys >> >>> sys.displayhook = pprint >> >>> from sympy.abc import x >> >>> x >> >> x >> >> >>> x**2 >> >> 2 >> x >> >> so it seems to me, that __repr__ should really return something that >> you can directly evaluate, i.e. >> >> (sympify("1/2").__repr_ >> >> should return sympify(1)/2, or Integer(1)/2, or something like that. > > Hello, > I think that repr() should return an evaluable expression that returns the > same type of the called object: > i.e. > > In [1]: Basic.set_repr_level(0) > Out[1]: 1 > > In [2]: repr(sympify("1/2")) > Out[2]: Half(1, 2) > > It should not returns 1/2 because evaluating 1/2 returns a float: > > In [3]: Basic.set_repr_level(1) > Out[3]: 0 > > In [4]: repr(sympify("1/2")) > Out[4]: 1/2 > > In [5]: type(eval(repr(sympify("1/2")))) > Out[5]: <type 'float'> > > In this particoular case the problem is that Half is not imported in the > namespace so we can't evaluate it, so a solution is to implement __repr__ > that returns a function that returns an Half(): something like: > > In: repr(sympify("1/2")) > Out: Rational(1,2) > In: type(Rational(1,2)) > Out: <class 'sympy.core.numbers.Half'>
Yes, I agree with this. Also, let's get rid of set_repr_level()? This is quite an important change, so I'd like to hear opinions of others as well. Ondrej --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to sympy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sympy?hl=en -~----------~----~----~----~------~----~------~--~---