


import sys
from dataclasses import dataclass
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, 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


if TYPE_CHECKING:
		import sqlitea

		import sqlalchemy


__SCREAMING_SNAKE_CASE	:							int           =  datasets.utils.logging.get_logger(__name__)


@dataclass
class        __lowerCamelCase      (				datasets.BuilderConfig ):


				"""simple docstring"""







				a_:		Union[str, "sqlalchemy.sql.Selectable"]					      =	None
				a_:		Union[str, "sqlalchemy.engine.Connection", "sqlalchemy.engine.Engine", "sqlite3.Connection"]					      =	None
				a_:		Optional[Union[str, List[str]]]					      =	None
				a_:		bool					      =	True
				a_:		Optional[Union[List, Tuple, Dict]]					      =	None
				a_:		Optional[Union[List, Dict]]					      =	None
				a_:		Optional[List[str]]					      =	None
				a_:		Optional[int]					      =	1_00_00
				a_:		Optional[datasets.Features]					      =	None






				def        lowerCAmelCase__			(				self     :    Tuple					):
								if self.sql is None:
												raise ValueError("""sql must be specified"""					)
								if self.con is None:
												raise ValueError("""con must be specified"""					)






				def        lowerCAmelCase__			(				self     :    str	,							lowerCamelCase_     :    dict	,							lowerCamelCase_     :    Optional[datasets.Features] = None	,							):
								_lowerCAmelCase  						=config_kwargs.copy()
								# We need to stringify the Selectable object to make its hash deterministic

								# The process of stringifying is explained here: http://docs.sqlalchemy.org/en/latest/faq/sqlexpressions.html
								_lowerCAmelCase  						=config_kwargs["""sql"""]
								if not isinstance(lowerCamelCase_	,							lowerCamelCase_					):
												if datasets.config.SQLALCHEMY_AVAILABLE and "sqlalchemy" in sys.modules:
																import sqlalchemy

																if isinstance(lowerCamelCase_	,							sqlalchemy.sql.Selectable					):
																				_lowerCAmelCase  						=sqlalchemy.create_engine(config_kwargs["""con"""].split("""://"""					)[0] + """://"""					)
																				_lowerCAmelCase  						=str(sql.compile(dialect=engine.dialect					)					)
																				_lowerCAmelCase  						=sql_str
																else:
																				raise TypeError(
																				    F"Supported types for 'sql' are string and sqlalchemy.sql.Selectable but got {type(lowerCamelCase_					)}: {sql}"					)
												else:
																raise TypeError(
																    F"Supported types for 'sql' are string and sqlalchemy.sql.Selectable but got {type(lowerCamelCase_					)}: {sql}"					)
								_lowerCAmelCase  						=config_kwargs["""con"""]
								if not isinstance(lowerCamelCase_	,							lowerCamelCase_					):
												_lowerCAmelCase  						=id(lowerCamelCase_					)
												logger.info(
												    F"SQL connection 'con' of type {type(lowerCamelCase_					)} couldn't be hashed properly. To enable hashing, specify 'con' as URI string instead."					)

								return super().create_config_id(lowerCamelCase_	,							custom_features=lowerCamelCase_					)






				@property
				def        lowerCAmelCase__			(				self     :    Optional[Any]					):
								_lowerCAmelCase  						={
								    """index_col""": self.index_col,
								    """columns""": self.columns,
								    """params""": self.params,
								    """coerce_float""": self.coerce_float,
								    """parse_dates""": self.parse_dates,
								}
								return pd_read_sql_kwargs


class        __lowerCamelCase      (				datasets.ArrowBasedBuilder ):


				"""simple docstring"""







				a_:		Tuple					      =	SqlConfig






				def        lowerCAmelCase__			(				self     :    str					):
								return datasets.DatasetInfo(features=self.config.features					)






				def        lowerCAmelCase__			(				self     :    List[Any]	,							lowerCamelCase_     :    str					):
								return [datasets.SplitGenerator(name=datasets.Split.TRAIN	,							gen_kwargs={}					)]






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






				def        lowerCAmelCase__			(				self     :    List[Any]					):
								_lowerCAmelCase  						=self.config.chunksize
								_lowerCAmelCase  						=pd.read_sql(
								    self.config.sql	,							self.config.con	,							chunksize=lowerCamelCase_	,							**self.config.pd_read_sql_kwargs					)
								_lowerCAmelCase  						=[sql_reader] if chunksize is None else sql_reader
								for chunk_idx, df in enumerate(lowerCamelCase_					):
												_lowerCAmelCase  						=pa.Table.from_pandas(lowerCamelCase_					)
												yield chunk_idx, self._cast_table(lowerCamelCase_					)





from functools import partial
from typing import Any, Callable, Dict, List, Type, TypeVar, Union, overload

import torch
import torch.nn as nn
import torch.types

def 		snake_case_   (				lowercase__     :    torch.Tensor       ,     lowercase__     :    torch.Tensor       ,     lowercase__     :    bool     ):






				'''simple docstring'''






				if not inplace:
								_lowerCAmelCase  						=ma + ma
				else:
								ma += ma

				return ma

def 		snake_case_   (				lowercase__     :    torch.Tensor       ,     lowercase__     :    List[int]     ):






				'''simple docstring'''






				_lowerCAmelCase  						=-1 * len(lowercase__     )
				_lowerCAmelCase  						=list(range(len(tensor.shape[:zero_index]     )     )     )
				return tensor.permute(first_inds + [zero_index + i for i in inds]     )

def 		snake_case_   (				lowercase__     :    torch.Tensor       ,     lowercase__     :    int     ):






				'''simple docstring'''






				return t.reshape(t.shape[:-no_dims] + (-1,)     )

def 		snake_case_   (				lowercase__     :    torch.Tensor       ,     lowercase__     :    torch.Tensor       ,     lowercase__     :    int       ,     lowercase__     :    float = 1e-4     ):






				'''simple docstring'''






				_lowerCAmelCase  						=mask.expand(*value.shape     )
				return torch.sum(mask * value       ,     dim=lowercase__     ) / (eps + torch.sum(lowercase__       ,     dim=lowercase__     ))

def 		snake_case_   (				lowercase__     :    torch.Tensor       ,     lowercase__     :    torch.types.Number = 2.3_1_2_5       ,     lowercase__     :    torch.types.Number = 2_1.6_8_7_5       ,     lowercase__     :    int = 64     ):






				'''simple docstring'''






				_lowerCAmelCase  						=torch.linspace(lowercase__       ,     lowercase__       ,     no_bins - 1       ,     device=pts.device     )
				_lowerCAmelCase  						=torch.sqrt(torch.sum((pts.unsqueeze(-2     ) - pts.unsqueeze(-3     )) ** 2       ,     dim=-1     )     )
				return torch.bucketize(lowercase__       ,     lowercase__     )

def 		snake_case_   (				lowercase__     :    Callable[[list], Any]       ,     lowercase__     :    List[dict]     ):






				'''simple docstring'''






				_lowerCAmelCase  						=dicts[0]
				_lowerCAmelCase  						={}
				for k, v in first.items():
								_lowerCAmelCase  						=[d[k] for d in dicts]
								if isinstance(lowercase__       ,     lowercase__     ):
												_lowerCAmelCase  						=dict_multimap(lowercase__       ,     lowercase__     )
								else:
												_lowerCAmelCase  						=fn(lowercase__     )

				return new_dict

def 		snake_case_   (				lowercase__     :    torch.Tensor       ,     lowercase__     :    torch.Tensor     ):






				'''simple docstring'''






				_lowerCAmelCase  						=v_bins.view(((1,) * len(x.shape     )) + (len(lowercase__     ),)     )
				_lowerCAmelCase  						=x[..., None] - reshaped_bins
				_lowerCAmelCase  						=torch.argmin(torch.abs(lowercase__     )       ,     dim=-1     )
				return nn.functional.one_hot(lowercase__       ,     num_classes=len(lowercase__     )     ).float()

def 		snake_case_   (				lowercase__     :    torch.Tensor       ,     lowercase__     :    torch.Tensor       ,     lowercase__     :    int = 0       ,     lowercase__     :    int = 0     ):






				'''simple docstring'''






				_lowerCAmelCase  						=[]
				for i, s in enumerate(data.shape[:no_batch_dims]     ):
								_lowerCAmelCase  						=torch.arange(lowercase__     )
								_lowerCAmelCase  						=r.view(*(*((1,) * i), -1, *((1,) * (len(inds.shape     ) - i - 1)))     )
								ranges.append(lowercase__     )

				_lowerCAmelCase  						=[slice(lowercase__     ) for _ in range(len(data.shape     ) - no_batch_dims     )]
				_lowerCAmelCase  						=inds
				ranges.extend(lowercase__     )
				# Matt note: Editing this to get around the behaviour of using a list as an array index changing
				# in recent Numpy versions
				return data[tuple(lowercase__     )]


__SCREAMING_SNAKE_CASE	:							str           =  TypeVar('''T''')

def 		snake_case_   (				lowercase__     :    Callable[[T], Any]       ,     lowercase__     :    Dict[Any, Union[dict, list, tuple, T]]       ,     lowercase__     :    Type[T]     ):






				'''simple docstring'''






				_lowerCAmelCase  						={}
				for k, v in dic.items():
								if isinstance(lowercase__       ,     lowercase__     ):
												_lowerCAmelCase  						=dict_map(lowercase__       ,     lowercase__       ,     lowercase__     )
								else:
												_lowerCAmelCase  						=tree_map(lowercase__       ,     lowercase__       ,     lowercase__     )

				return new_dict

@overload
def 		snake_case_   (				lowercase__     :    Callable[[T], Any]       ,     lowercase__     :    T       ,     lowercase__     :    Type[T]     ):






				'''simple docstring'''






				...

@overload
def 		snake_case_   (				lowercase__     :    Callable[[T], Any]       ,     lowercase__     :    dict       ,     lowercase__     :    Type[T]     ):






				'''simple docstring'''






				...

@overload
def 		snake_case_   (				lowercase__     :    Callable[[T], Any]       ,     lowercase__     :    list       ,     lowercase__     :    Type[T]     ):






				'''simple docstring'''






				...

@overload
def 		snake_case_   (				lowercase__     :    Callable[[T], Any]       ,     lowercase__     :    tuple       ,     lowercase__     :    Type[T]     ):






				'''simple docstring'''






				...

def 		snake_case_   (				lowercase__     :    Optional[Any]       ,     lowercase__     :    str       ,     lowercase__     :    Optional[int]     ):






				'''simple docstring'''






				if isinstance(lowercase__       ,     lowercase__     ):
								return dict_map(lowercase__       ,     lowercase__       ,     lowercase__     )
				elif isinstance(lowercase__       ,     lowercase__     ):
								return [tree_map(lowercase__       ,     lowercase__       ,     lowercase__     ) for x in tree]
				elif isinstance(lowercase__       ,     lowercase__     ):
								return tuple(tree_map(lowercase__       ,     lowercase__       ,     lowercase__     ) for x in tree     )
				elif isinstance(lowercase__       ,     lowercase__     ):
								return fn(lowercase__     )
				else:
								print(type(lowercase__     )     )
								raise ValueError("""Not supported"""     )





__SCREAMING_SNAKE_CASE	:							Any           =  partial(tree_map, leaf_type=torch.Tensor)

