hwt/hdl/frameTmplUtils.py
def iterSort(iterators, cmpFn):
    """
    Sort items from iterators(generators) by alwas selecting item
    with lowest value (min first)

    :return: generator of tuples (origin index, item) where origin index
        is index of iterator in "iterators" from where item commes from
    """
    actual = []
    _iterators = []
    for i, it in enumerate(iterators):
        try:
            a = next(it)
            _iterators.append((i, it))
            actual.append(a)
        except StopIteration:
            continue

    while True:
        if not _iterators:
            return
        elif len(_iterators) == 1:
            originIndex, it = _iterators[0]
            yield originIndex, actual[0]
            for item in it:
                yield originIndex, item
            return

        # select minimum and iterator from where it comes from
        minimum = None
        minimumIndex = None
        secondMin = None
        for i, val in enumerate(actual):
            skipSecMinCheck = False
            if minimum is None:
                minimum = val
                minimumIndex = i
            elif cmpFn(val, minimum):
                secondMin = minimum
                minimum = val
                minimumIndex = i
                skipSecMinCheck = True
            elif not skipSecMinCheck and (
                    secondMin is None or cmpFn(val, secondMin)):
                secondMin = val

        actualI, actualIt = _iterators[minimumIndex]
        while not cmpFn(secondMin, minimum):
            yield (actualI, minimum)
            try:
                minimum = next(actualIt)
            except StopIteration:
                minimum = None
                break

        # consume from actual iterator while
        if minimum is None:
            del _iterators[minimumIndex]
            del actual[minimumIndex]
        else:
            # minimum is not minimum anymore
            actual[minimumIndex] = minimum
def iterSort(iterators, cmpFn):
    """
    Sort items from iterators(generators) by alwas selecting item
    with lowest value (min first)

    :return: generator of tuples (origin index, item) where origin index
        is index of iterator in "iterators" from where item commes from
    """
    actual = []
    _iterators = []
    for i, it in enumerate(iterators):
        try:
            a = next(it)
            _iterators.append((i, it))
            actual.append(a)
        except StopIteration:
            continue

    while True:
        if not _iterators:
            return
        elif len(_iterators) == 1:
            originIndex, it = _iterators[0]
            yield originIndex, actual[0]
            for item in it:
                yield originIndex, item
            return

        # select minimum and iterator from where it comes from
        minimum = None
        minimumIndex = None
        secondMin = None
        for i, val in enumerate(actual):
            skipSecMinCheck = False
            if minimum is None:
                minimum = val
                minimumIndex = i
            elif cmpFn(val, minimum):
                secondMin = minimum
                minimum = val
                minimumIndex = i
                skipSecMinCheck = True
            elif not skipSecMinCheck and (
                    secondMin is None or cmpFn(val, secondMin)):
                secondMin = val

        actualI, actualIt = _iterators[minimumIndex]
        while not cmpFn(secondMin, minimum):
            yield (actualI, minimum)
            try:
                minimum = next(actualIt)
            except StopIteration:
                minimum = None
                break

        # consume from actual iterator while
        if minimum is None:
            del _iterators[minimumIndex]
            del actual[minimumIndex]
        else:
            # minimum is not minimum anymore
            actual[minimumIndex] = minimum
Sort items from iterators(generators) by alwas selecting item
    with lowest value (min first)

    :return: generator of tuples (origin index, item) where origin index
        is index of iterator in "iterators" from where item commes from