# Here you create the method of the node object that will return the generator
from spacy.symbols import obj


def _get_child_candidates(self, distance, min_dist, max_dist):
    # Here is the code that will be called each time you use the generator object:

    # If there is still a child of the node object on its left
    # AND if distance is ok, return the next child
    if self._leftchild and distance - max_dist < self._median:
        yield self._leftchild

    # If there is still a child of the node object on its right
    # AND if distance is ok, return the next child
    if self._rightchild and distance + max_dist >= self._median:
        yield self._rightchild

    # If the function arrives here, the generator will be considered empty
    # there is no more than two values: the left and the right children

    # Create an empty list and a list with the current object reference
    result, candidates = list(), [self]

    # Loop on candidates (they contain only one element at the beginning)
    while candidates:

        # Get the last candidate and remove it from the list
        node = candidates.pop()

        # Get the distance between obj and the candidate
        distance = node._get_dist(obj)

        # If distance is ok, then you can fill the result
        if distance <= max_dist and distance >= min_dist:
            result.extend(node._values)

        # Add the children of the candidate in the candidates list
        # so the loop will keep running until it will have looked
        # at all the children of the children of the children, etc. of the candidate
        candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))

    return result
