
from typing import List, Optional, TypeVar

from .arrow_dataset import Dataset, _concatenate_map_style_datasets, _interleave_map_style_datasets
from .dataset_dict import DatasetDict, IterableDatasetDict
from .info import DatasetInfo
from .iterable_dataset import IterableDataset, _concatenate_iterable_datasets, _interleave_iterable_datasets
from .splits import NamedSplit
from .utils import logging
from .utils.py_utils import Literal


lowercase  : List[Any]						   =							logging.get_logger(__name__)


lowercase  : int						   =							TypeVar("""DatasetType""", Dataset, IterableDataset)







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ = None ,     SCREAMING_SNAKE_CASE__ = None ,     SCREAMING_SNAKE_CASE__ = None ,     SCREAMING_SNAKE_CASE__ = None ,     SCREAMING_SNAKE_CASE__ = "first_exhausted" ,     )			->   DatasetType:
       from .arrow_dataset import Dataset
       from .iterable_dataset import IterableDataset

       if not datasets:
              raise ValueError("""Unable to interleave an empty list of datasets."""    )
       for i, dataset in enumerate(SCREAMING_SNAKE_CASE__    ):
              if not isinstance(SCREAMING_SNAKE_CASE__ ,     (Dataset, IterableDataset)    ):
                     if isinstance(SCREAMING_SNAKE_CASE__ ,     (DatasetDict, IterableDatasetDict)    ):
                            if not dataset:
                                   raise ValueError(
                                       f"Expected a list of Dataset objects or a list of IterableDataset objects, but element at position {i} "
                                       """is an empty dataset dictionary."""    )
                            raise ValueError(
                                f"Dataset at position {i} has at least one split: {list(SCREAMING_SNAKE_CASE__    )}\n"
                                f"Please pick one to interleave with the other datasets, for example: dataset['{next(iter(SCREAMING_SNAKE_CASE__    )    )}']"    )
                     raise ValueError(
                         f"Expected a list of Dataset objects or a list of IterableDataset objects, but element at position {i} is a {type(SCREAMING_SNAKE_CASE__    ).__name__}."    )
              if i == 0:
                     lowercase     ,      lowercase							:					str	     =				(
                         (Dataset, IterableDataset) if isinstance(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    ) else (IterableDataset, Dataset)
                     )
              elif not isinstance(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    ):
                     raise ValueError(
                         f"Unable to interleave a {dataset_type.__name__} (at position 0) with a {other_type.__name__} (at position {i}). Expected a list of Dataset objects or a list of IterableDataset objects."    )
       if stopping_strategy not in ["first_exhausted", "all_exhausted"]:
              raise ValueError(f"{stopping_strategy} is not supported. Please enter a valid stopping_strategy."    )
       if dataset_type is Dataset:
              return _interleave_map_style_datasets(
                  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     info=SCREAMING_SNAKE_CASE__ ,     split=SCREAMING_SNAKE_CASE__ ,     stopping_strategy=SCREAMING_SNAKE_CASE__    )
       else:
              return _interleave_iterable_datasets(
                  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     info=SCREAMING_SNAKE_CASE__ ,     split=SCREAMING_SNAKE_CASE__ ,     stopping_strategy=SCREAMING_SNAKE_CASE__    )







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ = None ,     SCREAMING_SNAKE_CASE__ = None ,     SCREAMING_SNAKE_CASE__ = 0 ,     )			->   DatasetType:

       if not dsets:
              raise ValueError("""Unable to concatenate an empty list of datasets."""    )
       for i, dataset in enumerate(SCREAMING_SNAKE_CASE__    ):
              if not isinstance(SCREAMING_SNAKE_CASE__ ,     (Dataset, IterableDataset)    ):
                     if isinstance(SCREAMING_SNAKE_CASE__ ,     (DatasetDict, IterableDatasetDict)    ):
                            if not dataset:
                                   raise ValueError(
                                       f"Expected a list of Dataset objects or a list of IterableDataset objects, but element at position {i} "
                                       """is an empty dataset dictionary."""    )
                            raise ValueError(
                                f"Dataset at position {i} has at least one split: {list(SCREAMING_SNAKE_CASE__    )}\n"
                                f"Please pick one to interleave with the other datasets, for example: dataset['{next(iter(SCREAMING_SNAKE_CASE__    )    )}']"    )
                     raise ValueError(
                         f"Expected a list of Dataset objects or a list of IterableDataset objects, but element at position {i} is a {type(SCREAMING_SNAKE_CASE__    ).__name__}."    )
              if i == 0:
                     lowercase     ,      lowercase							:					Union[str, Any]	     =				(
                         (Dataset, IterableDataset) if isinstance(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    ) else (IterableDataset, Dataset)
                     )
              elif not isinstance(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    ):
                     raise ValueError(
                         f"Unable to interleave a {dataset_type.__name__} (at position 0) with a {other_type.__name__} (at position {i}). Expected a list of Dataset objects or a list of IterableDataset objects."    )
       if dataset_type is Dataset:
              return _concatenate_map_style_datasets(SCREAMING_SNAKE_CASE__ ,     info=SCREAMING_SNAKE_CASE__ ,     split=SCREAMING_SNAKE_CASE__ ,     axis=SCREAMING_SNAKE_CASE__    )
       else:
              return _concatenate_iterable_datasets(SCREAMING_SNAKE_CASE__ ,     info=SCREAMING_SNAKE_CASE__ ,     split=SCREAMING_SNAKE_CASE__ ,     axis=SCREAMING_SNAKE_CASE__    )


def 						_snake_case(  SCREAMING_SNAKE_CASE__    )			->   int:
       assert (
           isinstance(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    ) and number_of_steps > 0
       ), f"number_of_steps needs to be positive integer, your input {number_of_steps}"
       if number_of_steps == 1:
              return 1
       lowercase     ,      lowercase							:					Tuple	     =				1, 1
       for _ in range(number_of_steps - 1    ):
              lowercase     ,      lowercase							:					str	     =				current + previous, current
       return current


if __name__ == "__main__":
  import doctest

  doctest.testmod()
