sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.3k stars 447 forks source link

fix docstring printing of constants #18077

Open rwst opened 9 years ago

rwst commented 9 years ago

Other constants give more or less specific help but

sage: log2?

Type:           Expression
String form:    log2
Length:         0
File:           /home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression.so
Docstring:
   Nearly all expressions are created by calling
   new_Expression_from_*, but we need to make sure this at least does

This confused me because I first thought I had found the Sage binary log function.

Component: documentation

Author: Ralf Stephan

Branch/Commit: u/rws/18077 @ 281eb93

Reviewer: Jeroen Demeyer

Issue created by migration from https://trac.sagemath.org/ticket/18077

kcrisman commented 9 years ago
comment:1

That's interesting, because here exactly this constant is used to show how awesome the interactive help is! So something is messed up.

deinst commented 9 years ago
comment:2

This appears to be broken for most constants declared in sage/symbolic/constants.py with the exception of e.

I would expect that Expression would have a custom _sage_doc function that would reroute the help request to the appropriate class, but no such function seems to exist, or to ever have existed. If someone indicates how this should work, I'll be glad to try to fix it.

On a not entirely unrelated note: The format of the help has changed somewhat from what is written in the tutorial.

kcrisman commented 9 years ago
comment:3

On a not entirely unrelated note: The format of the help has changed somewhat from what is written in the tutorial.

Can you be more specific?

deinst commented 9 years ago
comment:4

Replying to @kcrisman:

On a not entirely unrelated note: The format of the help has changed somewhat from what is written in the tutorial.

Can you be more specific?

I thought I had answered this a while ago. Obviously I got distracted.

The tutorial help for tan (gotten locally from file:///Users/davideinstein/projects/sage/src/doc/output/html/en/tutorial/tour_help.html looks like:

sage: tan?
Type:        <class 'sage.calculus.calculus.Function_tan'>
Definition:  tan( [noargspec] )
Docstring:

    The tangent function

    EXAMPLES:
        sage: tan(pi)
        0
        sage: tan(3.1415)
        -0.0000926535900581913
        sage: tan(3.1415/4)
        0.999953674278156
        sage: tan(pi/4)
        1
        sage: tan(1/2)
        tan(1/2)
        sage: RR(tan(1/2))
        0.546302489843790

If I run tan? in sage 6.7 I get

Type:           Function_tan
String form:    tan
File:           ~/projects/sage/local/lib/python2.7/site-packages/sage/functions/trig.py
Docstring:
   The tangent function.

   EXAMPLES:

      sage: tan(pi)
      0
      sage: tan(3.1415)
      -0.0000926535900581913
      sage: tan(3.1415/4)
      0.999953674278156
      sage: tan(pi/4)
      1
      sage: tan(1/2)
      tan(1/2)
      sage: RR(tan(1/2))
      0.546302489843790

   We can prevent evaluation using the "hold" parameter:

      sage: tan(pi/4,hold=True)
      tan(1/4*pi)

   To then evaluate again, we currently must use Maxima via
   "sage.symbolic.expression.Expression.simplify()":

      sage: a = tan(pi/4,hold=True); a.simplify()
      1

   TESTS:

      sage: conjugate(tan(x))
      tan(conjugate(x))
      sage: tan(complex(1,1))     # rel tol 1e-15
      (0.2717525853195118+1.0839233273386946j)

Init docstring:
   The tangent function.

   EXAMPLES:

      sage: tan(pi)
      0
      sage: tan(3.1415)
      -0.0000926535900581913
      sage: tan(3.1415/4)
      0.999953674278156
      sage: tan(pi/4)
      1
      sage: tan(1/2)
      tan(1/2)
      sage: RR(tan(1/2))
      0.546302489843790

   We can prevent evaluation using the "hold" parameter:

      sage: tan(pi/4,hold=True)
      tan(1/4*pi)

   To then evaluate again, we currently must use Maxima via
   "sage.symbolic.expression.Expression.simplify()":

      sage: a = tan(pi/4,hold=True); a.simplify()
      1

   TESTS:

      sage: conjugate(tan(x))
      tan(conjugate(x))
      sage: tan(complex(1,1))     # rel tol 1e-15
      (0.2717525853195118+1.0839233273386946j)
Call docstring:
   Wrapper around "BuiltinFunction.__call__()" which converts Python
   >>``<<int``s which are returned by Ginac to Sage Integers.

   This is needed to fix http://trac.sagemath.org/10133, where Ginac
   evaluates "sin(0)" to the Python int "0":

      sage: from sage.symbolic.function import BuiltinFunction
      sage: out = BuiltinFunction.__call__(sin, 0)
      sage: out, parent(out)
      (0, <type 'int'>)

   With this wrapper we have:

      sage: out = sin(0)
      sage: out, parent(out)
      (0, Integer Ring)

   However, if all inputs are Python types, we do not convert:

      sage: out = sin(int(0))
      sage: (out, parent(out))
      (0, <type 'int'>)
      sage: out = arctan2(int(0), float(1))
      sage: (out, parent(out))
      (0, <type 'int'>)
      sage: out = arctan2(int(0), RR(1))
      sage: (out, parent(out))
      (0, Integer Ring)

The Type: is shorter. The module information is now in the new File: line. The Definition: has been kidnapped by aliens, possibly replaced by the less informative String Form:. The Init Docstring and Call Docstring have been added.

rwst commented 6 years ago
comment:5

Replying to @deinst:

This appears to be broken for most constants declared in sage/symbolic/constants.py with the exception of e.

This works because e is not a PyObject embedded in an Expression like pi (where pi.pyobject() returns that object). e has its own class, and so its own docstring. e.is_constant() returns True because is_constant() just checks that there are no variables present.

I would expect that Expression would have a custom _sage_doc function that would reroute the help request to the appropriate class, but no such function seems to exist, or to ever have existed. If someone indicates how this should work, I'll be glad to try to fix it.

Well, _sage_doc()_ apparently(?) has nothing to do with what IPython prints when appending ? to an object (same as giving the %pdoc magic). This is some other help mechanism.

rwst commented 6 years ago
comment:6

Okay, there is now sage.docs.instancedoc. This will work.

rwst commented 6 years ago

Branch: u/rws/fix_log2_help

rwst commented 6 years ago

Commit: d080e9e

rwst commented 6 years ago

Author: Ralf Stephan

rwst commented 6 years ago
comment:8

The uninformative docstring from the Expression class that follows the constant docstring will be improved in another ticket.

Please review.


New commits:

d080e9e18077: fix docstring printing of constants
jdemeyer commented 6 years ago
comment:9

What does the following sentence mean:

Instances of constants are usually embedded as ``PyObject`` in
a symbolic expression.
jdemeyer commented 6 years ago
comment:10

Can you move the doctest to the _instancedoc_ method? It seems like it would best fit there. I would also want to see a doctest for the __doc__ of an Expression which is not a constant, something like (sin(x) + 1).__doc__

jdemeyer commented 6 years ago
comment:11

I'm not convinced by the except AttributeError. It seems that every object has a __doc__, but it could be empty. So instead of the AttributeError, it would be better to do something like:

doc = self.pyobject().__doc__
if doc:
    return doc
return type(self).__doc__   # Isn't self.__doc__ an infinite recursion?
jdemeyer commented 6 years ago

Reviewer: Jeroen Demeyer

rwst commented 6 years ago
comment:13

Replying to @jdemeyer:

What does the following sentence mean:

Instances of constants are usually embedded as ``PyObject`` in
a symbolic expression.

Does this make more sense? Instances of constants are usually embedded in a symbolic expression.

rwst commented 6 years ago
comment:14

I'll also move the orphaned docstring for I to the file where it is defined, because at the moment the reference manual associates it with the wrong object.

rwst commented 6 years ago

Changed branch from u/rws/fix_log2_help to u/rws/18077

rwst commented 6 years ago
comment:16

Note that I also improved docstrings for the class, init, and call slots. Suggestions welcome.


New commits:

610387918077: fix docstring printing of constants
rwst commented 6 years ago

Changed commit from d080e9e to 6103879

jdemeyer commented 6 years ago
comment:17

Replying to @rwst:

I'll also move the orphaned docstring for I to the file where it is defined, because at the moment the reference manual associates it with the wrong object.

You can just remove that docstring. For some reason, it is an identical copy of a docstring in init_pynac_I().

rwst commented 6 years ago
comment:18

Improved branch uploaded.

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Branch pushed to git repo; I updated commit sha1. New commits:

281eb93remove duplicate docstring
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 6103879 to 281eb93

jdemeyer commented 5 years ago
comment:20

Please rebase to latest master.

jdemeyer commented 5 years ago
comment:21

I'm also wondering whether this could help with #26492 and/or #26297