
'''simple docstring'''





import collections
import types

import numpy as np

from ..utils import (
    add_end_docstrings,
    is_tensorflow_probability_available,
    is_tf_available,
    is_torch_available,
    requires_backends,
)
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, Dataset, Pipeline, PipelineException


if is_torch_available():
     import torch

     from ..models.auto.modeling_auto import (
         MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
         MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
     )

if is_tf_available() and is_tensorflow_probability_available():
     import tensorflow as tf
     import tensorflow_probability as tfp

     from ..models.auto.modeling_tf_auto import (
         TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
         TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
     )



class  lowerCAmelCase__   (       UpperCamelCase       ):



  '''simple docstring'''






  def __call__(self  : Union[str, Any]	, lowerCAmelCase_  : int=None	, lowerCAmelCase_  : Union[str, Any]=None	, **lowerCAmelCase_  : Optional[int]    )   ->       Union[str, Any]:
        # Returns tqa_pipeline_inputs of shape:
        # [
        #   {"table": pd.DataFrame, "query": List[str]},
        #   ...,
        #   {"table": pd.DataFrame, "query" : List[str]}
        # ]
        requires_backends(self	, "pandas"    )
        import pandas as pd

        if table is None:
              raise ValueError("Keyword argument `table` cannot be None."    )
        elif query is None:
              if isinstance(lowerCAmelCase_	, lowerCAmelCase_    ) and table.get("query"    ) is not None and table.get("table"    ) is not None:
                    snake_case_						       =							[table]
              elif isinstance(lowerCAmelCase_	, lowerCAmelCase_    ) and len(lowerCAmelCase_    ) > 0:
                    if not all(isinstance(lowerCAmelCase_	, lowerCAmelCase_    ) for d in table    ):
                          raise ValueError(
                              f'''Keyword argument `table` should be a list of dict, but is {(type(lowerCAmelCase_    ) for d in table)}'''    )

                    if table[0].get("query"    ) is not None and table[0].get("table"    ) is not None:
                          snake_case_						       =							table
                    else:
                          raise ValueError(
                              "If keyword argument `table` is a list of dictionaries, each dictionary should have a `table`"
                              f''' and `query` key, but only dictionary has keys {table[0].keys()} `table` and `query` keys.'''    )
              elif Dataset is not None and isinstance(lowerCAmelCase_	, lowerCAmelCase_    ) or isinstance(lowerCAmelCase_	, types.GeneratorType    ):
                    return table
              else:
                    raise ValueError(
                        "Invalid input. Keyword argument `table` should be either of type `dict` or `list`, but "
                        f'''is {type(lowerCAmelCase_    )})'''    )
        else:
              snake_case_						       =							[{"table": table, "query": query}]

        for tqa_pipeline_input in tqa_pipeline_inputs:
              if not isinstance(tqa_pipeline_input["table"]	, pd.DataFrame    ):
                    if tqa_pipeline_input["table"] is None:
                          raise ValueError("Table cannot be None."    )

                    snake_case_						       =							pd.DataFrame(tqa_pipeline_input["table"]    )

        return tqa_pipeline_inputs



@add_end_docstrings(UpperCamelCase       )
class  lowerCAmelCase__   (       UpperCamelCase       ):



  '''simple docstring'''






  _UpperCamelCase						= 'table,query'

  def __init__(self  : List[Any]	, lowerCAmelCase_  : str=TableQuestionAnsweringArgumentHandler()	, *lowerCAmelCase_  : Optional[Any]	, **lowerCAmelCase_  : Optional[int]    )   ->       Optional[int]:
        super().__init__(*lowerCAmelCase_	, **lowerCAmelCase_    )
        snake_case_						       =							args_parser

        self.check_model_type(
            dict(
                TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items()
                + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items()    )
            if self.framework == "tf"
            else dict(
                MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items() + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items()    )    )

        snake_case_						       =							bool(getattr(self.model.config	, "aggregation_labels"	, lowerCAmelCase_    )    ) and bool(
            getattr(self.model.config	, "num_aggregation_labels"	, lowerCAmelCase_    )    )
        snake_case_						       =							"tapas" if hasattr(self.model.config	, "aggregation_labels"    ) else None

  def 		_lowerCamelCase	(self  : Optional[Any]	, **lowerCAmelCase_  : Dict    )   ->       Any:
        return self.model(**lowerCAmelCase_    )

  def 		_lowerCamelCase	(self  : Tuple	, **lowerCAmelCase_  : Dict    )   ->       Any:
        if self.framework == "pt":
              snake_case_						       =							[]
              snake_case_						       =							[]
              snake_case_						       =							None
              snake_case_						       =							inputs["input_ids"].shape[0]

              snake_case_						       =							inputs["input_ids"].to(self.device    )
              snake_case_						       =							inputs["attention_mask"].to(self.device    )
              snake_case_						       =							inputs["token_type_ids"].to(self.device    )
              snake_case_						       =							None

              for index in range(lowerCAmelCase_    ):
                    # If sequences have already been processed, the token type IDs will be created according to the previous
                    # answer.
                    if prev_answers is not None:
                          snake_case_						       =							token_type_ids_example[:, 3]  # shape (seq_len,)
                          snake_case_						       =							np.zeros_like(prev_labels_example.cpu().numpy()    )  # shape (seq_len,)

                          snake_case_						       =							token_type_ids[index]  # shape (seq_len, 7)
                          for i in range(model_labels.shape[0]    ):
                                snake_case_						       =							token_type_ids_example[:, 0].tolist()[i]
                                snake_case_						       =							token_type_ids_example[:, 1].tolist()[i] - 1
                                snake_case_						       =							token_type_ids_example[:, 2].tolist()[i] - 1

                                if row_id >= 0 and col_id >= 0 and segment_id == 1:
                                      snake_case_						       =							int(prev_answers[(col_id, row_id)]    )

                          snake_case_						       =							torch.from_numpy(lowerCAmelCase_    ).type(torch.long    ).to(self.device    )

                    snake_case_						       =							input_ids[index]
                    snake_case_						       =							attention_mask[index]  # shape (seq_len,)
                    snake_case_						       =							token_type_ids[index]  # shape (seq_len, 7)
                    snake_case_						       =							self.model(
                        input_ids=input_ids_example.unsqueeze(0    )	, attention_mask=attention_mask_example.unsqueeze(0    )	, token_type_ids=token_type_ids_example.unsqueeze(0    )	, )
                    snake_case_						       =							outputs.logits

                    if self.aggregate:
                          all_aggregations.append(outputs.logits_aggregation    )

                    all_logits.append(lowerCAmelCase_    )

                    snake_case_						       =							torch.distributions.Bernoulli(logits=lowerCAmelCase_    )
                    snake_case_						       =							dist_per_token.probs * attention_mask_example.type(torch.floataa    ).to(
                        dist_per_token.probs.device    )

                    snake_case_						       =							collections.defaultdict(lowerCAmelCase_    )
                    for i, p in enumerate(probabilities.squeeze().tolist()    ):
                          snake_case_						       =							token_type_ids_example[:, 0].tolist()[i]
                          snake_case_						       =							token_type_ids_example[:, 1].tolist()[i] - 1
                          snake_case_						       =							token_type_ids_example[:, 2].tolist()[i] - 1
                          if col >= 0 and row >= 0 and segment_id == 1:
                                coords_to_probs[(col, row)].append(lowerCAmelCase_    )

                    snake_case_						       =							{key: np.array(coords_to_probs[key]    ).mean() > 0.5 for key in coords_to_probs}

              snake_case_						       =							torch.cat(tuple(lowerCAmelCase_    )	, 0    )

              return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(lowerCAmelCase_    )	, 0    ))
        else:
              snake_case_						       =							[]
              snake_case_						       =							[]
              snake_case_						       =							None
              snake_case_						       =							inputs["input_ids"].shape[0]

              snake_case_						       =							inputs["input_ids"]
              snake_case_						       =							inputs["attention_mask"]
              snake_case_						       =							inputs["token_type_ids"].numpy()
              snake_case_						       =							None

              for index in range(lowerCAmelCase_    ):
                    # If sequences have already been processed, the token type IDs will be created according to the previous
                    # answer.
                    if prev_answers is not None:
                          snake_case_						       =							token_type_ids_example[:, 3]  # shape (seq_len,)
                          snake_case_						       =							np.zeros_like(lowerCAmelCase_	, dtype=np.intaa    )  # shape (seq_len,)

                          snake_case_						       =							token_type_ids[index]  # shape (seq_len, 7)
                          for i in range(model_labels.shape[0]    ):
                                snake_case_						       =							token_type_ids_example[:, 0].tolist()[i]
                                snake_case_						       =							token_type_ids_example[:, 1].tolist()[i] - 1
                                snake_case_						       =							token_type_ids_example[:, 2].tolist()[i] - 1

                                if row_id >= 0 and col_id >= 0 and segment_id == 1:
                                      snake_case_						       =							int(prev_answers[(col_id, row_id)]    )

                          snake_case_						       =							model_labels

                    snake_case_						       =							input_ids[index]
                    snake_case_						       =							attention_mask[index]  # shape (seq_len,)
                    snake_case_						       =							token_type_ids[index]  # shape (seq_len, 7)
                    snake_case_						       =							self.model(
                        input_ids=np.expand_dims(lowerCAmelCase_	, axis=0    )	, attention_mask=np.expand_dims(lowerCAmelCase_	, axis=0    )	, token_type_ids=np.expand_dims(lowerCAmelCase_	, axis=0    )	, )
                    snake_case_						       =							outputs.logits

                    if self.aggregate:
                          all_aggregations.append(outputs.logits_aggregation    )

                    all_logits.append(lowerCAmelCase_    )

                    snake_case_						       =							tfp.distributions.Bernoulli(logits=lowerCAmelCase_    )
                    snake_case_						       =							dist_per_token.probs_parameter() * tf.cast(lowerCAmelCase_	, tf.floataa    )

                    snake_case_						       =							collections.defaultdict(lowerCAmelCase_    )
                    snake_case_						       =							token_type_ids_example
                    for i, p in enumerate(tf.squeeze(lowerCAmelCase_    ).numpy().tolist()    ):
                          snake_case_						       =							token_type_ids_example[:, 0].tolist()[i]
                          snake_case_						       =							token_type_ids_example[:, 1].tolist()[i] - 1
                          snake_case_						       =							token_type_ids_example[:, 2].tolist()[i] - 1
                          if col >= 0 and row >= 0 and segment_id == 1:
                                coords_to_probs[(col, row)].append(lowerCAmelCase_    )

                    snake_case_						       =							{key: np.array(coords_to_probs[key]    ).mean() > 0.5 for key in coords_to_probs}

              snake_case_						       =							tf.concat(tuple(lowerCAmelCase_    )	, 0    )

              return (logits_batch,) if not self.aggregate else (logits_batch, tf.concat(tuple(lowerCAmelCase_    )	, 0    ))

  def __call__(self  : Any	, *lowerCAmelCase_  : Union[str, Any]	, **lowerCAmelCase_  : Optional[Any]    )   ->       Optional[Any]:
        snake_case_						       =							self._args_parser(*lowerCAmelCase_	, **lowerCAmelCase_    )

        snake_case_						       =							super().__call__(lowerCAmelCase_	, **lowerCAmelCase_    )
        if len(lowerCAmelCase_    ) == 1:
              return results[0]
        return results

  def 		_lowerCamelCase	(self  : str	, lowerCAmelCase_  : Optional[int]=None	, lowerCAmelCase_  : Optional[Any]=None	, lowerCAmelCase_  : Any=None	, **lowerCAmelCase_  : Optional[int]    )   ->       int:
        snake_case_						       =							{}
        if padding is not None:
              snake_case_						       =							padding
        if truncation is not None:
              snake_case_						       =							truncation

        snake_case_						       =							{}
        if sequential is not None:
              snake_case_						       =							sequential
        return preprocess_params, forward_params, {}

  def 		_lowerCamelCase	(self  : Optional[int]	, lowerCAmelCase_  : List[Any]	, lowerCAmelCase_  : List[Any]=None	, lowerCAmelCase_  : List[str]=True	, lowerCAmelCase_  : Optional[Any]=None    )   ->       Optional[Any]:
        if truncation is None:
              if self.type == "tapas":
                    snake_case_						       =							"drop_rows_to_fit"
              else:
                    snake_case_						       =							"do_not_truncate"

        snake_case_       ,	snake_case_						       =							pipeline_input["table"], pipeline_input["query"]
        if table.empty:
              raise ValueError("table is empty"    )
        if query is None or query == "":
              raise ValueError("query is empty"    )
        snake_case_						       =							self.tokenizer(lowerCAmelCase_	, lowerCAmelCase_	, return_tensors=self.framework	, truncation=lowerCAmelCase_	, padding=lowerCAmelCase_    )
        snake_case_						       =							table
        return inputs

  def 		_lowerCamelCase	(self  : Union[str, Any]	, lowerCAmelCase_  : Union[str, Any]	, lowerCAmelCase_  : Dict=False    )   ->       Optional[Any]:
        snake_case_						       =							model_inputs.pop("table"    )

        if self.type == "tapas":
              if sequential:
                    snake_case_						       =							self.sequential_inference(**lowerCAmelCase_    )
              else:
                    snake_case_						       =							self.batch_inference(**lowerCAmelCase_    )
        else:
              snake_case_						       =							self.model.generate(**lowerCAmelCase_    )
        snake_case_						       =							{"model_inputs": model_inputs, "table": table, "outputs": outputs}
        return model_outputs


  def 		_lowerCamelCase	(self  : Union[str, Any]	, lowerCAmelCase_  : List[str]    )   ->       Union[str, Any]:
        snake_case_						       =							model_outputs["model_inputs"]
        snake_case_						       =							model_outputs["table"]
        snake_case_						       =							model_outputs["outputs"]
        if self.type == "tapas":
              if self.aggregate:
                    snake_case_       ,	snake_case_						       =							outputs[:2]
                    snake_case_						       =							self.tokenizer.convert_logits_to_predictions(lowerCAmelCase_	, lowerCAmelCase_	, lowerCAmelCase_    )
                    snake_case_       ,	snake_case_						       =							predictions
                    snake_case_						       =							{i: self.model.config.aggregation_labels[pred] for i, pred in enumerate(lowerCAmelCase_    )}

                    snake_case_						       =							self.model.config.no_aggregation_label_index
                    snake_case_						       =							{
                        i: aggregators[i] + " > " for i, pred in enumerate(lowerCAmelCase_    ) if pred != no_agg_label_index
                    }
              else:
                    snake_case_						       =							outputs[0]
                    snake_case_						       =							self.tokenizer.convert_logits_to_predictions(lowerCAmelCase_	, lowerCAmelCase_    )
                    snake_case_						       =							predictions[0]
                    snake_case_						       =							{}
                    snake_case_						       =							{}
              snake_case_						       =							[]
              for index, coordinates in enumerate(lowerCAmelCase_    ):
                    snake_case_						       =							[table.iat[coordinate] for coordinate in coordinates]
                    snake_case_						       =							aggregators.get(lowerCAmelCase_	, ""    )
                    snake_case_						       =							aggregators_prefix.get(lowerCAmelCase_	, ""    )
                    snake_case_						       =							{
                        "answer": aggregator_prefix + ", ".join(lowerCAmelCase_    ),
                        "coordinates": coordinates,
                        "cells": [table.iat[coordinate] for coordinate in coordinates],
                    }
                    if aggregator:
                          snake_case_						       =							aggregator

                    answers.append(lowerCAmelCase_    )
              if len(lowerCAmelCase_    ) == 0:
                    raise PipelineException("Empty answer"    )
        else:
              snake_case_						       =							[{"answer": answer} for answer in self.tokenizer.batch_decode(lowerCAmelCase_	, skip_special_tokens=lowerCAmelCase_    )]

        return answers if len(lowerCAmelCase_    ) > 1 else answers[0]



'''simple docstring'''





def   snake_case_       (							_a     :							int = 1_000			):
      return sum(i for i in range(_a			) if i % 3 == 0 or i % 5 == 0			)


if __name__ == "__main__":
     print(F"""{solution() = }""")

