human
Complete this python program:
def helper_funcs(G, orientation):
assistant
#Here is the Python program you requested.

    """These are various G-specific functions that help us implement the algorithm
    for all graph types: graph, multigraph, directed or not.
    """
    ignore_orientation = (G.is_directed() and (orientation == 'ignore'))
    reverse_orientation = (G.is_directed() and (orientation == 'reverse'))
    if ignore_orientation:
        def out_edges(u, **kwds):
            for edge in G.out_edges(u, **kwds):
                (yield (edge + (FORWARD,)))
            for edge in G.in_edges(u, **kwds):
                (yield (edge + (REVERSE,)))
    elif reverse_orientation:
        def out_edges(u, **kwds):
            for edge in G.in_edges(u, **kwds):
                (yield (edge + (REVERSE,)))
    else:
        out_edges = G.edges
    if (ignore_orientation or reverse_orientation):
        def key(edge):
            return edge[:(-1)]
    elif G.is_directed():
        def key(edge):
            return edge
    else:
        def key(edge):
            new_edge = ((frozenset(edge[:2]),) + edge[2:])
            return new_edge
    def traversed_tailhead(edge):
        '\n                                Returns    the    tail    and    head    of    an    edge,    as    it    was    traversed.\n\n                                So    in    general,    this    is    different    from    the    true    tail    and    head.\n                                (Also,    undirected    edges    have    no    true    tail    or    head.)\n\n                                '
        if ((ignore_orientation or reverse_orientation) and (edge[(-1)] == REVERSE)):
            (tail, head) = (edge[1], edge[0])
        else:
            (tail, head) = (edge[0], edge[1])
        return (tail, head)
    return (out_edges, key, traversed_tailhead)