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

Docstring Conventions #106

Open
5 tasks done
lsetiawan opened this issue Sep 29, 2017 · 8 comments
Open
5 tasks done

Docstring Conventions #106

lsetiawan opened this issue Sep 29, 2017 · 8 comments

Comments

@lsetiawan
Copy link
Member

lsetiawan commented Sep 29, 2017

This Issue follows up #105 (comment).

We need a set of conventions that we should follow when writing docstring within the functions and classes:

  • Follow the google style documentation as discussed in Documentation standard? #97. Official example here (and for reference, here's a comparison to the numpy style)
  • Don't say "defaults to ____" unless it needs further explanation. The default value is already available in the method/function definition.
  • If function needs to be instantiated, explicitly show in example. See here for discussion of class vs instance methods.
  • Provide link to Controlled Vocabulary if it needs CV as value.
  • Other code comments besides docstrings must use # rather than triple quotes, because all triple quotes, regardless of where they're found will be interpreted as doctrings by Sphinx.

Currently (10/1) one of the best docstrings available as an example is in ReadODM2.getAffiliations

cc @emiliom

Please add more as necessary.

@lsetiawan
Copy link
Member Author

@emiliom Do you think that it's necessary to add Examples to docstring for every function under ReadODM2?

@ocefpaf
Copy link
Member

ocefpaf commented Sep 29, 2017

@emiliom one topic we did not discussed is how to use the example section of the docstrings, specially for the classes methods.

For example, when adding an example for one can:

  1. add a simple overarching to the class docstring only;
  2. add a fragment example to each method;
  3. add a full example to each method.

(1) is a good idea when the methods docstrings a self-explanatory and examples would be redundant while (2) could be used to complement (1). (3) can be tedious to write and read and lead to big docs when the classes have many methods.

I usually go for (3) only for small projects and use a mix of (1) and (2) + notebooks with full case examples.

@emiliom
Copy link
Member

emiliom commented Oct 2, 2017

@emiliom Do you think that it's necessary to add Examples to docstring for every function under ReadODM2?

I think they're helpful and we should build towards having them. But one step at a time. First step is documenting the parameters; some of that documentation is already there, but the first step is really to confirm that text is correct (fix it if it isn't), and fix the format to match the Sphinx Google style structure.

@emiliom one topic we did not discussed is how to use the example section of the docstrings, specially for the classes methods.

@ocefpaf, can you add short examples to your comment, to illustrate each of the 3 options you presented? Otherwise I find it hard to visualize.

@emiliom
Copy link
Member

emiliom commented Oct 2, 2017

Summary of overall Sphinx documentation system that's been implemented

Sorry to add stuff here that's not about the docstring convention per se. Ignore this. It's a placeholder (for me, or us) for reference, to summarize from our recent emails (or maybe I should create a markdown document somewhere else?):

  • We're using Sphinx with the Napoleon extension. docstrings are in ReST markup, not markdown.
  • We're using gh-pages for the generated documentation, not readthedocs.org or pythonhosted.org.
  • The documentation lands at http://odm2.github.io/ODM2PythonAPI/ (ie, http://odm2.github.io/).
  • Core document system files are under https://github.com/ODM2/ODM2PythonAPI/tree/master/docs (the _NOTES subdirectory is the old doc directory, preserved just in case. Most of the stuff in there is very old and probably won't be needed)
  • Code documentation is auto-updated via Travis-CI, whenever a commit or PR is merged.
  • The documents auto-generated from the code should ideally be supplemented a bit by complementary, hand-crafted documentation.
  • The system is set up to integrate Jupyter notebooks into the documentation. Here's an example from folium (source notebook is here).
  • Documentation can be versioned, such that the versions are tied to the release versions. From @ocefpaf: As soon as a new release is tagged we branch that version and we'll get the docs in a page like, http://odm2.github.io/ODM2PythonAPI/docs-{{ version }}
  • We're fleshing out a set of conventions for the function/method/class code docstrings (that's the focus of this issue!)
  • This system will be applicable to other https://github.com/ODM2 software.

@ocefpaf
Copy link
Member

ocefpaf commented Oct 2, 2017

@ocefpaf, can you add short examples to your comment, to illustrate each of the 3 options you presented? Otherwise I find it hard to visualize.

Sure.

  1. add a simple overarching example to the class docstring only;
class MyClass(object):
    """In the class docstring we can describe what is the purpose of of MyClass.
        
    Examples:
    >>> my_class = MyClass()
    >>> my_class.my_cool_method()
    results
    >>> my_class.my_other_cool_method() 
    more_results

    def my_cool_method():
    """Terse docstring without the example b/c they are in the overarching class."""

    def my_other_cool_method():
    """Again only docstrings, no examples.
    Note that we don't need examples for all methods when using (1)
    to avoid cluttering the class docstring.
    """
  1. add a fragment example to each method;
class MyClass(object):
    """In the class docstring we can describe what is the purpose of of MyClass."""
        
    def my_cool_method():
    """docstring + example.
    The class instantiation is implicit! We omitted the `my_class = MyClass()`!!

    Examples:
    >>> my_class.my_cool_method()
    results
    """

    def my_other_cool_method():
    """Note that this strategy makes for very readable docs.
    However, it won't allow to run doctests b/c the code examples are fragments.

    Examples:
    >>> my_class.my_other_cool_method()
    more_results
    """
  1. add a full example to each method.
class MyClass(object):
    """In the class docstring we can describe what is the purpose of of MyClass.

    def my_cool_method():
    """Full example with all the steps to get to the result.

    Examples:
    >>> my_class = MyClass()
    >>> my_class.my_cool_method()
    results
    """

    def my_other_cool_method():
    """There will be some redundancy, but the example will be 100% "copy-n-paste-able."

    Examples:
    >>> my_class = MyClass()
    >>> my_class.my_other_cool_method() 
    more_results
    """

@ocefpaf
Copy link
Member

ocefpaf commented Oct 2, 2017

Documentation can be versioned, such that the versions are tied to the release versions. This is not in place yet, I think.

It is in place. We just won't build the old versions. As soon as a new release is tagged we branch that version and we'll get the docs in a page like, http://odm2.github.io/ODM2PythonAPI/docs-{{ version }}

@lsetiawan
Copy link
Member Author

I am going to continue on models doc discussion here from #111 (comment).

This is what the samplingfeatures doc look like:

screenshot 2017-10-11 08 55 06

@emiliom Do we want docs for each of the Sampling Features Attributes or just a listing?

@emiliom
Copy link
Member

emiliom commented Oct 11, 2017

Thanks. @lsetiawan and I have discussed this. We'll keep those additions for now, and make a decision later about whether to add docstrings to class properties (and methods?).

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

No branches or pull requests

3 participants