ids = ('C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9')

"""
Explanation: Figure out how to divide an iterable into evenly-sized chunks.
End of explanation
"""


pairs = tuple(itertools.combinations(ids, 2))

len(pairs)

"""
Explanation: Suppose the iterable is a tuple of all possible pairs from ids:
End of explanation
"""


numProc = 16

def get_chunk_lengths(vec, numProc):
    """Get the length of each chunk"""
    numDivFloor = len(vec)//numProc
    lengths = [numDivFloor]*numProc
    remainder = len(vec) - numDivFloor*numProc
    if remainder > len(vec):
        print('Error: remainder greater than vector length')
        return
    else:
        for i in range(remainder):
            lengths[i] += 1
        return lengths

splitlengths = get_chunk_lengths(pairs, numProc)

splitlengths

divpos = np.cumsum([0] + splitlengths)

divpos

len(divpos)

def chunks(divpos, vec):
    for i in range(len(divpos)-1):
        yield vec[divpos[i]:divpos[i+1]]

tuple(chunks(divpos, pairs))

"""
Explanation: Also suppose that there are 16 processors, each operating on a single chunk.
End of explanation
"""


numProc = 7
v = tuple(range(10,75))
splitLengths = get_chunk_lengths(v, numProc)
divpos = np.cumsum([0] + splitLengths)
tuple(chunks(divpos, v))

"""
Explanation: Try it on an iterable that is the range of integers from 10 to 74, with number of processors equal to 7:
End of explanation
"""


