<gh_stars>0
from multiprocessing.pool import ThreadPool, Pool
from typing import Any, List, Callable, Sequence, TypeVar, Optional, Iterable
from functools import partial

from tqdm import tqdm

T = TypeVar('T')


def apply_map(func: Callable[[T], Any], sequence: Sequence[T],
              parallelism: Optional[str], show_progress: bool, tqdm_description: str = None) -> List:
    chunksize = max(int(len(sequence) / 1000), 1)
    map_func = _choose_map_func(parallelism, chunksize)
    map_generator = map_func(func, sequence)
    if show_progress:
        map_generator = tqdm(map_generator, desc=tqdm_description, total=len(sequence))
    objects = list(map_generator)
    return objects


def _choose_map_func(parallelism: Optional[str], chunksize: int) -> Callable[[Callable, Iterable], List]:
    if parallelism is None:
        return map
    elif parallelism == "multi_thread":
        return partial(ThreadPool().imap, chunksize=chunksize)
    elif parallelism == "multi_process":
        return partial(Pool().imap, chunksize=chunksize)
    else:
        raise ValueError("supported 'parallelism' types are [None, 'multi_thread', 'multi_process']")

from multiprocessing.pool import ThreadPool, Pool
from typing import Any, List, Callable, Sequence, TypeVar, Optional, Iterable
from functools import partial

from tqdm import tqdm

T = TypeVar('T')


def apply_map(func: Callable[[T], Any], sequence: Sequence[T],
              parallelism: Optional[str], show_progress: bool, tqdm_description: str = None) -> List:
    chunksize = max(int(len(sequence) / 1000), 1)
    map_func = _choose_map_func(parallelism, chunksize)
    map_generator = map_func(func, sequence)
    if show_progress:
        map_generator = tqdm(map_generator, desc=tqdm_description, total=len(sequence))
    objects = list(map_generator)
    return objects


def _choose_map_func(parallelism: Optional[str], chunksize: int) -> Callable[[Callable, Iterable], List]:
    if parallelism is None:
        return map
    elif parallelism == "multi_thread":
        return partial(ThreadPool().imap, chunksize=chunksize)
    elif parallelism == "multi_process":
        return partial(Pool().imap, chunksize=chunksize)
    else:
        raise ValueError("supported 'parallelism' types are [None, 'multi_thread', 'multi_process']")