






import dataclasses
import enum
import functools
import math
import re

# The following script is adapted from the script of TaPas.
# Original: https://github.com/google-research/tapas/master/wikisql_utils.py
from typing import Any, List, Text


A_	:	Union[str, Any]				=				'none'
A_	:	List[Any]				=				'none'

def 						snake_case      (UpperCAmelCase__			,					UpperCAmelCase__						):
  UpperCamelCase_:      Tuple					   =       value.split(lowercase_						)
  return len(lowercase_						) > 1 and any((len(lowercase_						) == 3 for x in split)						)

def 						snake_case      (UpperCAmelCase__						):
  if isinstance(lowercase_			,					lowercase_						):
    return value
  if isinstance(lowercase_			,					lowercase_						):
    return float(lowercase_						)
  if not isinstance(lowercase_			,					lowercase_						):
    raise ValueError('Argument value is not a string. Can\'t parse it as float'						)
  UpperCamelCase_:      Any					   =       value

  try:
    # Example: 1,000.7
    if "." in sanitized and "," in sanitized:
      return float(sanitized.replace(','			,					''						)						)
    # 1,000
    if "," in sanitized and _split_thousands(','			,					lowercase_						):
      return float(sanitized.replace(','			,					''						)						)
    # 5,5556
    if "," in sanitized and sanitized.count(','						) == 1 and not _split_thousands(','			,					lowercase_						):
      return float(sanitized.replace(','			,					'.'						)						)
    # 0.0.0.1
    if sanitized.count('.'						) > 1:
      return float(sanitized.replace('.'			,					''						)						)
    # 0,0,0,1
    if sanitized.count(','						) > 1:
      return float(sanitized.replace(','			,					''						)						)
    return float(lowercase_						)
  except ValueError:
    # Avoid adding the sanitized value in the error message.
    raise ValueError('Unable to convert value to float'						)

def 						snake_case      (UpperCAmelCase__						):
  if answer is None:
    return None
  try:
    UpperCamelCase_:      str					   =       convert_to_float(lowercase_						)
    if isinstance(lowercase_			,					lowercase_						) and math.isnan(lowercase_						):
      return None
    return value
  except ValueError:
    return answer.lower()


A_	:	List[str]				=				{
    'text': lambda x: x,
    'real': convert_to_float,
}




class        _lowerCAmelCase( enum.Enum      ):





       """simple docstring"""







       a       :	Optional[Any]								=0
       a       :	Tuple								=1
       a       :	Dict								=2
       a       :	int								=3
       a       :	Optional[Any]								=4
       a       :	Optional[Any]								=5







class        _lowerCAmelCase( enum.Enum      ):





       """simple docstring"""







       a       :	Optional[Any]								=0
       a       :	Optional[Any]								=1
       a       :	str								=2







@dataclasses.dataclass
class        _lowerCAmelCase:





       """simple docstring"""







       a       :	Text
       a       :	_Operator
       a       :	Any







A_	:	List[str]				=				re.compile(r'\w+|[^\w\s]+', re.UNICODE | re.MULTILINE | re.DOTALL)

def 						snake_case      (UpperCAmelCase__						):
  return list(_TOKENIZER.findall(x.lower()						)						)

def 						snake_case      (UpperCAmelCase__			,					UpperCAmelCase__			,					UpperCAmelCase__						):
  if operator == _Operator.EQUALS:
    return src == tgt
  elif operator == _Operator.GREATER:
    return src > tgt
  elif operator == _Operator.LESSER:
    return src < tgt
  raise ValueError(F'''Unknown operator: {operator}'''						)

def 						snake_case      (UpperCAmelCase__			,					UpperCAmelCase__			,					UpperCAmelCase__						):
  UpperCamelCase_:      Tuple					   =       table['types']
  return _TYPE_CONVERTER[types[column]](lowercase_						)

def 						snake_case      (UpperCAmelCase__						):
  return isinstance(lowercase_			,					lowercase_						)

def 						snake_case      (UpperCAmelCase__			,					UpperCAmelCase__			,					UpperCAmelCase__						):
  for cond in conditions:
    UpperCamelCase_:      List[Any]					   =       row[cond.column]

    UpperCamelCase_:      Any					   =       _parse_value(lowercase_			,					cond.column			,					cond.cmp_value						)

    if _is_string(lowercase_						) and _is_string(lowercase_						):
      UpperCamelCase_:      Tuple					   =       _normalize_for_match(lowercase_						)
      UpperCamelCase_:      Optional[int]					   =       _normalize_for_match(lowercase_						)

    if not isinstance(lowercase_			,					type(lowercase_						)						):
      raise ValueError('Type difference {} != {}'.format(type(lowercase_						)			,					type(lowercase_						)						)						)

    if not _compare(cond.operator			,					lowercase_			,					lowercase_						):
      return False
  return True

def 						snake_case      (UpperCAmelCase__			,					UpperCAmelCase__			,					UpperCAmelCase__						):
  if not answer_coordinates:
    if aggregation_op == _Aggregation.COUNT:
      return 0.0
    else:
      return EMPTY_ANSWER_AGG

    # Count can support non numeric answers.
  if aggregation_op == _Aggregation.COUNT:
    return float(len(lowercase_						)						)

  # If we have just one answer, if float returns it or try a conversion.
  UpperCamelCase_:      Any					   =       [table['rows'][i][j] for (i, j) in answer_coordinates]
  if len(lowercase_						) == 1:
    try:
      return convert_to_float(values[0]						)
    except ValueError as e:
      if aggregation_op != _Aggregation.NONE:
        raise e

  if aggregation_op == _Aggregation.NONE:
    return None

  # Other aggregation only support numeric values. Bail out if we have strings.
  if not all((isinstance(lowercase_			,					(int, float)						) for v in values)						):
    return None

  if aggregation_op == _Aggregation.SUM:
    return float(sum(lowercase_						)						)
  elif aggregation_op == _Aggregation.AVERAGE:
    return sum(lowercase_						) / len(lowercase_						)
  else:
    raise ValueError(F'''Unknown aggregation: {aggregation_op}'''						)

def 						snake_case      (UpperCAmelCase__			,					UpperCAmelCase__						):
  UpperCamelCase_:      Union[str, Any]					   =       sql_query['agg']
  if aggregation_op_index >= 3:
    UpperCamelCase_:      Optional[int]					   =       _Aggregation(lowercase_						)
  else:
    UpperCamelCase_:      List[Any]					   =       _Aggregation.NONE

  UpperCamelCase_:      str					   =       sql_query['sel']
  UpperCamelCase_:      Tuple					   =       [
      _Condition(lowercase_			,					_Operator(lowercase_						)			,					lowercase_						)
      for column, operator, cmp_value in zip(
          sql_query['conds']['column_index']			,					sql_query['conds']['operator_index']			,					sql_query['conds']['condition']						)
  ]

  UpperCamelCase_:      List[str]					   =       []
  for row in range(len(table['rows']						)						):
    if _respect_conditions(lowercase_			,					table['rows'][row]			,					lowercase_						):
      indices.append((row, target_column)						)

  if not indices:
    return [], aggregation_op

  if len(lowercase_						) == 1:
    return indices, aggregation_op

  # Parsing of MIN/MAX.
  if aggregation_op_index in (1, 2):
    UpperCamelCase_:      Optional[Any]					   =       {2: min, 1: max}
    UpperCamelCase_:      Optional[int]					   =       [(table['rows'][i][j], index) for index, (i, j) in enumerate(lowercase_						)]
    UpperCamelCase_:      Dict					   =       functools.reduce(operators[sql_query['agg']]			,					lowercase_						)

    UpperCamelCase_:      Tuple					   =       [indices[reduced[1]]]
    return ret, _Aggregation.NONE

  return indices, aggregation_op

def 						snake_case      (UpperCAmelCase__			,					UpperCAmelCase__			,					UpperCAmelCase__						):
  if float_answer is not None:
    return [str(lowercase_						)]
  return [str(table['real_rows'][r][c]						) for r, c in answer_coordinates]

def 						snake_case      (UpperCAmelCase__			,					UpperCAmelCase__						):
  UpperCamelCase_:      Dict					   =       _get_answer_coordinates(lowercase_			,					lowercase_						)
  UpperCamelCase_:      Union[str, Any]					   =       _get_float_answer(lowercase_			,					lowercase_			,					lowercase_						)
  UpperCamelCase_:      int					   =       _get_answer_text(lowercase_			,					lowercase_			,					lowercase_						)
  # keep the original data the same with TaPas
  if len(lowercase_						) == 0:
    UpperCamelCase_:      Tuple					   =       [EMPTY_ANSWER]
  return answer_text







# Lint as: python3

import hashlib
from typing import Union

def 						snake_case      (UpperCAmelCase__						) ->       bytes:
  if isinstance(UpperCAmelCase__			,					UpperCAmelCase__						):
    # Data already in bytes, returns as it as
    return hash_data
  elif isinstance(UpperCAmelCase__			,					UpperCAmelCase__						):
    # We keep the data as it as for it ot be later encoded to UTF-8
    # However replace `\\` with `/` for Windows compatibility
    UpperCamelCase_:      List[str]					   =       hash_data.replace('\\'			,					'/'						)
  elif isinstance(UpperCAmelCase__			,					UpperCAmelCase__						):
    UpperCamelCase_:      Union[str, Any]					   =       str(UpperCAmelCase__						)
  else:
    # If data is not of the required type, raise error
    raise InvalidKeyError(UpperCAmelCase__						)

  return hash_data.encode('utf-8'						)




class        _lowerCAmelCase( UpperCAmelCase_      ):





       """simple docstring"""







       def __init__(      self						,    _lowerCamelCase							):
         UpperCamelCase_:      int					   =       '\nFAILURE TO GENERATE DATASET: Invalid key type detected'
         UpperCamelCase_:      Dict					   =       f'''\nFound Key {hash_data} of type {type(_lowerCamelCase							)}'''
         UpperCamelCase_:      Any					   =       '\nKeys should be either str, int or bytes type'
         super().__init__(f'''{self.prefix}{self.err_msg}{self.suffix}'''							)







class        _lowerCAmelCase( UpperCAmelCase_      ):





       """simple docstring"""







       def __init__(      self						,    _lowerCamelCase						,    _lowerCamelCase						,    _lowerCamelCase=""							):
         UpperCamelCase_:      int					   =       key
         UpperCamelCase_:      Dict					   =       duplicate_key_indices
         UpperCamelCase_:      int					   =       fix_msg
         UpperCamelCase_:      List[Any]					   =       'Found multiple examples generated with the same key'
         if len(_lowerCamelCase							) <= 2_0:
           UpperCamelCase_:      Tuple					   =       f'''\nThe examples at index {', '.join(_lowerCamelCase							)} have the key {key}'''
         else:
           UpperCamelCase_:      Optional[int]					   =       f'''\nThe examples at index {', '.join(duplicate_key_indices[:2_0]							)}... ({len(_lowerCamelCase							) - 2_0} more) have the key {key}'''
         UpperCamelCase_:      List[Any]					   =       '\n' + fix_msg if fix_msg else ''
         super().__init__(f'''{self.prefix}{self.err_msg}{self.suffix}'''							)







class        _lowerCAmelCase:





       """simple docstring"""







       def __init__(      self						,    _lowerCamelCase							):
         UpperCamelCase_:      int					   =       hashlib.mda(_as_bytes(_lowerCamelCase							)							)





       def     _a					(      self						,    _lowerCamelCase							):
         UpperCamelCase_:      Optional[int]					   =       self._split_mda.copy()
         UpperCamelCase_:      str					   =       _as_bytes(_lowerCamelCase							)
         mda.update(_lowerCamelCase							)
         # Convert to integer with hexadecimal conversion
         return int(mda.hexdigest()						,    1_6							)