<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def bisect(a, b, fn, epsilon, target):
 """ The simplest root-finding algorithm. It is extremely reliable. However, it converges slowly for this reason, it is recommended that this only be used after the secant() method has returned None. Args: a: A lower guess of the value you are tying to find. b: A higher guess of the value you are tying to find. fn: A function representing the relationship between the value you are trying to find and the target condition you are trying to satisfy. It should typically be structured in the following way: `def fn(value_trying_to_find):
 funct(value_trying_to_find) - target_desired_from_funct` has a negative relationship with the funct. epsilon: The acceptable error in the target_desired_from_funct. target: The target slope (typically 0 for a local minima or maxima). Returns: root: The value that gives the target_desired_from_funct. References [1] Wikipedia contributors. (2018, December 29). Root-finding algorithm. In Wikipedia, The Free Encyclopedia. Retrieved 18:16, December 30, 2018, from https://en.wikipedia.org/wiki/Root-finding_algorithm#Bisection_method """

    while (abs(b - a) > 2 * epsilon):
        midpoint = (b + a) / 2
        a_t = fn(a)
        b_t = fn(b)
        midpoint_t = fn(midpoint)
        if (a_t - target) * (midpoint_t - target) < 0:
            b = midpoint
        elif (b_t - target) * (midpoint_t - target) < 0:
            a = midpoint
        else:
            return -999

    return midpoint