def bisection(f, a, b, tol=1e-6):
    """
    Find a root of function f (i.e., f(x) = 0) within bracket [a, b] using bisection.

    Parameters
    ----------
    f : function
        the function that we are finding a root for: f(x) = 0
    a : float
        left endpoint
    b : float
        right endpoint. note f(a) * f (b) must be < 0, otherwise function will return.
    tol : float
        tolerance for stopping criteria

    Returns
    -------
    x : float
        the root where f(x) = 0
    """

    # check if this is a valid interval.  if not return

    # start while loop, continue while the bracket half-width is > tolerance

        # compute midpoint

        # evaluate function at midpoint

        # check if midpoint is a root (within tolerance), if so return it

        # update new bracket based on sign of f(midpoint)

    # done with while loop, return midpoint as the root