Repository: pyjanitor-devs/pyjanitor

Issue:
[DOC] API Documentation for Chemistry functions is not standardized
# Brief Description of Fix

<!-- Please describe the fix in terms of a "before" and "after". In other words, what's not so good about the current docs
page, and what you would like to see it become. 

Example starter wording is provided. -->

Currently, the docs do not have a standard docstring format for functions. Some docstrings contain only `Parameters`. Some have `Parameters` and `Method chaining usage`.  Some have a combination of `Parameters`, ` Returns`, `Functional usage example`, and `Method chaining example` but not each one of these pieces.

I would like to propose a change, such that now the docs contain a **standardized** docstring suite. All functions should contain (at a minimum) the following:
  - `Parameters`
  - ` Returns`
  - `Functional usage example`
  - `Method chaining example`

**NOTE**: This can be done for all functions within the `janitor` directory. For ease of review, this will focus on the `chemistry.py` file and move to other files/functions as time permits.

# Relevant Context

<!-- Please put here, in bullet points, links to the relevant docs page. A few starting template points are available
to get you started. -->

- [Link to documentation page](https://pyjanitor.readthedocs.io/reference/chemistry.html)
- [Link to exact file to be edited](https://github.com/ericmjl/pyjanitor/blob/dev/janitor/chemistry.py)


Discussion:
I would like to work on this issue :) Yah docstrings!

Resolving patch:
diff --git a/janitor/biology.py b/janitor/biology.py
--- a/janitor/biology.py
+++ b/janitor/biology.py
@@ -40,8 +40,11 @@ def join_fasta(
 
     .. code-block:: python
 
+        import pandas as pd
         import janitor.biology
 
+        df = pd.DataFrame(...)
+
         df = janitor.biology.join_fasta(
             df=df,
             filename='fasta_file.fasta',
@@ -49,14 +52,16 @@ def join_fasta(
             column_name='sequence',
         )
 
-    Method chaining example:
+    Method chaining usage example:
 
     .. code-block:: python
 
         import pandas as pd
         import janitor.biology
 
-        df = pd.DataFrame(...).join_fasta(
+        df = pd.DataFrame(...)
+
+        df = df.join_fasta(
             filename='fasta_file.fasta',
             id_col='sequence_accession',
             column_name='sequence',
diff --git a/janitor/chemistry.py b/janitor/chemistry.py
--- a/janitor/chemistry.py
+++ b/janitor/chemistry.py
@@ -70,8 +70,8 @@
 @deprecated_alias(smiles_col="smiles_column_name", mols_col="mols_column_name")
 def smiles2mol(
     df: pd.DataFrame,
-    smiles_column_name,
-    mols_column_name,
+    smiles_column_name: str,
+    mols_column_name: str,
     drop_nulls: bool = True,
     progressbar: Union[None, str] = None,
 ) -> pd.DataFrame:
@@ -82,15 +82,33 @@ def smiles2mol(
 
     This method mutates the original DataFrame.
 
-    Method chaining usage:
+    Functional usage example:
 
     .. code-block:: python
 
-        df = (
-            pd.DataFrame(...)
-            .smiles2mol(smiles_column_name='smiles', mols_column_name='mols')
+        import pandas as pd
+        import janitor.chemistry
+
+        df = pd.DataFrame(...)
+
+        df = janitor.chemistry.smiles2mol(
+            df=df,
+            smiles_column_name='smiles',
+            mols_column_name='mols'
         )
 
+    Method chaining usage example:
+
+    .. code-block:: python
+
+        import pandas as pd
+        import janitor.chemistry
+
+        df = pd.DataFrame(...)
+
+        df = df.smiles2mol(smiles_column_name='smiles',
+                           mols_column_name='mols')
+
     A progressbar can be optionally used.
 
     - Pass in "notebook" to show a tqdm notebook progressbar. (ipywidgets must
@@ -105,6 +123,7 @@ def smiles2mol(
     :param drop_nulls: Whether to drop rows whose mols failed to be
         constructed.
     :param progressbar: Whether to show a progressbar or not.
+    :returns: A pandas DataFrame with new RDKIT Mol objects column.
     """
     valid_progress = ["notebook", "terminal", None]
     if progressbar not in valid_progress:
@@ -133,7 +152,7 @@ def smiles2mol(
 @deprecated_alias(mols_col="mols_column_name")
 def morgan_fingerprint(
     df: pd.DataFrame,
-    mols_column_name,
+    mols_column_name: str,
     radius: int = 3,
     nbits: int = 2048,
     kind: str = "counts",
@@ -147,17 +166,65 @@ def morgan_fingerprint(
 
     This method does not mutate the original DataFrame.
 
-    Method chaining usage:
+    Functional usage example:
 
     .. code-block:: python
 
+        import pandas as pd
+        import janitor.chemistry
+
         df = pd.DataFrame(...)
-        morgans = df.morgan_fingerprint(mols_column_name='mols', radius=3,
-                                        nbits=2048)
 
-    If you wish to join the Morgans back into the original dataframe, this
-    can be accomplished by doing a `join`, becuase the indices are
-    preserved:
+        # For "counts" kind
+        morgans = janitor.chemistry.morgan_fingerprint(
+            df=df.smiles2mol('smiles', 'mols'),
+            mols_column_name='mols',
+            radius=3,      # Defaults to 3
+            nbits=2048,    # Defaults to 2048
+            kind='counts'  # Defaults to "counts"
+        )
+
+        # For "bits" kind
+        morgans = janitor.chemistry.morgan_fingerprint(
+            df=df.smiles2mol('smiles', 'mols'),
+            mols_column_name='mols',
+            radius=3,      # Defaults to 3
+            nbits=2048,    # Defaults to 2048
+            kind='bits'    # Defaults to "counts"
+        )
+
+    Method chaining usage example:
+
+    .. code-block:: python
+
+        import pandas as pd
+        import janitor.chemistry
+
+        df = pd.DataFrame(...)
+
+        # For "counts" kind
+        morgans = (
+            df.smiles2mol('smiles', 'mols')
+              .morgan_fingerprint(mols_column_name='mols',
+                                  radius=3,      # Defaults to 3
+                                  nbits=2048,    # Defaults to 2048
+                                  kind='counts'  # Defaults to "counts"
+              )
+        )
+
+        # For "bits" kind
+        morgans = (
+            df.smiles2mol('smiles', 'mols')
+              .morgan_fingerprint(mols_column_name='mols',
+                                  radius=3,    # Defaults to 3
+                                  nbits=2048,  # Defaults to 2048
+                                  kind='bits'  # Defaults to "counts"
+              )
+        )
+
+    If you wish to join the morgan fingerprints back into the original
+    dataframe, this can be accomplished by doing a `join`,
+    because the indices are preserved:
 
     .. code-block:: python
 
@@ -169,7 +236,7 @@ def morgan_fingerprint(
     :param radius: Radius of Morgan fingerprints. Defaults to 3.
     :param nbits: The length of the fingerprints. Defaults to 2048.
     :param kind: Whether to return counts or bits. Defaults to counts.
-    :returns: A pandas DataFrame
+    :returns: A new pandas DataFrame of Morgan fingerprints.
     """
     acceptable_kinds = ["counts", "bits"]
     if kind not in acceptable_kinds:
@@ -199,7 +266,9 @@ def morgan_fingerprint(
 
 @pf.register_dataframe_method
 @deprecated_alias(mols_col="mols_column_name")
-def molecular_descriptors(df: pd.DataFrame, mols_column_name) -> pd.DataFrame:
+def molecular_descriptors(
+    df: pd.DataFrame, mols_column_name: str
+) -> pd.DataFrame:
     """
     Convert a column of RDKIT mol objects into a Pandas DataFrame
     of molecular descriptors.
@@ -222,12 +291,33 @@ def molecular_descriptors(df: pd.DataFrame, mols_column_name) -> pd.DataFrame:
         NumSaturatedRings, NumSpiroAtoms, NumUnspecifiedAtomStereoCenters,
         TPSA.
 
-     Method chaining usage:
+    Functional usage example:
 
     .. code-block:: python
 
+        import pandas as pd
+        import janitor.chemistry
+
         df = pd.DataFrame(...)
-        mol_desc = df.molecular_descriptors(mols_column_name='mols')
+
+        mol_desc = janitor.chemistry.molecular_descriptors(
+            df=df.smiles2mol('smiles', 'mols'),
+            mols_column_name='mols'
+        )
+
+    Method chaining usage example:
+
+    .. code-block:: python
+
+        import pandas as pd
+        import janitor.chemistry
+
+        df = pd.DataFrame(...)
+
+        mol_desc = (
+            df.smiles2mol('smiles', 'mols')
+              .molecular_descriptors(mols_column_name='mols')
+        )
 
     If you wish to join the molecular descriptors back into the original
     dataframe, this can be accomplished by doing a `join`,
@@ -240,7 +330,7 @@ def molecular_descriptors(df: pd.DataFrame, mols_column_name) -> pd.DataFrame:
     :param df: A pandas DataFrame.
     :param mols_column_name: The name of the column that has the RDKIT mol
         objects.
-    :returns: A pandas DataFrame
+    :returns: A new pandas DataFrame of molecular descriptors.
     """
     descriptors = [
         CalcChi0n,
@@ -293,23 +383,46 @@ def molecular_descriptors(df: pd.DataFrame, mols_column_name) -> pd.DataFrame:
 
 @pf.register_dataframe_method
 @deprecated_alias(mols_col="mols_column_name")
-def maccs_keys_fingerprint(df: pd.DataFrame, mols_column_name) -> pd.DataFrame:
+def maccs_keys_fingerprint(
+    df: pd.DataFrame, mols_column_name: str
+) -> pd.DataFrame:
     """
-    Convert a column of RDKIT mol objects into MACCS Keys Fingeprints.
+    Convert a column of RDKIT mol objects into MACCS Keys Fingerprints.
 
     Returns a new dataframe without any of the original data.
     This is intentional to leave the user with the data requested.
 
     This method does not mutate the original DataFrame.
 
-    Method chaining usage:
+    Functional usage example:
+
+    .. code-block:: python
+
+        import pandas as pd
+        import janitor.chemistry
+
+        df = pd.DataFrame(...)
+
+        maccs = janitor.chemistry.maccs_keys_fingerprint(
+            df=df.smiles2mol('smiles', 'mols'),
+            mols_column_name='mols'
+        )
+
+    Method chaining usage example:
 
     .. code-block:: python
 
+        import pandas as pd
+        import janitor.chemistry
+
         df = pd.DataFrame(...)
-        maccs = df.maccs_keys_fingerprint(mols_column_name='mols')
 
-    If you wish to join the molecular descriptors back into the
+        maccs = (
+            df.smiles2mol('smiles', 'mols')
+              .maccs_keys_fingerprint(mols_column_name='mols')
+        )
+
+    If you wish to join the maccs keys fingerprints back into the
     original dataframe, this can be accomplished by doing a `join`,
     because the indices are preserved:
 
@@ -321,7 +434,7 @@ def maccs_keys_fingerprint(df: pd.DataFrame, mols_column_name) -> pd.DataFrame:
     :param df: A pandas DataFrame.
     :param mols_column_name: The name of the column that has the RDKIT mol
         objects.
-    :returns: A pandas DataFrame
+    :returns: A new pandas DataFrame of MACCS keys fingerprints.
     """
 
     maccs = [GetMACCSKeysFingerprint(m) for m in df[mols_column_name]]


Test patch: