"""
Reference Parallel Primitives

These are reference implementations of basic parallel
primitives. These are not actually parallel, but work the same way.
They are good for testing.
"""

from sage.misc.prandom import shuffle


def parallel_iter(f, inputs):
    """
    Reference parallel iterator implementation.

    INPUT:

    - ``f`` -- a Python function that can be pickled using
      the pickle_function command.

    - ``inputs`` -- a list of pickleable pairs (args, kwds), where
      args is a tuple and kwds is a dictionary.

    OUTPUT:

    - iterator over 2-tuples ``(inputs[i], f(inputs[i]))``, where the
      order may be completely random

    EXAMPLES::

        sage: def f(N,M=10): return N*M
        sage: inputs = [((2,3),{}),  (tuple([]), {'M':5,'N':3}), ((2,),{})]
        sage: set_random_seed(0)
        sage: for a, val in sage.parallel.reference.parallel_iter(f, inputs):
        ....:     print((a, val))
        (((2,), {}), 20)
        (((), {'M': 5, 'N': 3}), 15)
        (((2, 3), {}), 6)
        sage: for a, val in sage.parallel.reference.parallel_iter(f, inputs):
        ....:     print((a, val))
        (((), {'M': 5, 'N': 3}), 15)
        (((2,), {}), 20)
        (((2, 3), {}), 6)
    """
    v = list(inputs)
    shuffle(v)
    for args, kwds in v:
        yield ((args, kwds), f(*args, **kwds))
