human
Complete this python program:
def _calc_spanning_tree():
assistant
#Here is the Python program you requested.

    """Calculates the actual spanning tree
    Returns it as dictionary where the keys are DPID1, and the
    values are tuples of (DPID2, port-num), where port-num
    is the port on DPID1 connecting to DPID2.
    """
    def flip(link):
        return Discovery.Link(link[2], link[3], link[0], link[1])
    adj = defaultdict((lambda : defaultdict((lambda : []))))
    switches = set()
    for l in core.openflow_discovery.adjacency:
        adj[l.dpid1][l.dpid2].append(l)
        switches.add(l.dpid1)
        switches.add(l.dpid2)
    for s1 in switches:
        for s2 in switches:
            if (s2 not in adj[s1]):
                continue
            if (not isinstance(adj[s1][s2], list)):
                continue
            assert (s1 is not s2)
            good = False
            for l in adj[s1][s2]:
                if (flip(l) in core.openflow_discovery.adjacency):
                    adj[s1][s2] = l.port1
                    adj[s2][s1] = l.port2
                    good = True
                    break
            if (not good):
                del adj[s1][s2]
                if (s1 in adj[s2]):
                    del adj[s2][s1]
    q = []
    more = set(switches)
    done = set()
    tree = defaultdict(set)
    while True:
        q = (sorted(list(more)) + q)
        more.clear()
        if (len(q) == 0):
            break
        v = q.pop(False)
        if (v in done):
            continue
        done.add(v)
        for (w, p) in adj[v].iteritems():
            if (w in tree):
                continue
            more.add(w)
            tree[v].add((w, p))
            tree[w].add((v, adj[w][v]))
    if False:
        log.debug('***    SPANNING    TREE    ***')
        for (sw, ports) in tree.iteritems():
            log.debug((('    %i    :    ' % sw) + '    '.join([str(l[0]) for l in sorted(list(ports))])))
        log.debug('*********************')
    return tree