Docstrings are an incredibly useful tool in anyone who writes python codes' toolbelt. They are great for letting people know how to use your code.

You should be using docstrings in EVERY class and function definition. Remember that even a poorly styled docstring is better than no context whatsoever so if you are in a hurry at least get the crucial usage details down.

Some terms to help you navigate the post

Docstrings are used to document modules/files, classes, and functions. They help others to understand your code and use it. They are often integrated into IDE's to allow people (and yourself) to quickly see information about using your code including arguments for functions and class instantiation, as well as purpose.

They are also particularly useful for helping YOU to remember how your code works after not working on a code base for a while.

Although there are different styles they all follow the same layout outlined in PEP-257. The format for each type of docstring is as follows

The layout for modules/files is to put the docstring at the top of the file encased in triple quotes. See docstrings.py for more details.

The layout for functions is to put the docstring right after the funcion declaration, the docstring can (should) include information about purpose, usage, arguments, and returm/yield values. For example:

```
def main(x,y):
"""
Takes two arguments, both are ints that will be used to instantiate
a math_operations instance and run it's add_x_y method.
"""
example = math_operations(x,y) # Instantiate using provided x, y values
example.add_x_y() # Run the math_operations instance add_x_y method
```

There are two optional layouts (note that both are often implemented in IDE's and autodocumentation generators).

The first layout is class definition followed on the next line by triple quotes and the information. For example:

```
class math_operations:
"""
This class takes 2 arguments on instantiation to be used with the remaining class functions to complete simple math operations.
"""
```

The second layout is to use the class constructors' docstring to contain the class information.

```
class math_operations:
def __init__(self, x, y):
"""
This class takes 2 arguments on instantiation to be used with the remaining class functions to complete simple math operations.
"""
# Assign arguments to instance variables
self.x = x
self.y = y
```

Style guides are conventions for formatting code. They are prevelant in all languages, there are a few different ones in python, I have outlined a couple of the more popular ones for python later in this file.

Although running the demos are not the point, you can run each file using python `<filename>.py`

Docstrings (and documentation in general) are an essential part of large projects, without them code becomes completely unmanageable, especially for external contributors.

PEP-8 is a popular python style guide, it is very useful for styling python code. Particularly for this demo https://www.python.org/dev/peps/pep-0008/#documentation-strings may be helpful.

There are multiple different 'styles' of docstrings, although (as far as I know) there is no official 'style' I have provided information on the three most popular styles below.

This style is often the 'preffered' style in the python community as it is the most prominent style used for sphinx (http://www.sphinx-doc.org/en/master/index.html) autodocumentation.

For more details about reStructuredtext. SEE: http://docutils.sourceforge.net/rst.html

Example function:

```
def main(x,y):
"""
Instantiates a math_operations instance using the provided values and runs the instance add_x_y method.
:param x: an arbitrary number to be used in instantiating a math_operations instance
:type x: int or float
:param y: an arbitrary number to be used in instantiating a math_operations instance
:type y: int or float
"""
```

This style is my preffered style for it's easy readability and flexibility.

For more details about the full google style guide. http://google.github.io/styleguide/pyguide.html

For details about google style docstrings http://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings

Example function:

```
def main(x,y):
"""
Instantiates a math_operations instance using the provided values and runs the instance add_x_y method.
Args:
x(int or float): an arbitrary number to be used in instantiating a math_operations instance
y(int or float): an arbitrary number to be used in instantiating a math_operations instance
"""
```

This style is used heavily in scientific and complex caculation libraries.

For details about numpy style docstrings https://numpydoc.readthedocs.io/en/latest/format.html

Example function:

```
def main(x,y):
"""
Instantiates a math_operations instance using the provide values and runs the instance add_x_y method.
Parameters
----------
x : int or float
an arbitrary number to be used in other instance methods
y : int or float
an arbitrary number to be used in other instance methods
"""
```

```
""" This is the module/file docstring, this is where you put
information about the module/file purpose, as well as information
about any global variables.
NOTE: There are many different 'styles' of docstrings, there are
examples of the same class & function(s) in some of the different
styles found in the other files in this directory.
"""
# NOTE: it's also worth noting that some people include metadata at the top of their files like author, maintainers etc.
# SEE: http://epydoc.sourceforge.net/manual-fields.html#module-metadata-variables
# For example:
__author__ = "Canadian Coding"
__license__ = "MIT"
__date__ = "2019-07-19"
__version__ = "0.0.1"
class MathOperations:
"""
This is the class docstring, here you can put info about class
variables, relevant documentation reference(s), and basic 'quick start'
info. You can also mention the purpose of the class here, For example:
This class takes 2 arguments on instantiation to be used with the
remaining class functions to complete simple math operations.
"""
def __init__(self, x, y):
"""
Class constructor, takes 2 arguments of arbitrary ints to be
used with the other class methods after instantiation.
"""
# Assign arguments to instance variables
self.x = x
self.y = y
def add_x_y(self):
"""
Takes the provided instance variables, adds them and prints
and returns the result.
"""
print(f"The result of {self.x} + {self.y} is {self.x+self.y}")
return self.x+self.y
def main(x,y):
"""
This is a function docstring, it can be used to provide information
about function usage, arguments, and function purpose. For example:
Takes two arguments, both are ints that will be used to instantiate
a math_operations instance and run it's add_x_y method.
"""
example = math_operations(x,y) # Instantiate using provided x, y values
example.add_x_y() # Run the math_operations instance add_x_y method
if __name__ == "__main__":
main(4,4)
```

```
""" This file is here to demonstrate the Google style of docstrings.
This style is my preffered style for it's easy readability and flexibility.
For more details about the full google style guide.
SEE: http://google.github.io/styleguide/pyguide.html
For details about google style docstrings
SEE: http://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings
"""
class MathOperations:
"""
There are two options for documenting the overall class. You can include
all the information about the class purpose, instance/class paramaters, and
contructor details, before the __init__ mehod or as the __init__ methods' docstring.
In this example file I have done both. Also notice that when using the docstring outside
the __init__ method the heading changes from Args to attributes.
Attributes:
x(int or float): an arbitrary number to be used in other instance methods
y(int or float): an arbitrary number to be used in other instance methods
"""
def __init__(self, x, y):
"""
There are two options for documenting the overall class. You can include
all the information about the class purpose, instance/class paramaters, and
contructor details, before the __init__ mehod or as the __init__ methods' docstring.
In this example file I have done both.
Args:
x(int or float): an arbitrary number to be used in other instance methods
y(int or float): an arbitrary number to be used in other instance methods
"""
# Assign arguments to instance variables
self.x = x
self.y = y
def add_x_y(self):
"""
Takes the provided instance variables, adds them and prints
and returns the result.
Returns:
int: The result of adding the instances x and y variables
"""
print(f"The result of {self.x} + {self.y} is {self.x+self.y}")
return self.x+self.y
def main(x,y):
"""
Instantiates a math_operations instance using the provided values
and runs the instance add_x_y method.
Args:
x(int or float): an arbitrary number to be used in instantiating a math_operations instance
y(int or float): an arbitrary number to be used in instantiating a math_operations instance
"""
example = math_operations(x,y) # Instantiate using provided x, y values
example.add_x_y() # Run the math_operations instance add_x_y method
if __name__ == "__main__":
main(4,4)
```

```
""" This file is here to demonstrate the Numpy style of docstrings.
This style is used heavily in scientific and complex caculation libraries.
For details about numpy style docstrings
SEE: https://numpydoc.readthedocs.io/en/latest/format.html
"""
class MathOperations:
"""
There are two options for documenting the overall class. You can include
all the information about the class purpose, instance/class paramaters, and
contructor details, before the __init__ mehod or as the __init__ methods' docstring.
In this example file I have done both. Also notice that when using the docstring outside
the __init__ method the heading changes from Parameters to Attributes.
Attributes
----------
x : int or float
an arbitrary number to be used in other instance methods
y : int or float
an arbitrary number to be used in other instance methods
"""
def __init__(self, x, y):
"""
There are two options for documenting the overall class. You can include
all the information about the class purpose, instance/class paramaters, and
contructor details, before the __init__ mehod or as the __init__ methods' docstring.
In this example file I have done both.
Parameters
----------
x : int or float
an arbitrary number to be used in other instance methods
y : int or float
an arbitrary number to be used in other instance methods
"""
# Assign arguments to instance variables
self.x = x
self.y = y
def add_x_y(self):
"""
Takes the provided instance variables, adds them and prints
and returns the result.
Returns
-------
int or float
The result of adding the instances x and y variables
"""
print(f"The result of {self.x} + {self.y} is {self.x+self.y}")
return self.x+self.y
def main(x,y):
"""
Instantiates a math_operations instance using the provided values
and runs the instance add_x_y method.
Parameters
----------
x : int or float
an arbitrary number to be used in other instance methods
y : int or float
an arbitrary number to be used in other instance methods
"""
example = math_operations(x,y) # Instantiate using provided x, y values
example.add_x_y() # Run the math_operations instance add_x_y method
if __name__ == "__main__":
main(4,4)
```

```
""" This file is here to demonstrate the reStructured Text style of docstrings.
This style is often the 'preffered' style in the python community as it is the most
prominent style used for sphinx (http://www.sphinx-doc.org/en/master/index.html) autodocumentation.
For more details about reStructuredtext.
SEE: http://docutils.sourceforge.net/rst.html
For details about docstrings in general SEE: docstrings.py and readme.md
"""
class MathOperations:
"""
There are two options for documenting the overall class. You can include
all the information about the class purpose, instance/class paramaters, and
contructor details, before the __init__ mehod or as the __init__ methods' docstring.
In this example file I have done both.
:param x: an arbitrary number to be used in other instance methods
:type x: int or float
:param y: an arbitrary number to be used in other instance methods
:type y: int or float
"""
def __init__(self, x, y):
"""
There are two options for documenting the overall class. You can include
all the information about the class purpose, instance/class paramaters, and
contructor details, before the __init__ mehod or as the __init__ methods' docstring.
In this example file I have done both.
:param x: an arbitrary number to be used in other instance methods
:type x: int or float
:param y: an arbitrary number to be used in other instance methods
:type y: int or float"""
# Assign arguments to instance variables
self.x = x
self.y = y
def add_x_y(self):
"""
Takes the provided instance variables, adds them and prints
and returns the result.
:returns: The result of adding the instances x and y variables
:rtype: int
"""
print(f"The result of {self.x} + {self.y} is {self.x+self.y}")
return self.x+self.y
def main(x,y):
"""
Instantiates a math_operations instance using the provided values
and runs the instance add_x_y method.
:param x: an arbitrary number to be used in instantiating a math_operations instance
:type x: int or float
:param y: an arbitrary number to be used in instantiating a math_operations instance
:type y: int or float
"""
example = math_operations(x,y) # Instantiate using provided x, y values
example.add_x_y() # Run the math_operations instance add_x_y method
if __name__ == "__main__":
main(4,4)
```