code: def coverage(module_path, verbose=False, no_color=False, sphinx=True):
      """Given a module path, builds an index of all classes and functions
      contained. It then goes through each of the classes/functions to get
      the docstring and doctest coverage of the module."""
  
      # Import the package and find members
      m = None
      try:
          __import__(module_path)
          m = sys.modules[module_path]
      except Exception as a:
          # Most likely cause, absence of __init__
          print(
              "%s could not be loaded due to %s."
              % (module_path, repr(a))
          )
          return 0, 0, 0
  
      c_skipped = []
      c_missing_doc = []
      c_missing_doctest = []
      c_has_doctest = []
      c_indirect_doctest = []
      classes = 0
      c_doctests = 0
      c_sph = []
  
      f_skipped = []
      f_missing_doc = []
      f_missing_doctest = []
      f_has_doctest = []
      f_indirect_doctest = []
      functions = 0
      f_doctests = 0
      f_sph = []
  
      skip_members = ["__abstractmethods__"]
  
      # Get the list of members
      m_members = dir(m)
      for member in m_members:
          # Check for skipped functions first, they throw nasty errors
          # when combined with getattr
          if member in skip_members:
              continue
  
          # Identify if the member (class/def) is a part of this module
          obj = getattr(m, member)
          obj_mod = inspect.getmodule(obj)
  
          # Function not a part of this module
          if not obj_mod or not obj_mod.__name__ == module_path:
              continue
  
          # If it's a function
          if inspect.isfunction(obj) or inspect.ismethod(obj):
              f_dt, f = process_function(
                  member,
                  "",
                  obj,
                  module_path,
                  f_skipped,
                  f_missing_doc,
                  f_missing_doctest,
                  f_indirect_doctest,
                  f_has_doctest,
                  skip_members,
                  f_sph,
                  sphinx=sphinx,
              )
              if f:
                  functions += 1
              if f_dt:
                  f_doctests += 1
  
          # If it's a class, look at it's methods too
          elif inspect.isclass(obj):
              # Process the class first
              c_dt, c, source = process_class(
                  member,
                  obj,
                  c_skipped,
                  c_missing_doc,
                  c_missing_doctest,
                  c_indirect_doctest,
                  c_has_doctest,
                  module_path,
                  c_sph,
                  sphinx=sphinx,
              )
              if not c:
                  continue
              else:
                  classes += 1
              if c_dt:
                  c_doctests += 1
  
              # Iterate through it's members
              for f_name in obj.__dict__:
                  if f_name in skip_members or f_name.startswith("_"):
                      continue
  
                  # Check if def funcname appears in source
                  if not ("def " + f_name) in " ".join(source):
                      continue
  
                  # Identify the module of the current class member
                  f_obj = getattr(obj, f_name)
                  obj_mod = inspect.getmodule(f_obj)
  
                  # Function not a part of this module
                  if not obj_mod or not obj_mod.__name__ == module_path:
                      continue
  
                  # If it's a function
                  if inspect.isfunction(f_obj) or inspect.ismethod(
                      f_obj
                  ):
                      f_dt, f = process_function(
                          f_name,
                          member,
                          obj,
                          module_path,
                          f_skipped,
                          f_missing_doc,
                          f_missing_doctest,
                          f_indirect_doctest,
                          f_has_doctest,
                          skip_members,
                          f_sph,
                          sphinx=sphinx,
                      )
                      if f:
                          functions += 1
                      if f_dt:
                          f_doctests += 1
  
      # Evaluate the percent coverage
      total_doctests = c_doctests + f_doctests
      total_members = classes + functions
      if total_members:
          score = 100 * float(total_doctests) / (total_members)
      else:
          score = 100
      score = int(score)
  
      if sphinx:
          total_sphinx = len(c_sph) + len(f_sph)
          if total_members:
              sphinx_score = (
                  100 - 100 * float(total_sphinx) / total_members
              )
          else:
              sphinx_score = 100
          sphinx_score = int(sphinx_score)
      else:
          total_sphinx = 0
          sphinx_score = 0
  
      # Sort functions/classes by line number
      c_missing_doc = sorted(
          c_missing_doc, key=lambda x: int(x.split()[1][:-1])
      )
      c_missing_doctest = sorted(
          c_missing_doctest, key=lambda x: int(x.split()[1][:-1])
      )
      c_indirect_doctest = sorted(
          c_indirect_doctest, key=lambda x: int(x.split()[1][:-1])
      )
  
      f_missing_doc = sorted(
          f_missing_doc, key=lambda x: int(x.split()[1][:-1])
      )
      f_missing_doctest = sorted(
          f_missing_doctest, key=lambda x: int(x.split()[1][:-1])
      )
      f_indirect_doctest = sorted(
          f_indirect_doctest, key=lambda x: int(x.split()[1][:-1])
      )
  
      print_coverage(
          module_path,
          classes,
          c_missing_doc,
          c_missing_doctest,
          c_indirect_doctest,
          c_sph,
          functions,
          f_missing_doc,
          f_missing_doctest,
          f_indirect_doctest,
          f_sph,
          score,
          total_doctests,
          total_members,
          sphinx_score,
          total_sphinx,
          verbose=verbose,
          no_color=no_color,
          sphinx=sphinx,
      )
  
      return total_doctests, total_sphinx, total_members
  
file_path: sympy/bin/coverage_doctest.py
imports: from __future__ import print_function
  import os
  import sys
  import inspect
  from argparse import ArgumentParser, RawDescriptionHelpFormatter
  from sympy.utilities.misc import filldedent
label_desc: Use image node_id 9 for calling a global function with example usage: coverage(module_path, verbose, no_color, sphinx) and returns: total_doctests,  total_sphinx,  total_members, int,  int,  int