Opened 8 years ago

Last modified 4 years ago

#18077 needs_work defect

fix docstring printing of constants

Reported by: Ralf Stephan Owned by:
Priority: major Milestone: sage-8.2
Component: documentation Keywords:
Cc: Merged in:
Authors: Ralf Stephan Reviewers: Jeroen Demeyer
Report Upstream: N/A Work issues:
Branch: u/rws/18077 (Commits, GitHub, GitLab) Commit: 281eb93d17c6abba4b88e334e98b1d93c5a11ebf
Dependencies: Stopgaps:

Status badges

Description

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.

Change History (21)

comment:1 Changed 8 years ago by Karl-Dieter Crisman

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

comment:2 Changed 7 years ago by David Einstein

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.

comment:3 in reply to:  2 ; Changed 7 years ago by Karl-Dieter Crisman

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?

comment:4 in reply to:  3 Changed 7 years ago by David Einstein

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.

comment:5 in reply to:  2 Changed 5 years ago by Ralf Stephan

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.

Last edited 5 years ago by Ralf Stephan (previous) (diff)

comment:6 Changed 5 years ago by Ralf Stephan

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

comment:7 Changed 5 years ago by Ralf Stephan

Branch: u/rws/fix_log2_help

comment:8 Changed 5 years ago by Ralf Stephan

Authors: Ralf Stephan
Commit: d080e9e5046ded4e958a421ab422a46ef68494bc
Milestone: sage-6.6sage-8.2
Status: newneeds_review
Summary: fix log2 helpfix docstring printing of constants

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

comment:9 Changed 5 years ago by Jeroen Demeyer

What does the following sentence mean:

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

comment:10 Changed 5 years ago by Jeroen Demeyer

Status: needs_reviewneeds_work

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__

comment:11 Changed 5 years ago by Jeroen Demeyer

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?

comment:12 Changed 5 years ago by Jeroen Demeyer

Reviewers: Jeroen Demeyer

comment:13 in reply to:  9 Changed 5 years ago by Ralf Stephan

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.

comment:14 Changed 5 years ago by Ralf Stephan

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.

comment:15 Changed 5 years ago by Ralf Stephan

Branch: u/rws/fix_log2_helpu/rws/18077

comment:16 Changed 5 years ago by Ralf Stephan

Commit: d080e9e5046ded4e958a421ab422a46ef68494bc6103879df7d0653dcc5b882718540c1d01127b02
Status: needs_workneeds_review

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


New commits:

610387918077: fix docstring printing of constants

comment:17 in reply to:  14 Changed 5 years ago by Jeroen Demeyer

Replying to rws:

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().

comment:18 Changed 5 years ago by Ralf Stephan

Improved branch uploaded.

comment:19 Changed 5 years ago by git

Commit: 6103879df7d0653dcc5b882718540c1d01127b02281eb93d17c6abba4b88e334e98b1d93c5a11ebf

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

281eb93remove duplicate docstring

comment:20 Changed 4 years ago by Jeroen Demeyer

Status: needs_reviewneeds_work

Please rebase to latest master.

comment:21 Changed 4 years ago by Jeroen Demeyer

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

Note: See TracTickets for help on using tickets.