import io
import itertools
import json
from dataclasses import dataclass
from typing import Optional

import pyarrow as pa
import pyarrow.json as paj

import datasets
from datasets.table import table_cast
from datasets.utils.file_utils import readline


lowercase__ 	=     datasets.utils.logging.get_logger(__name__)




@dataclass
class        __snake_case	(					datasets.BuilderConfig    ):
      a__				=		None
      a__				=		"""utf-8"""
      a__				=		None
      a__				=		None
      a__				=		True  # deprecated
      a__				=		None  # deprecated
      a__				=		10 << 20  # 10MB
      a__				=		None







class        __snake_case	(					datasets.ArrowBasedBuilder    ):
      a__				=		JsonConfig



      def   lowerCamelCase_       (						self)     ->      Optional[int]:





        '''simple docstring'''





        if self.config.block_size is not None:
          logger.warning('The JSON loader parameter `block_size` is deprecated. Please use `chunksize` instead')
          a__:					Optional[int]      							=     self.config.block_size
        if self.config.use_threads is not True:
          logger.warning(
              'The JSON loader parameter `use_threads` is deprecated and doesn\'t have any effect anymore.')
        if self.config.newlines_in_values is not None:
          raise ValueError('The JSON loader parameter `newlines_in_values` is no longer supported')
        return datasets.DatasetInfo(features=self.config.features)



      def   lowerCamelCase_       (						self   ,      lowercase)     ->      str:





        '''simple docstring'''





        if not self.config.data_files:
          raise ValueError(f'At least one data file must be specified, but got data_files={self.config.data_files}')
        a__:					Union[str, Any]      							=     dl_manager.download_and_extract(self.config.data_files)
        if isinstance(lowercase_   ,      (str, list, tuple)):
          a__:					Optional[int]      							=     data_files
          if isinstance(lowercase_   ,      lowercase_):
            a__:					List[str]      							=     [files]
          a__:					Union[str, Any]      							=     [dl_manager.iter_files(lowercase_) for file in files]
          return [datasets.SplitGenerator(name=datasets.Split.TRAIN   ,      gen_kwargs={'files': files})]
        a__:					List[str]      							=     []
        for split_name, files in data_files.items():
          if isinstance(lowercase_   ,      lowercase_):
            a__:					Dict      							=     [files]
          a__:					Optional[Any]      							=     [dl_manager.iter_files(lowercase_) for file in files]
          splits.append(datasets.SplitGenerator(name=lowercase_   ,      gen_kwargs={'files': files}))
        return splits



      def   lowerCamelCase_       (						self   ,      lowercase)     ->      List[Any]:





        '''simple docstring'''





        if self.config.features is not None:
          # adding missing columns
          for column_name in set(self.config.features) - set(pa_table.column_names):
            a__:					int      							=     self.config.features.arrow_schema.field(lowercase_).type
            a__:					List[Any]      							=     pa_table.append_column(lowercase_   ,      pa.array([None] * len(lowercase_)   ,      type=lowercase_))
          # more expensive cast to support nested structures with keys in a different order
          # allows str <-> int/float or str to Audio for example
          a__:					Any      							=     table_cast(lowercase_   ,      self.config.features.arrow_schema)
        return pa_table



      def   lowerCamelCase_       (						self   ,      lowercase)     ->      Any:





        '''simple docstring'''





        for file_idx, file in enumerate(itertools.chain.from_iterable(lowercase_)):
          # If the file is one json object and if we need to look at the list of items in one specific field
          if self.config.field is not None:
            with open(lowercase_   ,      encoding=self.config.encoding   ,      errors=self.config.encoding_errors) as f:
              a__:					Optional[int]      							=     json.load(lowercase_)

            # We keep only the field we are interested in
            a__:					Dict      							=     dataset[self.config.field]

            # We accept two format: a list of dicts or a dict of lists
            if isinstance(lowercase_   ,      (list, tuple)):
              a__:					str      							=     set().union(*[row.keys() for row in dataset])
              a__:					Any      							=     {col: [row.get(lowercase_) for row in dataset] for col in keys}
            else:
              a__:					List[str]      							=     dataset
            a__:					List[Any]      							=     pa.Table.from_pydict(lowercase_)
            yield file_idx, self._cast_table(lowercase_)

          # If the file has one json object per line
          else:
            with open(lowercase_   ,      'rb') as f:
              a__:					Dict      							=     0
              # Use block_size equal to the chunk size divided by 32 to leverage multithreading
              # Set a default minimum value of 16kB if the chunk size is really small
              a__:					Optional[int]      							=     max(self.config.chunksize // 32   ,      16 << 10)
              a__:					List[Any]      							=     (
                  self.config.encoding_errors if self.config.encoding_errors is not None else '''strict'''
              )
              while True:
                a__:					List[str]      							=     f.read(self.config.chunksize)
                if not batch:
                  break
                # Finish current line
                try:
                  batch += f.readline()
                except (AttributeError, io.UnsupportedOperation):
                  batch += readline(lowercase_)
                # PyArrow only accepts utf-8 encoded bytes
                if self.config.encoding != "utf-8":
                  a__:					Optional[int]      							=     batch.decode(self.config.encoding   ,      errors=lowercase_).encode('utf-8')
                try:
                  while True:
                    try:
                      a__:					Optional[int]      							=     paj.read_json(
                          io.BytesIO(lowercase_)   ,      read_options=paj.ReadOptions(block_size=lowercase_))
                      break
                    except (pa.ArrowInvalid, pa.ArrowNotImplementedError) as e:
                      if (
                          isinstance(lowercase_   ,      pa.ArrowInvalid)
                          and "straddling" not in str(lowercase_)
                          or block_size > len(lowercase_)
                      ):
                        raise
                      else:
                        # Increase the block size in case it was too small.
                        # The block size will be reset for the next file.
                        logger.debug(
                            f'Batch of {len(lowercase_)} bytes couldn\'t be parsed with block_size={block_size}. Retrying with block_size={block_size * 2}.')
                        block_size *= 2
                except pa.ArrowInvalid as e:
                  try:
                    with open(
                        lowercase_   ,      encoding=self.config.encoding   ,      errors=self.config.encoding_errors) as f:
                      a__:					Optional[Any]      							=     json.load(lowercase_)
                  except json.JSONDecodeError:
                    logger.error(f'Failed to read file \'{file}\' with error {type(lowercase_)}: {e}')
                    raise e
                  # If possible, parse the file as a list of json objects and exit the loop
                  if isinstance(lowercase_   ,      lowercase_):  # list is the only sequence type supported in JSON
                    try:
                      a__:					Optional[int]      							=     set().union(*[row.keys() for row in dataset])
                      a__:					str      							=     {col: [row.get(lowercase_) for row in dataset] for col in keys}
                      a__:					List[Any]      							=     pa.Table.from_pydict(lowercase_)
                    except (pa.ArrowInvalid, AttributeError) as e:
                      logger.error(f'Failed to read file \'{file}\' with error {type(lowercase_)}: {e}')
                      raise ValueError(f'Not able to read records in the JSON file at {file}.') from None
                    yield file_idx, self._cast_table(lowercase_)
                    break
                  else:
                    logger.error(f'Failed to read file \'{file}\' with error {type(lowercase_)}: {e}')
                    raise ValueError(
                        f'Not able to read records in the JSON file at {file}. '
                        f'You should probably indicate the field of the JSON file containing your records. '
                        f'This JSON file contain the following fields: {str(list(dataset.keys()))}. '
                        f'Select the correct one and provide it as `field=\'XXX\'` to the dataset loading method. ') from None
                        # Uncomment for debugging (will print the Arrow table size and elements)
                        # logger.warning(f"pa_table: {pa_table} num rows: {pa_table.num_rows}")
                        # logger.warning('\n'.join(str(pa_table.slice(i, 1).to_pydict()) for i in range(pa_table.num_rows)))
                yield (file_idx, batch_idx), self._cast_table(lowercase_)
                batch_idx += 1



"""simple docstring"""
def 						__a       (     _SCREAMING_SNAKE_CASE       )     ->bool:
  return credit_card_number.startswith(('34', '35', '37', '4', '5', '6')       )







def 						__a       (     _SCREAMING_SNAKE_CASE       )     ->bool:
  a__:					Any      							=     credit_card_number
  a__:					Tuple      							=     0
  a__:					List[str]      							=     len(_SCREAMING_SNAKE_CASE       ) - 2
  for i in range(_SCREAMING_SNAKE_CASE		,					-1		,					-2       ):
    #  double the value of every second digit
    a__:					Tuple      							=     int(cc_number[i]       )
    digit *= 2
    # If doubling of a number results in a two digit number
    # i.e greater than 9(e.g., 6 × 2 = 12),
    # then add the digits of the product (e.g., 12: 1 + 2 = 3, 15: 1 + 5 = 6),
    # to get a single digit number.
    if digit > 9:
      digit %= 10
      digit += 1
    a__:					Optional[Any]      							=     cc_number[:i] + str(_SCREAMING_SNAKE_CASE       ) + cc_number[i + 1 :]
    total += digit

  # Sum up the remaining digits
  for i in range(len(_SCREAMING_SNAKE_CASE       ) - 1		,					-1		,					-2       ):
    total += int(cc_number[i]       )

  return total % 10 == 0







def 						__a       (     _SCREAMING_SNAKE_CASE       )     ->bool:
  a__:					Optional[int]      							=     F'{credit_card_number} is an invalid credit card number because'
  if not credit_card_number.isdigit():
    print(F'{error_message} it has nonnumerical characters.'       )
    return False

  if not 13 <= len(_SCREAMING_SNAKE_CASE       ) <= 16:
    print(F'{error_message} of its length.'       )
    return False

  if not validate_initial_digits(_SCREAMING_SNAKE_CASE       ):
    print(F'{error_message} of its first two digits.'       )
    return False

  if not luhn_validation(_SCREAMING_SNAKE_CASE       ):
    print(F'{error_message} it fails the Luhn check.'       )
    return False

  print(F'{credit_card_number} is a valid credit card number.'       )
  return True


if __name__ == "__main__":
 import doctest

 doctest.testmod()
 validate_credit_card_number('4111111111111111')
 validate_credit_card_number('32323')


