



from __future__ import annotations

from collections.abc import Callable
from typing import Generic, TypeVar

__A       =						TypeVar('''T''')
__A       =						TypeVar('''U''')






class 		lowercase						(			Generic[T, U]):






 """simple docstring"""


 def __init__(     self     :						Any						,  __UpperCAmelCase     :						Optional[int]						,  __UpperCAmelCase     :						List[str]					)      ->			Union[str, Any]:
       UpperCAmelCase_=       key
       UpperCAmelCase_=       val
       UpperCAmelCase_=       None
       UpperCAmelCase_=       None




 def __repr__(     self     :						int					)      ->			str:
       return (
           F"""Node: key: {self.key}, val: {self.val}, """
           F"""has next: {bool(self.next					)}, has prev: {bool(self.prev					)}"""
       )






class 		lowercase						(			Generic[T, U]):






 """simple docstring"""


 def __init__(     self     :						List[str]					)      ->			None:
       UpperCAmelCase_=       DoubleLinkedListNode(_SCREAMING_SNAKE_CASE						,  _SCREAMING_SNAKE_CASE					)
       UpperCAmelCase_=       DoubleLinkedListNode(_SCREAMING_SNAKE_CASE						,  _SCREAMING_SNAKE_CASE					)
       UpperCAmelCase_=       self.rear, self.head




 def __repr__(     self     :						Union[str, Any]					)      ->			str:
       UpperCAmelCase_=       ["DoubleLinkedList"]
       UpperCAmelCase_=       self.head
       while node.next is not None:
             rep.append(str(_SCREAMING_SNAKE_CASE					)					)
             UpperCAmelCase_=       node.next
       rep.append(str(self.rear					)					)
       return ",\n    ".join(_SCREAMING_SNAKE_CASE					)




 def   _SCREAMING_SNAKE_CASE		(     self     :						Any						,  __UpperCAmelCase     :						Optional[Any]					)      ->			None:
       UpperCAmelCase_=       self.rear.prev

       # All nodes other than self.head are guaranteed to have non-None previous
       assert previous is not None

       UpperCAmelCase_=       node
       UpperCAmelCase_=       previous
       UpperCAmelCase_=       node
       UpperCAmelCase_=       self.rear




 def   _SCREAMING_SNAKE_CASE		(     self     :						int						,  __UpperCAmelCase     :						str					)      ->			DoubleLinkedListNode[T, U] | None:

       if node.prev is None or node.next is None:
             return None

       UpperCAmelCase_=       node.next
       UpperCAmelCase_=       node.prev
       UpperCAmelCase_=       None
       UpperCAmelCase_=       None
       return node






class 		lowercase						(			Generic[T, U]):






 """simple docstring"""


 a__				: dict[Callable[[T], U], LRUCache[T, U]]		       =							{}




 def __init__(     self     :						List[Any]						,  __UpperCAmelCase     :						Union[str, Any]					)      ->			Dict:
       UpperCAmelCase_=       DoubleLinkedList()
       UpperCAmelCase_=       capacity
       UpperCAmelCase_=       0
       UpperCAmelCase_=       0
       UpperCAmelCase_=       0
       UpperCAmelCase_=       {}




 def __repr__(     self     :						Any					)      ->			str:
       return (
           F"""CacheInfo(hits={self.hits}, misses={self.miss}, """
           F"""capacity={self.capacity}, current size={self.num_keys})"""
       )




 def __contains__(     self     :						Optional[int]						,  __UpperCAmelCase     :						Union[str, Any]					)      ->			bool:
       return key in self.cache




 def   _SCREAMING_SNAKE_CASE		(     self     :						int						,  __UpperCAmelCase     :						Optional[int]					)      ->			U | None:
       # Note: pythonic interface would throw KeyError rather than return None

       if key in self.cache:
             self.hits += 1
             UpperCAmelCase_=       self.cache[key]
             UpperCAmelCase_=       self.list.remove(self.cache[key]					)
             assert node == value_node

             # node is guaranteed not None because it is in self.cache
             assert node is not None
             self.list.add(_SCREAMING_SNAKE_CASE					)
             return node.val
       self.miss += 1
       return None




 def   _SCREAMING_SNAKE_CASE		(     self     :						Any						,  __UpperCAmelCase     :						str						,  __UpperCAmelCase     :						Optional[int]					)      ->			None:

       if key not in self.cache:
             if self.num_keys >= self.capacity:
                   # delete first node (oldest) when over capacity
                   UpperCAmelCase_=       self.list.head.next

                   # guaranteed to have a non-None first node when num_keys > 0
                   # explain to type checker via assertions
                   assert first_node is not None
                   assert first_node.key is not None
                   assert (
                       self.list.remove(_SCREAMING_SNAKE_CASE					) is not None
                   )  # node guaranteed to be in list assert node.key is not None

                   del self.cache[first_node.key]
                   self.num_keys -= 1
             UpperCAmelCase_=       DoubleLinkedListNode(_SCREAMING_SNAKE_CASE						,  _SCREAMING_SNAKE_CASE					)
             self.list.add(self.cache[key]					)
             self.num_keys += 1

       else:
             # bump node to the end of the list, update value
             UpperCAmelCase_=       self.list.remove(self.cache[key]					)
             assert node is not None  # node guaranteed to be in list
             UpperCAmelCase_=       value
             self.list.add(_SCREAMING_SNAKE_CASE					)




 @classmethod
 def   _SCREAMING_SNAKE_CASE		(     cls     :						Optional[int]						,  __UpperCAmelCase     :						List[str] = 128					)      ->			Callable[[Callable[[T], U]], Callable[..., U]]:

       def cache_decorator_inner(__UpperCAmelCase     :						Optional[int]					) -> Callable[..., U]:
             def cache_decorator_wrapper(*__UpperCAmelCase     :						Optional[int]					) -> U:
                   if func not in cls.decorator_function_to_instance_map:
                         UpperCAmelCase_=       LRUCache(_SCREAMING_SNAKE_CASE					)

                   UpperCAmelCase_=       cls.decorator_function_to_instance_map[func].get(args[0]					)
                   if result is None:
                         UpperCAmelCase_=       func(*_SCREAMING_SNAKE_CASE					)
                         cls.decorator_function_to_instance_map[func].put(args[0]						,  _SCREAMING_SNAKE_CASE					)
                   return result

             def cache_info() -> LRUCache[T, U]:
                   return cls.decorator_function_to_instance_map[func]

             setattr(_SCREAMING_SNAKE_CASE						,  """cache_info"""						,  _SCREAMING_SNAKE_CASE					)  # noqa: B010

             return cache_decorator_wrapper

       return cache_decorator_inner


if __name__ == "__main__":
 import doctest

 doctest.testmod()









import itertools
from dataclasses import dataclass
from typing import Any, Callable, Dict, List, Optional, Union

import pandas as pd
import pyarrow as pa

import datasets
import datasets.config
from datasets.features.features import require_storage_cast
from datasets.table import table_cast
from datasets.utils.py_utils import Literal


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

__A       =						['''names''', '''prefix''']
__A       =						['''warn_bad_lines''', '''error_bad_lines''', '''mangle_dupe_cols''']
__A       =						['''encoding_errors''', '''on_bad_lines''']
__A       =						['''date_format''']






@dataclass
class 		lowercase						(			datasets.BuilderConfig):






	"""simple docstring"""


	a__				: str		       =							","
	a__				: Optional[str]		       =							None
	a__				: Optional[Union[int, List[int], str]]		       =							"infer"
	a__				: Optional[List[str]]		       =							None
	a__				: Optional[List[str]]		       =							None
	a__				: Optional[Union[int, str, List[int], List[str]]]		       =							None
	a__				: Optional[Union[List[int], List[str]]]		       =							None
	a__				: Optional[str]		       =							None
	a__				: bool		       =							True
	a__				: Optional[Literal["c", "python", "pyarrow"]]		       =							None
	a__				: Dict[Union[int, str], Callable[[Any], Any]]		       =							None
	a__				: Optional[list]		       =							None
	a__				: Optional[list]		       =							None
	a__				: bool		       =							False
	a__				: Optional[Union[int, List[int]]]		       =							None
	a__				: Optional[int]		       =							None
	a__				: Optional[Union[str, List[str]]]		       =							None
	a__				: bool		       =							True
	a__				: bool		       =							True
	a__				: bool		       =							False
	a__				: bool		       =							True
	a__				: Optional[str]		       =							None
	a__				: str		       =							"."
	a__				: Optional[str]		       =							None
	a__				: str		       =							'"'
	a__				: int		       =							0
	a__				: Optional[str]		       =							None
	a__				: Optional[str]		       =							None
	a__				: Optional[str]		       =							None
	a__				: Optional[str]		       =							None
	a__				: bool		       =							True
	a__				: bool		       =							True
	a__				: int		       =							0
	a__				: bool		       =							True
	a__				: bool		       =							False
	a__				: Optional[str]		       =							None
	a__				: int		       =							1_0000
	a__				: Optional[datasets.Features]		       =							None
	a__				: Optional[str]		       =							"strict"
	a__				: Literal["error", "warn", "skip"]		       =							"error"
	a__				: Optional[str]		       =							None




	def   _SCREAMING_SNAKE_CASE		(     self     :						Optional[Any]					)      ->			int:
							if self.delimiter is not None:
													UpperCAmelCase_=       self.delimiter
							if self.column_names is not None:
													UpperCAmelCase_=       self.column_names




	@property
	def   _SCREAMING_SNAKE_CASE		(     self     :						str					)      ->			Tuple:
							UpperCAmelCase_=       {
							    """sep""": self.sep,
							    """header""": self.header,
							    """names""": self.names,
							    """index_col""": self.index_col,
							    """usecols""": self.usecols,
							    """prefix""": self.prefix,
							    """mangle_dupe_cols""": self.mangle_dupe_cols,
							    """engine""": self.engine,
							    """converters""": self.converters,
							    """true_values""": self.true_values,
							    """false_values""": self.false_values,
							    """skipinitialspace""": self.skipinitialspace,
							    """skiprows""": self.skiprows,
							    """nrows""": self.nrows,
							    """na_values""": self.na_values,
							    """keep_default_na""": self.keep_default_na,
							    """na_filter""": self.na_filter,
							    """verbose""": self.verbose,
							    """skip_blank_lines""": self.skip_blank_lines,
							    """thousands""": self.thousands,
							    """decimal""": self.decimal,
							    """lineterminator""": self.lineterminator,
							    """quotechar""": self.quotechar,
							    """quoting""": self.quoting,
							    """escapechar""": self.escapechar,
							    """comment""": self.comment,
							    """encoding""": self.encoding,
							    """dialect""": self.dialect,
							    """error_bad_lines""": self.error_bad_lines,
							    """warn_bad_lines""": self.warn_bad_lines,
							    """skipfooter""": self.skipfooter,
							    """doublequote""": self.doublequote,
							    """memory_map""": self.memory_map,
							    """float_precision""": self.float_precision,
							    """chunksize""": self.chunksize,
							    """encoding_errors""": self.encoding_errors,
							    """on_bad_lines""": self.on_bad_lines,
							    """date_format""": self.date_format,
							}

							# some kwargs must not be passed if they don't have a default value
							# some others are deprecated and we can also not pass them if they are the default value
							for pd_read_csv_parameter in _PANDAS_READ_CSV_NO_DEFAULT_PARAMETERS + _PANDAS_READ_CSV_DEPRECATED_PARAMETERS:
													if pd_read_csv_kwargs[pd_read_csv_parameter] == getattr(CsvConfig()						,  __UpperCAmelCase					):
																			del pd_read_csv_kwargs[pd_read_csv_parameter]

        # Remove 2.0 new arguments
							if not (datasets.config.PANDAS_VERSION.major >= 2):
													for pd_read_csv_parameter in _PANDAS_READ_CSV_NEW_2_0_0_PARAMETERS:
																			del pd_read_csv_kwargs[pd_read_csv_parameter]

        # Remove 1.3 new arguments
							if not (datasets.config.PANDAS_VERSION.major >= 1 and datasets.config.PANDAS_VERSION.minor >= 3):
													for pd_read_csv_parameter in _PANDAS_READ_CSV_NEW_1_3_0_PARAMETERS:
																			del pd_read_csv_kwargs[pd_read_csv_parameter]

							return pd_read_csv_kwargs






class 		lowercase						(			datasets.ArrowBasedBuilder):






	"""simple docstring"""


	a__				: int		       =							CsvConfig




	def   _SCREAMING_SNAKE_CASE		(     self     :						List[str]					)      ->			Any:
							return datasets.DatasetInfo(features=self.config.features					)




	def   _SCREAMING_SNAKE_CASE		(     self     :						Any						,  __UpperCAmelCase     :						Dict					)      ->			Optional[int]:
							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}"""					)
							UpperCAmelCase_=       dl_manager.download_and_extract(self.config.data_files					)
							if isinstance(__UpperCAmelCase						,  (str, list, tuple)					):
													UpperCAmelCase_=       data_files
													if isinstance(__UpperCAmelCase						,  __UpperCAmelCase					):
																			UpperCAmelCase_=       [files]
													UpperCAmelCase_=       [dl_manager.iter_files(__UpperCAmelCase					) for file in files]
													return [datasets.SplitGenerator(name=datasets.Split.TRAIN						,  gen_kwargs={"""files""": files}					)]
							UpperCAmelCase_=       []
							for split_name, files in data_files.items():
													if isinstance(__UpperCAmelCase						,  __UpperCAmelCase					):
																			UpperCAmelCase_=       [files]
													UpperCAmelCase_=       [dl_manager.iter_files(__UpperCAmelCase					) for file in files]
													splits.append(datasets.SplitGenerator(name=__UpperCAmelCase						,  gen_kwargs={"""files""": files}					)					)
							return splits




	def   _SCREAMING_SNAKE_CASE		(     self     :						Tuple						,  __UpperCAmelCase     :						pa.Table					)      ->			pa.Table:
							if self.config.features is not None:
													UpperCAmelCase_=       self.config.features.arrow_schema
													if all(not require_storage_cast(__UpperCAmelCase					) for feature in self.config.features.values()					):
																			# cheaper cast
																			UpperCAmelCase_=       pa.Table.from_arrays([pa_table[field.name] for field in schema]						,  schema=__UpperCAmelCase					)
													else:
																			# more expensive cast; allows str <-> int/float or str to Audio for example
																			UpperCAmelCase_=       table_cast(__UpperCAmelCase						,  __UpperCAmelCase					)
							return pa_table




	def   _SCREAMING_SNAKE_CASE		(     self     :						Any						,  __UpperCAmelCase     :						List[Any]					)      ->			List[str]:
							UpperCAmelCase_=       self.config.features.arrow_schema if self.config.features else None
							# dtype allows reading an int column as str
							UpperCAmelCase_=       (
							    {
							        name: dtype.to_pandas_dtype() if not require_storage_cast(__UpperCAmelCase					) else object
							        for name, dtype, feature in zip(schema.names						,  schema.types						,  self.config.features.values()					)
							    }
							    if schema is not None
							    else None
							)
							for file_idx, file in enumerate(itertools.chain.from_iterable(__UpperCAmelCase					)					):
													UpperCAmelCase_=       pd.read_csv(__UpperCAmelCase						,  iterator=__UpperCAmelCase						,  dtype=__UpperCAmelCase						,  **self.config.pd_read_csv_kwargs					)
													try:
																			for batch_idx, df in enumerate(__UpperCAmelCase					):
																									UpperCAmelCase_=       pa.Table.from_pandas(__UpperCAmelCase					)
																									# 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(__UpperCAmelCase					)
													except ValueError as e:
																			logger.error(F"""Failed to read file '{file}' with error {type(__UpperCAmelCase					)}: {e}"""					)
																			raise




