'Remove data corresponding to the given key.
Parameters
key : tuple
The key to remove
data : int or None
If None, remove the node corresponding to the given key.
If not None, remove only the given data value from the node.
Returns
successful : bool
True if removal was successful, false otherwise'

def remove(self, key, data=None):

    (node, parent) = self.find_node(key)
    if (node is None):
        return False
    if (data is not None):
        if (data not in node.data):
            raise ValueError(u'Data    does    not    belong    to    correct    node')
        elif (len(node.data) > 1):
            node.data.remove(data)
            return True
    if ((node.left is None) and (node.right is None)):
        self._substitute(node, parent, None)
    elif ((node.left is None) and (node.right is not None)):
        self._substitute(node, parent, node.right)
    elif ((node.right is None) and (node.left is not None)):
        self._substitute(node, parent, node.left)
    else:
        curr_node = node.left
        parent = node
        while (curr_node.right is not None):
            parent = curr_node
            curr_node = curr_node.right
        self._substitute(curr_node, parent, curr_node.left)
        node.set(curr_node)
    self.size -= 1
    return True
