# Path: expremigen/patterns/pattern.py
# class Pattern(metaclass=abc.ABCMeta):
#     """
#     abstract base class for a Pattern
#     """
# 
#     def __str__(self):
#         return "{0}".format(self.__class__.__name__)
# 
#     def __repr__(self):
#         return self.__str__()
# 
# Path: expremigen/patterns/utils.py
# def flatten(l):
#     """
# 
#     :param l: list l
#     :return: iterator to flatten list l; Pchord are not flattened
#     """
#     for el in l:
#         if isinstance(el, Pattern) and not isinstance(el, Pchord):
#             yield from flatten(el)
#         else:
#             yield el
# 
# def take(n, iterable):
#     """Return first n items of the iterable as a list"""
#     return itertools.islice(iterable, n)
# 
# Path: expremigen/patterns/utils.py
# def random_permutation(iterable, r=None):
#     """Random selection from itertools.permutations(iterable, r)"""
#     pool = tuple(iterable)
#     r = len(pool) if r is None else r
#     return tuple(random.sample(pool, r))


import copy
import itertools
import sys
from expremigen.patterns.pattern import Pattern
from expremigen.patterns.utils import flatten, take
from expremigen.patterns.utils import random_permutation



class Prand(Pattern):
    """
    Pattern used to draw random numbers from a list
    (numbers may repeat themselves)
    """

    def __init__(self, alist=None, repeats=sys.maxsize):
        """
        pattern that
        :param alist: possible numbers
        :param repeats: how many numbers to draw
        """
        super().__init__()
        if alist is None:
            alist = []
        self.alist = copy.deepcopy(alist)
        self.repeats = repeats

    def __iter__(self):
        # following shuffles the list after repeating

# Path: expremigen/patterns/pattern.py
# class Pattern(metaclass=abc.ABCMeta):
#     """
#     abstract base class for a Pattern
#     """
# 
#     def __str__(self):
#         return "{0}".format(self.__class__.__name__)
# 
#     def __repr__(self):
#         return self.__str__()
# 
# Path: expremigen/patterns/utils.py
# def flatten(l):
#     """
# 
#     :param l: list l
#     :return: iterator to flatten list l; Pchord are not flattened
#     """
#     for el in l:
#         if isinstance(el, Pattern) and not isinstance(el, Pchord):
#             yield from flatten(el)
#         else:
#             yield el
# 
# def take(n, iterable):
#     """Return first n items of the iterable as a list"""
#     return itertools.islice(iterable, n)
# 
# Path: expremigen/patterns/utils.py
# def random_permutation(iterable, r=None):
#     """Random selection from itertools.permutations(iterable, r)"""
#     pool = tuple(iterable)
#     r = len(pool) if r is None else r
#     return tuple(random.sample(pool, r))


# Path: expremigen/patterns/prand.py
import copy
import itertools
import sys
from expremigen.patterns.pattern import Pattern
from expremigen.patterns.utils import flatten, take
from expremigen.patterns.utils import random_permutation




class Prand(Pattern):
    """
    Pattern used to draw random numbers from a list
    (numbers may repeat themselves)
    """

    def __init__(self, alist=None, repeats=sys.maxsize):
        """
        pattern that
        :param alist: possible numbers
        :param repeats: how many numbers to draw
        """
        super().__init__()
        if alist is None:
            alist = []
        self.alist = copy.deepcopy(alist)
        self.repeats = repeats

    def __iter__(self):
        # following shuffles the list after repeating

        return flatten(take(self.repeats, (i for i in random_permutation(