'''simple docstring'''

import os
import sys
import warnings
from dataclasses import dataclass, field
from io import BytesIO
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Union

import numpy as np
import pyarrow as pa

from .. import config
from ..download.streaming_download_manager import xopen
from ..table import array_cast
from ..utils.file_utils import is_local_path
from ..utils.py_utils import first_non_null_value, no_op_if_value_is_null, string_to_dict


if TYPE_CHECKING:
     import PIL.Image

     from .features import FeatureType


SCREAMING_SNAKE_CASE__											=     None
SCREAMING_SNAKE_CASE__											=     '<' if sys.byteorder == 'little' else '>'
# Origin: https://github.com/python-pillow/Pillow/blob/698951e19e19972aeed56df686868f1329981c12/src/PIL/Image.py#L3126 minus "|i1" which values are not preserved correctly when saving and loading an image
SCREAMING_SNAKE_CASE__											=     [
    np.dtype('|b1'),
    np.dtype('|u1'),
    np.dtype('<u2'),
    np.dtype('>u2'),
    np.dtype('<i2'),
    np.dtype('>i2'),
    np.dtype('<u4'),
    np.dtype('>u4'),
    np.dtype('<i4'),
    np.dtype('>i4'),
    np.dtype('<f4'),
    np.dtype('>f4'),
    np.dtype('<f8'),
    np.dtype('>f8'),
]






@dataclass
class        a_		:
  lowercase  	=   True
  lowercase  	=   None
  # Automatically constructed
  lowercase  	=   "PIL.Image.Image"
  lowercase  	=   pa.struct({"""bytes""": pa.binary(), """path""": pa.string()}       )
  lowercase  	=   field(default="""Image"""			, init=__lowerCamelCase			, repr=__lowerCamelCase       )

  def __call__(   self   )						->   Optional[Any]:



        """simple docstring"""






        return self.pa_type

  def 						A__		(   self    ,	_SCREAMING_SNAKE_CASE   )						->   List[str]:



        """simple docstring"""






        if config.PIL_AVAILABLE:
              import PIL.Image
        else:
              raise ImportError("""To support encoding images, please install 'Pillow'."""   )

        if isinstance(UpperCamelCase_    ,	UpperCamelCase_   ):
              UpperCamelCase       						=      np.array(UpperCamelCase_   )

        if isinstance(UpperCamelCase_    ,	UpperCamelCase_   ):
              return {"path": value, "bytes": None}
        elif isinstance(UpperCamelCase_    ,	UpperCamelCase_   ):
              return {"path": None, "bytes": value}
        elif isinstance(UpperCamelCase_    ,	np.ndarray   ):
              # convert the image array to PNG/TIFF bytes
              return encode_np_array(UpperCamelCase_   )
        elif isinstance(UpperCamelCase_    ,	PIL.Image.Image   ):
              # convert the PIL image to bytes (default format is PNG/TIFF)
              return encode_pil_image(UpperCamelCase_   )
        elif value.get("""path"""   ) is not None and os.path.isfile(value["""path"""]   ):
              # we set "bytes": None to not duplicate the data if they're already available locally
              return {"bytes": None, "path": value.get("""path"""   )}
        elif value.get("""bytes"""   ) is not None or value.get("""path"""   ) is not None:
              # store the image bytes, and path is used to infer the image format using the file extension
              return {"bytes": value.get("""bytes"""   ), "path": value.get("""path"""   )}
        else:
              raise ValueError(
                  F"An image sample should have one of \'path\' or \'bytes\' but they are missing or None in {value}."   )

  def 						A__		(   self    ,	_SCREAMING_SNAKE_CASE    ,	_SCREAMING_SNAKE_CASE=None   )						->   Optional[int]:



        """simple docstring"""






        if not self.decode:
              raise RuntimeError("""Decoding is disabled for this feature. Please use Image(decode=True) instead."""   )

        if config.PIL_AVAILABLE:
              import PIL.Image
        else:
              raise ImportError("""To support decoding images, please install 'Pillow'."""   )

        if token_per_repo_id is None:
              UpperCamelCase       						=      {}

        UpperCamelCase						,UpperCamelCase       						=      value["""path"""], value["""bytes"""]
        if bytes_ is None:
              if path is None:
                    raise ValueError(F"An image should have one of \'path\' or \'bytes\' but both are None in {value}."   )
              else:
                    if is_local_path(UpperCamelCase_   ):
                          UpperCamelCase       						=      PIL.Image.open(UpperCamelCase_   )
                    else:
                          UpperCamelCase       						=      path.split("""::"""   )[-1]
                          try:
                                UpperCamelCase       						=      string_to_dict(UpperCamelCase_    ,	config.HUB_DATASETS_URL   )["""repo_id"""]
                                UpperCamelCase       						=      token_per_repo_id.get(UpperCamelCase_   )
                          except ValueError:
                                UpperCamelCase       						=      None
                          with xopen(UpperCamelCase_    ,	"""rb"""    ,	use_auth_token=UpperCamelCase_   ) as f:
                                UpperCamelCase       						=      BytesIO(f.read()   )
                          UpperCamelCase       						=      PIL.Image.open(bytes_   )
        else:
              UpperCamelCase       						=      PIL.Image.open(BytesIO(bytes_   )   )
        image.load()  # to avoid "Too many open files" errors
        return image

  def 						A__		(   self   )						->   Union[str, Any]:



        """simple docstring"""






        from .features import Value

        return (
            self
            if self.decode
            else {
                "bytes": Value("""binary"""   ),
                "path": Value("""string"""   ),
            }
        )

  def 						A__		(   self    ,	_SCREAMING_SNAKE_CASE   )						->   List[str]:



        """simple docstring"""






        if pa.types.is_string(storage.type   ):
              UpperCamelCase       						=      pa.array([None] * len(UpperCamelCase_   )    ,	type=pa.binary()   )
              UpperCamelCase       						=      pa.StructArray.from_arrays([bytes_array, storage]    ,	["""bytes""", """path"""]    ,	mask=storage.is_null()   )
        elif pa.types.is_binary(storage.type   ):
              UpperCamelCase       						=      pa.array([None] * len(UpperCamelCase_   )    ,	type=pa.string()   )
              UpperCamelCase       						=      pa.StructArray.from_arrays([storage, path_array]    ,	["""bytes""", """path"""]    ,	mask=storage.is_null()   )
        elif pa.types.is_struct(storage.type   ):
              if storage.type.get_field_index("""bytes"""   ) >= 0:
                    UpperCamelCase       						=      storage.field("""bytes"""   )
              else:
                    UpperCamelCase       						=      pa.array([None] * len(UpperCamelCase_   )    ,	type=pa.binary()   )
              if storage.type.get_field_index("""path"""   ) >= 0:
                    UpperCamelCase       						=      storage.field("""path"""   )
              else:
                    UpperCamelCase       						=      pa.array([None] * len(UpperCamelCase_   )    ,	type=pa.string()   )
              UpperCamelCase       						=      pa.StructArray.from_arrays([bytes_array, path_array]    ,	["""bytes""", """path"""]    ,	mask=storage.is_null()   )
        elif pa.types.is_list(storage.type   ):
              UpperCamelCase       						=      pa.array(
                  [encode_np_array(np.array(UpperCamelCase_   )   )["""bytes"""] if arr is not None else None for arr in storage.to_pylist()]    ,	type=pa.binary()    ,	)
              UpperCamelCase       						=      pa.array([None] * len(UpperCamelCase_   )    ,	type=pa.string()   )
              UpperCamelCase       						=      pa.StructArray.from_arrays(
                  [bytes_array, path_array]    ,	["""bytes""", """path"""]    ,	mask=bytes_array.is_null()   )
        return array_cast(UpperCamelCase_    ,	self.pa_type   )


  def 						A__		(   self    ,	_SCREAMING_SNAKE_CASE   )						->   int:



        """simple docstring"""






        @no_op_if_value_is_null
        def path_to_bytes(_SCREAMING_SNAKE_CASE   ):
              with xopen(UpperCamelCase_    ,	"""rb"""   ) as f:
                    UpperCamelCase       						=      f.read()
              return bytes_

        UpperCamelCase       						=      pa.array(
            [
                (path_to_bytes(x["""path"""]   ) if x["""bytes"""] is None else x["""bytes"""]) if x is not None else None
                for x in storage.to_pylist()
            ]    ,	type=pa.binary()    ,	)
        UpperCamelCase       						=      pa.array(
            [os.path.basename(UpperCamelCase_   ) if path is not None else None for path in storage.field("""path"""   ).to_pylist()]    ,	type=pa.string()    ,	)
        UpperCamelCase       						=      pa.StructArray.from_arrays([bytes_array, path_array]    ,	["""bytes""", """path"""]    ,	mask=bytes_array.is_null()   )
        return array_cast(UpperCamelCase_    ,	self.pa_type   )







def 					lowercase__				(   )->				Any:



      if config.PIL_AVAILABLE:
            import PIL.Image
      else:
            raise ImportError("""To support encoding images, please install 'Pillow'."""					)

      global _IMAGE_COMPRESSION_FORMATS
      if _IMAGE_COMPRESSION_FORMATS is None:
            PIL.Image.init()
            UpperCamelCase       						=      list(set(PIL.Image.OPEN.keys()					) & set(PIL.Image.SAVE.keys()					)					)
      return _IMAGE_COMPRESSION_FORMATS







def 					lowercase__				(   __UpperCamelCase					)->				List[Any]:
      UpperCamelCase       						=      BytesIO()
      if image.format in list_image_compression_formats():
            UpperCamelCase       						=      image.format
      else:
            UpperCamelCase       						=      """PNG""" if image.mode in ["""1""", """L""", """LA""", """RGB""", """RGBA"""] else """TIFF"""
      image.save(A__	,		format=A__					)
      return buffer.getvalue()







def 					lowercase__				(   __UpperCamelCase					)->				int:



      if hasattr(A__	,		"""filename"""					) and image.filename != "":
            return {"path": image.filename, "bytes": None}
      else:
            return {"path": None, "bytes": image_to_bytes(A__					)}







def 					lowercase__				(   __UpperCamelCase					)->				Tuple:



      if config.PIL_AVAILABLE:
            import PIL.Image
      else:
            raise ImportError("""To support encoding images, please install 'Pillow'."""					)

      UpperCamelCase       						=      array.dtype
      UpperCamelCase       						=      dtype.byteorder if dtype.byteorder != """=""" else _NATIVE_BYTEORDER
      UpperCamelCase       						=      dtype.kind
      UpperCamelCase       						=      dtype.itemsize

      UpperCamelCase       						=      None

      # Multi-channel array case (only np.dtype("|u1") is allowed)
      if array.shape[2:]:
            UpperCamelCase       						=      np.dtype("""|u1"""					)
            if dtype_kind not in ["u", "i"]:
                  raise TypeError(
                      F"Unsupported array dtype {dtype} for image encoding. Only {dest_dtype} is supported for multi-channel arrays."					)
            if dtype is not dest_dtype:
                  warnings.warn(F"Downcasting array dtype {dtype} to {dest_dtype} to be compatible with \'Pillow\'"					)
    # Exact match
      elif dtype in _VALID_IMAGE_ARRAY_DTPYES:
            UpperCamelCase       						=      dtype
      else:  # Downcast the type within the kind (np.can_cast(from_type, to_type, casting="same_kind") doesn't behave as expected, so do it manually)
            while dtype_itemsize >= 1:
                  UpperCamelCase       						=      dtype_byteorder + dtype_kind + str(A__					)
                  UpperCamelCase       						=      np.dtype(A__					)
                  if dest_dtype in _VALID_IMAGE_ARRAY_DTPYES:
                        warnings.warn(F"Downcasting array dtype {dtype} to {dest_dtype} to be compatible with \'Pillow\'"					)
                        break
                  else:
                        dtype_itemsize //= 2

      if dest_dtype is None:
            raise TypeError(
                F"Cannot convert dtype {dtype} to a valid image dtype. Valid image dtypes: {_VALID_IMAGE_ARRAY_DTPYES}"					)
      UpperCamelCase       						=      PIL.Image.fromarray(array.astype(A__					)					)
      return {"path": None, "bytes": image_to_bytes(A__					)}







def 					lowercase__				(   __UpperCamelCase					)->				Any:



      if config.PIL_AVAILABLE:
            import PIL.Image
      else:
            raise ImportError("""To support encoding images, please install 'Pillow'."""					)

      if objs:
            UpperCamelCase						,UpperCamelCase       						=      first_non_null_value(A__					)
            if isinstance(A__	,		A__					):
                  return [{"path": obj, "bytes": None} if obj is not None else None for obj in objs]
            if isinstance(A__	,		np.ndarray					):
                  UpperCamelCase       						=      no_op_if_value_is_null(A__					)
                  return [obj_to_image_dict_func(A__					) for obj in objs]
            elif isinstance(A__	,		PIL.Image.Image					):
                  UpperCamelCase       						=      no_op_if_value_is_null(A__					)
                  return [obj_to_image_dict_func(A__					) for obj in objs]
            else:
                  return objs
      else:
            return objs








'''simple docstring'''

from math import factorial







def 					lowercase__				(   __UpperCamelCase = 20					)->				int:
      UpperCamelCase       						=      2 * n  # middle entry of odd rows starting at row 3 is the solution for n = 1,
      # 2, 3,...
      UpperCamelCase       						=      n // 2

      return int(factorial(__UpperCamelCase					) / (factorial(__UpperCamelCase					) * factorial(n - k					))					)


if __name__ == "__main__":
     import sys

     if len(sys.argv) == 1:
          print(solution(2_0))
     else:
          try:
               SCREAMING_SNAKE_CASE__											=     int(sys.argv[1])
               print(solution(n))
          except ValueError:
               print('Invalid entry - please enter a number.')
