<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def purcell_bidirectional(target, r_toroid, num_points=1e2, surface_tension='pore.surface_tension', contact_angle='pore.contact_angle', throat_diameter='throat.diameter', pore_diameter='pore.diameter'):
 r""" Computes the throat capillary entry pressure assuming the throat is a toroid. Makes use of the toroidal meniscus model with mode touch. This model accounts for mensicus protrusion into adjacent pores and touching solid features. It is bidirectional becauase the connected pores generally have different sizes and this determines how far the meniscus can protrude. Parameters target : OpenPNM Object The object for which these values are being calculated. This controls the length of the calculated array, and also provides access to other necessary thermofluid properties. r_toroid : float or array_like The radius of the toroid surrounding the pore num_points : float (Default 100) The number of divisions to make along the profile length to assess the meniscus properties in order to find the touch length. surface_tension : dict key (string) The dictionary key containing the surface tension values to be used. If a pore property is given, it is interpolated to a throat list. contact_angle : dict key (string) The dictionary key containing the contact angle values to be used. If a pore property is given, it is interpolated to a throat list. throat_diameter : dict key (string) The dictionary key containing the throat diameter values to be used. pore_diameter : dict key (string) The dictionary key containing the pore diameter values to be used. Notes """

    network = target.project.network
    conns = network['throat.conns']
    values = {}
    for p in range(2):
        network['throat.temp_diameter'] = network[pore_diameter][conns[:, p]]
        key = 'throat.touch_pore_'+str(p)
        target.add_model(propname=key,
                         model=pm.meniscus.toroidal,
                         mode='touch',
                         r_toroid=r_toroid,
                         num_points=num_points,
                         throat_diameter=throat_diameter,
                         surface_tension=surface_tension,
                         contact_angle=contact_angle,
                         touch_length='throat.temp_diameter')
        values[p] = target[key]
        target.remove_model(key)
    del network['throat.temp_diameter']
    return np.vstack((values[0], values[1])).T