Opened 7 years ago

Last modified 3 years ago

#18077 needs_work defect

fix docstring printing of constants

Reported by: rws 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 7 years ago by kcrisman

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 follow-ups: Changed 7 years ago by deinst

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 ; follow-up: Changed 7 years ago by 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?

comment:4 in reply to: ↑ 3 Changed 6 years ago by deinst

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 4 years ago by rws

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 4 years ago by rws (previous) (diff)

comment:6 Changed 4 years ago by rws

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

comment:7 Changed 4 years ago by rws

  • Branch set to u/rws/fix_log2_help

comment:8 Changed 4 years ago by rws

  • Authors set to Ralf Stephan
  • Commit set to d080e9e5046ded4e958a421ab422a46ef68494bc
  • Milestone changed from sage-6.6 to sage-8.2
  • Status changed from new to needs_review
  • Summary changed from fix log2 help to fix 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 follow-up: Changed 4 years ago by jdemeyer

What does the following sentence mean:

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

comment:10 Changed 4 years ago by jdemeyer

  • Status changed from needs_review to needs_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 4 years ago by jdemeyer

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 4 years ago by jdemeyer

  • Reviewers set to Jeroen Demeyer

comment:13 in reply to: ↑ 9 Changed 4 years ago by rws

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 follow-up: Changed 4 years ago by 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.

comment:15 Changed 4 years ago by rws

  • Branch changed from u/rws/fix_log2_help to u/rws/18077

comment:16 Changed 4 years ago by rws

  • Commit changed from d080e9e5046ded4e958a421ab422a46ef68494bc to 6103879df7d0653dcc5b882718540c1d01127b02
  • Status changed from needs_work to needs_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 4 years ago by jdemeyer

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 4 years ago by rws

Improved branch uploaded.

comment:19 Changed 4 years ago by git

  • Commit changed from 6103879df7d0653dcc5b882718540c1d01127b02 to 281eb93d17c6abba4b88e334e98b1d93c5a11ebf

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

281eb93remove duplicate docstring

comment:20 Changed 3 years ago by jdemeyer

  • Status changed from needs_review to needs_work

Please rebase to latest master.

comment:21 Changed 3 years ago by jdemeyer

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

Note: See TracTickets for help on using tickets.