# Buggy code
def pre_order(self, func=(lambda x: x.id)):
    """
    Performs pre-order traversal without recursive function calls.

    When a leaf node is first encountered, ``func`` is called with
    the leaf node as its argument, and its result is appended to
    the list.

    For example, the statement::

       ids = root.pre_order(lambda x: x.id)

    returns a list of the node ids corresponding to the leaf nodes
    of the tree as they appear from left to right.

    Parameters
    ----------
    func : function
        Applied to each leaf ClusterNode object in the pre-order traversal.
        Given the i'th leaf node in the pre-ordeR traversal ``n[i]``, the
        result of func(n[i]) is stored in L[i]. If not provided, the index
        of the original observation to which the node corresponds is used.

    Returns
    -------
    L : list
        The pre-order traversal.

    """

    # Do a preorder traversal, caching the result. To avoid having to do
    # recursion, we'll store the previous index we've visited in a vector.
    n = self.count

    curNode = [None] * (2 * n)
    lvisited = np.zeros((2 * n,), dtype=bool)
    rvisited = np.zeros((2 * n,), dtype=bool)
    curNode[0] = self
    k = 0
    preorder = []
    while k >= 0:
        nd = curNode[k]
        ndid = nd.id
        if nd.is_leaf():
            preorder.append(func(nd))
            k = k - 1
        else:
            if not lvisited[ndid]:
                curNode[k + 1] = nd.left
                lvisited[ndid] = True
                k = k + 1
            elif not rvisited[ndid]:
                curNode[k + 1] = nd.right
                rvisited[ndid] = True
                k = k + 1
            # If we've visited the left and right of this non-leaf
            # node already, go up in the tree.
            else:
                k = k - 1

    return preorder


# Traceback (IndexError)
Traceback (most recent call last):
File "C:\ReproduceError-pre_order.py", line 12, in <module>
left_root_node_ref.pre_order()
File "C:\Python27\lib\site-packages\scipy\cluster\hierarchy.py", line 732, in pre_order
if not lvisited[ndid]:
IndexError: index out of bounds

# Fixed code
def pre_order(self, func=(lambda x: x.id)):
    """
    Performs pre-order traversal without recursive function calls.

    When a leaf node is first encountered, ``func`` is called with
    the leaf node as its argument, and its result is appended to
    the list.

    For example, the statement::

       ids = root.pre_order(lambda x: x.id)

    returns a list of the node ids corresponding to the leaf nodes
    of the tree as they appear from left to right.

    Parameters
    ----------
    func : function
        Applied to each leaf ClusterNode object in the pre-order traversal.
        Given the i'th leaf node in the pre-ordeR traversal ``n[i]``, the
        result of func(n[i]) is stored in L[i]. If not provided, the index
        of the original observation to which the node corresponds is used.

    Returns
    -------
    L : list
        The pre-order traversal.

    """

    # Do a preorder traversal, caching the result. To avoid having to do
    # recursion, we'll store the previous index we've visited in a vector.
    n = self.count

    curNode = [None] * (2 * n)
    lvisited = set()
    rvisited = set()
    curNode[0] = self
    k = 0
    preorder = []
    while k >= 0:
        nd = curNode[k]
        ndid = nd.id
        if nd.is_leaf():
            preorder.append(func(nd))
            k = k - 1
        else:
            if ndid not in lvisited:
                curNode[k + 1] = nd.left
                lvisited.add(ndid)
                k = k + 1
            elif ndid not in rvisited:
                curNode[k + 1] = nd.right
                rvisited.add(ndid)
                k = k + 1
            # If we've visited the left and right of this non-leaf
            # node already, go up in the tree.
            else:
                k = k - 1

    return preorder