'''simple docstring'''

import json
import os
import shutil
import tempfile
import unittest
from multiprocessing import get_context
from pathlib import Path

import datasets
import numpy as np
from datasets import load_dataset
from parameterized import parameterized

from transformers import AutoProcessor
from transformers.models.wavaveca import WavaVecaCTCTokenizer, WavaVecaFeatureExtractor
from transformers.models.wavaveca.tokenization_wavaveca import VOCAB_FILES_NAMES
from transformers.testing_utils import require_pyctcdecode, require_torch, require_torchaudio, slow
from transformers.utils import FEATURE_EXTRACTOR_NAME, is_pyctcdecode_available, is_torch_available

from ..wavaveca.test_feature_extraction_wavaveca import floats_list


if is_pyctcdecode_available():
 from huggingface_hub import snapshot_download
 from pyctcdecode import BeamSearchDecoderCTC

 from transformers.models.wavaveca_with_lm import WavaVecaProcessorWithLM
 from transformers.models.wavaveca_with_lm.processing_wavaveca_with_lm import WavaVecaDecoderWithLMOutput

if is_torch_available():
 from transformers import WavaVecaForCTC







@require_pyctcdecode
class 				_lowercase     (				unittest.TestCase			):


 '''simple docstring'''






 def a					(      self   :	Any							)  ->    Dict:
  __lowerCAmelCase											=						"""| <pad> <unk> <s> </s> a b c d e f g h i j k""".split()
  __lowerCAmelCase											=						dict(zip(__lowerCamelCase      ,       range(len(__lowerCamelCase							)							)							)							)

  __lowerCAmelCase											=						{
      """unk_token""": """<unk>""",
      """bos_token""": """<s>""",
      """eos_token""": """</s>""",
  }
  __lowerCAmelCase											=						{
      """feature_size""": 1,
      """padding_value""": 0.0,
      """sampling_rate""": 1_60_00,
      """return_attention_mask""": False,
      """do_normalize""": True,
  }

  __lowerCAmelCase											=						tempfile.mkdtemp()
  __lowerCAmelCase											=						os.path.join(self.tmpdirname      ,       VOCAB_FILES_NAMES["""vocab_file"""]							)
  __lowerCAmelCase											=						os.path.join(self.tmpdirname      ,       __lowerCamelCase							)
  with open(self.vocab_file      ,       """w"""      ,       encoding="""utf-8"""							) as fp:
   fp.write(json.dumps(__lowerCamelCase							) + """\n"""							)

  with open(self.feature_extraction_file      ,       """w"""      ,       encoding="""utf-8"""							) as fp:
   fp.write(json.dumps(__lowerCamelCase							) + """\n"""							)

  # load decoder from hub
  __lowerCAmelCase											=						"""hf-internal-testing/ngram-beam-search-decoder"""
 def a					(      self   :	str      ,       **SCREAMING_SNAKE_CASE__   :	str							)  ->    int:
  __lowerCAmelCase											=						self.add_kwargs_tokens_map.copy()
  kwargs.update(__lowerCamelCase							)
  return WavaVecaCTCTokenizer.from_pretrained(self.tmpdirname      ,       **__lowerCamelCase							)
 def a					(      self   :	str      ,       **SCREAMING_SNAKE_CASE__   :	Dict							)  ->    int:
  return WavaVecaFeatureExtractor.from_pretrained(self.tmpdirname      ,       **__lowerCamelCase							)
 def a					(      self   :	Union[str, Any]      ,       **SCREAMING_SNAKE_CASE__   :	Optional[int]							)  ->    Union[str, Any]:
  return BeamSearchDecoderCTC.load_from_hf_hub(self.decoder_name      ,       **__lowerCamelCase							)
 def a					(      self   :	Any							)  ->    Tuple:
  shutil.rmtree(self.tmpdirname							)
 def a					(      self   :	Union[str, Any]							)  ->    List[str]:
  __lowerCAmelCase											=						self.get_tokenizer()
  __lowerCAmelCase											=						self.get_feature_extractor()
  __lowerCAmelCase											=						self.get_decoder()

  __lowerCAmelCase											=						WavaVecaProcessorWithLM(tokenizer=__lowerCamelCase      ,       feature_extractor=__lowerCamelCase      ,       decoder=__lowerCamelCase							)

  processor.save_pretrained(self.tmpdirname							)
  __lowerCAmelCase											=						WavaVecaProcessorWithLM.from_pretrained(self.tmpdirname							)

  # tokenizer
  self.assertEqual(processor.tokenizer.get_vocab()      ,       tokenizer.get_vocab()							)
  self.assertIsInstance(processor.tokenizer      ,       __lowerCamelCase							)

  # feature extractor
  self.assertEqual(processor.feature_extractor.to_json_string()      ,       feature_extractor.to_json_string()							)
  self.assertIsInstance(processor.feature_extractor      ,       __lowerCamelCase							)

  # decoder
  self.assertEqual(processor.decoder._alphabet.labels      ,       decoder._alphabet.labels							)
  self.assertEqual(
      processor.decoder.model_container[decoder._model_key]._unigram_set      ,       decoder.model_container[decoder._model_key]._unigram_set      ,       )
  self.assertIsInstance(processor.decoder      ,       __lowerCamelCase							)
 def a					(      self   :	Dict							)  ->    Any:
  __lowerCAmelCase											=						WavaVecaProcessorWithLM(
      tokenizer=self.get_tokenizer()      ,       feature_extractor=self.get_feature_extractor()      ,       decoder=self.get_decoder()							)
  processor.save_pretrained(self.tmpdirname							)

  # make sure that error is thrown when decoder alphabet doesn't match
  __lowerCAmelCase											=						WavaVecaProcessorWithLM.from_pretrained(
      self.tmpdirname      ,       alpha=5.0      ,       beta=3.0      ,       score_boundary=-7.0      ,       unk_score_offset=3							)

  # decoder
  self.assertEqual(processor.language_model.alpha      ,       5.0							)
  self.assertEqual(processor.language_model.beta      ,       3.0							)
  self.assertEqual(processor.language_model.score_boundary      ,       -7.0							)
  self.assertEqual(processor.language_model.unk_score_offset      ,       3							)
 def a					(      self   :	Union[str, Any]							)  ->    Optional[int]:
  __lowerCAmelCase											=						self.get_tokenizer()
  # add token to trigger raise
  tokenizer.add_tokens(["""xx"""]							)
  with self.assertRaisesRegex(__lowerCamelCase      ,       """include"""							):
   WavaVecaProcessorWithLM(
       tokenizer=__lowerCamelCase      ,       feature_extractor=self.get_feature_extractor()      ,       decoder=self.get_decoder()							)
 def a					(      self   :	Optional[Any]							)  ->    List[str]:
  __lowerCAmelCase											=						self.get_feature_extractor()
  __lowerCAmelCase											=						self.get_tokenizer()
  __lowerCAmelCase											=						self.get_decoder()

  __lowerCAmelCase											=						WavaVecaProcessorWithLM(tokenizer=__lowerCamelCase      ,       feature_extractor=__lowerCamelCase      ,       decoder=__lowerCamelCase							)

  __lowerCAmelCase											=						floats_list((3, 10_00)							)

  __lowerCAmelCase											=						feature_extractor(__lowerCamelCase      ,       return_tensors="""np"""							)
  __lowerCAmelCase											=						processor(__lowerCamelCase      ,       return_tensors="""np"""							)

  for key in input_feat_extract.keys():
   self.assertAlmostEqual(input_feat_extract[key].sum()      ,       input_processor[key].sum()      ,       delta=1e-2							)
 def a					(      self   :	Tuple							)  ->    List[Any]:
  __lowerCAmelCase											=						self.get_feature_extractor()
  __lowerCAmelCase											=						self.get_tokenizer()
  __lowerCAmelCase											=						self.get_decoder()

  __lowerCAmelCase											=						WavaVecaProcessorWithLM(tokenizer=__lowerCamelCase      ,       feature_extractor=__lowerCamelCase      ,       decoder=__lowerCamelCase							)

  __lowerCAmelCase											=						"""This is a test string"""

  __lowerCAmelCase											=						processor(text=__lowerCamelCase							)

  __lowerCAmelCase											=						tokenizer(__lowerCamelCase							)

  for key in encoded_tok.keys():
   self.assertListEqual(encoded_tok[key]      ,       encoded_processor[key]							)
 def a					(      self   :	int      ,       SCREAMING_SNAKE_CASE__   :	List[str]=(2, 10, 16)      ,       SCREAMING_SNAKE_CASE__   :	Any=77							)  ->    List[Any]:
  np.random.seed(__lowerCamelCase							)
  return np.random.rand(*__lowerCamelCase							)
 def a					(      self   :	Dict							)  ->    int:
  __lowerCAmelCase											=						self.get_feature_extractor()
  __lowerCAmelCase											=						self.get_tokenizer()
  __lowerCAmelCase											=						self.get_decoder()

  __lowerCAmelCase											=						WavaVecaProcessorWithLM(tokenizer=__lowerCamelCase      ,       feature_extractor=__lowerCamelCase      ,       decoder=__lowerCamelCase							)

  __lowerCAmelCase											=						self._get_dummy_logits(shape=(10, 16)      ,       seed=13							)

  __lowerCAmelCase											=						processor.decode(__lowerCamelCase							)

  __lowerCAmelCase											=						decoder.decode_beams(__lowerCamelCase							)[0]

  self.assertEqual(decoded_decoder[0]      ,       decoded_processor.text							)
  self.assertEqual("""</s> <s> </s>"""      ,       decoded_processor.text							)
  self.assertEqual(decoded_decoder[-2]      ,       decoded_processor.logit_score							)
  self.assertEqual(decoded_decoder[-1]      ,       decoded_processor.lm_score							)
 @parameterized.expand([[None], ["""fork"""], ["""spawn"""]]							)
 def a					(      self   :	Optional[Any]      ,       SCREAMING_SNAKE_CASE__   :	Any							)  ->    str:
  __lowerCAmelCase											=						self.get_feature_extractor()
  __lowerCAmelCase											=						self.get_tokenizer()
  __lowerCAmelCase											=						self.get_decoder()

  __lowerCAmelCase											=						WavaVecaProcessorWithLM(tokenizer=__lowerCamelCase      ,       feature_extractor=__lowerCamelCase      ,       decoder=__lowerCamelCase							)

  __lowerCAmelCase											=						self._get_dummy_logits()

  # note: pool should be instantiated *after* Wav2Vec2ProcessorWithLM.
  #       otherwise, the LM won't be available to the pool's sub-processes.
  # manual logic used to allow parameterized test for both pool=None and pool=Pool(...)
  if pool_context is None:
   __lowerCAmelCase											=						processor.batch_decode(__lowerCamelCase							)
  else:
   with get_context(__lowerCamelCase							).Pool() as pool:
    __lowerCAmelCase											=						processor.batch_decode(__lowerCamelCase      ,       __lowerCamelCase							)

  __lowerCAmelCase											=						list(__lowerCamelCase							)

  with get_context("""fork"""							).Pool() as p:
   __lowerCAmelCase											=						decoder.decode_beams_batch(__lowerCamelCase      ,       __lowerCamelCase							)

  __lowerCAmelCase							,       __lowerCAmelCase							,       __lowerCAmelCase											=						[], [], []
  for beams in decoded_beams:
   texts_decoder.append(beams[0][0]							)
   logit_scores_decoder.append(beams[0][-2]							)
   lm_scores_decoder.append(beams[0][-1]							)

  self.assertListEqual(__lowerCamelCase      ,       decoded_processor.text							)
  self.assertListEqual(["""<s> <s> </s>""", """<s> <s> <s>"""]      ,       decoded_processor.text							)
  self.assertListEqual(__lowerCamelCase      ,       decoded_processor.logit_score							)
  self.assertListEqual(__lowerCamelCase      ,       decoded_processor.lm_score							)
 def a					(      self   :	Dict							)  ->    Any:
  __lowerCAmelCase											=						self.get_feature_extractor()
  __lowerCAmelCase											=						self.get_tokenizer()
  __lowerCAmelCase											=						self.get_decoder()

  __lowerCAmelCase											=						WavaVecaProcessorWithLM(tokenizer=__lowerCamelCase      ,       feature_extractor=__lowerCamelCase      ,       decoder=__lowerCamelCase							)

  __lowerCAmelCase											=						self._get_dummy_logits()

  __lowerCAmelCase											=						15
  __lowerCAmelCase											=						-2_0.0
  __lowerCAmelCase											=						-4.0

  __lowerCAmelCase											=						processor.batch_decode(
      __lowerCamelCase      ,       beam_width=__lowerCamelCase      ,       beam_prune_logp=__lowerCamelCase      ,       token_min_logp=__lowerCamelCase      ,       )
  __lowerCAmelCase											=						decoded_processor_out.text

  __lowerCAmelCase											=						list(__lowerCamelCase							)

  with get_context("""fork"""							).Pool() as pool:
   __lowerCAmelCase											=						decoder.decode_beams_batch(
       __lowerCamelCase      ,       __lowerCamelCase      ,       beam_width=__lowerCamelCase      ,       beam_prune_logp=__lowerCamelCase      ,       token_min_logp=__lowerCamelCase      ,       )

  __lowerCAmelCase											=						[d[0][0] for d in decoded_decoder_out]
  __lowerCAmelCase											=						[d[0][2] for d in decoded_decoder_out]
  __lowerCAmelCase											=						[d[0][3] for d in decoded_decoder_out]

  self.assertListEqual(__lowerCamelCase      ,       __lowerCamelCase							)
  self.assertListEqual(["""</s> <s> <s>""", """<s> <s> <s>"""]      ,       __lowerCamelCase							)

  self.assertTrue(np.array_equal(__lowerCamelCase      ,       decoded_processor_out.logit_score							)							)
  self.assertTrue(np.allclose([-2_0.0_5_4, -1_8.4_4_7]      ,       __lowerCamelCase      ,       atol=1e-3							)							)

  self.assertTrue(np.array_equal(__lowerCamelCase      ,       decoded_processor_out.lm_score							)							)
  self.assertTrue(np.allclose([-1_5.5_5_4, -1_3.9_4_7_4]      ,       __lowerCamelCase      ,       atol=1e-3							)							)
 def a					(      self   :	Optional[int]							)  ->    Optional[Any]:
  __lowerCAmelCase											=						self.get_feature_extractor()
  __lowerCAmelCase											=						self.get_tokenizer()
  __lowerCAmelCase											=						self.get_decoder()

  __lowerCAmelCase											=						WavaVecaProcessorWithLM(tokenizer=__lowerCamelCase      ,       feature_extractor=__lowerCamelCase      ,       decoder=__lowerCamelCase							)

  __lowerCAmelCase											=						self._get_dummy_logits()

  __lowerCAmelCase											=						2.0
  __lowerCAmelCase											=						5.0
  __lowerCAmelCase											=						-2_0.0
  __lowerCAmelCase											=						True

  __lowerCAmelCase											=						processor.batch_decode(
      __lowerCamelCase      ,       alpha=__lowerCamelCase      ,       beta=__lowerCamelCase      ,       unk_score_offset=__lowerCamelCase      ,       lm_score_boundary=__lowerCamelCase      ,       )
  __lowerCAmelCase											=						decoded_processor_out.text

  __lowerCAmelCase											=						list(__lowerCamelCase							)
  decoder.reset_params(
      alpha=__lowerCamelCase      ,       beta=__lowerCamelCase      ,       unk_score_offset=__lowerCamelCase      ,       lm_score_boundary=__lowerCamelCase      ,       )

  with get_context("""fork"""							).Pool() as pool:
   __lowerCAmelCase											=						decoder.decode_beams_batch(
       __lowerCamelCase      ,       __lowerCamelCase      ,       )

  __lowerCAmelCase											=						[d[0][0] for d in decoded_decoder_out]

  self.assertListEqual(__lowerCamelCase      ,       __lowerCamelCase							)
  self.assertListEqual(["""<s> </s> <s> </s> </s>""", """</s> </s> <s> </s> </s>"""]      ,       __lowerCamelCase							)
  __lowerCAmelCase											=						processor.decoder.model_container[processor.decoder._model_key]
  self.assertEqual(lm_model.alpha      ,       2.0							)
  self.assertEqual(lm_model.beta      ,       5.0							)
  self.assertEqual(lm_model.unk_score_offset      ,       -2_0.0							)
  self.assertEqual(lm_model.score_boundary      ,       __lowerCamelCase							)
 def a					(      self   :	Tuple							)  ->    str:
  __lowerCAmelCase											=						WavaVecaProcessorWithLM.from_pretrained("""hf-internal-testing/processor_with_lm"""							)

  __lowerCAmelCase											=						processor.decoder.model_container[processor.decoder._model_key]
  __lowerCAmelCase											=						Path(language_model._kenlm_model.path.decode("""utf-8"""							)							).parent.parent.absolute()

  __lowerCAmelCase											=						os.listdir(__lowerCamelCase							)
  __lowerCAmelCase											=						["""alphabet.json""", """language_model"""]

  downloaded_decoder_files.sort()
  expected_decoder_files.sort()

  # test that only decoder relevant files from
  # https://huggingface.co/hf-internal-testing/processor_with_lm/tree/main
  # are downloaded and none of the rest (e.g. README.md, ...)
  self.assertListEqual(__lowerCamelCase      ,       __lowerCamelCase							)
 def a					(      self   :	str							)  ->    List[str]:
  __lowerCAmelCase											=						snapshot_download("""hf-internal-testing/processor_with_lm"""							)

  __lowerCAmelCase											=						WavaVecaProcessorWithLM.from_pretrained(__lowerCamelCase							)

  __lowerCAmelCase											=						processor.decoder.model_container[processor.decoder._model_key]
  __lowerCAmelCase											=						Path(language_model._kenlm_model.path.decode("""utf-8"""							)							).parent.parent.absolute()

  __lowerCAmelCase											=						os.listdir(__lowerCamelCase							)
  __lowerCAmelCase											=						os.listdir(__lowerCamelCase							)

  local_decoder_files.sort()
  expected_decoder_files.sort()

  # test that both decoder form hub and local files in cache are the same
  self.assertListEqual(__lowerCamelCase      ,       __lowerCamelCase							)
 def a					(      self   :	int							)  ->    Dict:
  __lowerCAmelCase											=						WavaVecaProcessorWithLM.from_pretrained("""hf-internal-testing/processor_with_lm"""							)
  __lowerCAmelCase											=						AutoProcessor.from_pretrained("""hf-internal-testing/processor_with_lm"""							)

  __lowerCAmelCase											=						floats_list((3, 10_00)							)

  __lowerCAmelCase											=						processor_wavaveca(__lowerCamelCase      ,       return_tensors="""np"""							)
  __lowerCAmelCase											=						processor_auto(__lowerCamelCase      ,       return_tensors="""np"""							)

  for key in input_wavaveca.keys():
   self.assertAlmostEqual(input_wavaveca[key].sum()      ,       input_auto[key].sum()      ,       delta=1e-2							)

  __lowerCAmelCase											=						self._get_dummy_logits()

  __lowerCAmelCase											=						processor_wavaveca.batch_decode(__lowerCamelCase							)
  __lowerCAmelCase											=						processor_auto.batch_decode(__lowerCamelCase							)

  self.assertListEqual(decoded_wavaveca.text      ,       decoded_auto.text							)
 def a					(      self   :	List[str]							)  ->    Union[str, Any]:
  __lowerCAmelCase											=						self.get_feature_extractor()
  __lowerCAmelCase											=						self.get_tokenizer()
  __lowerCAmelCase											=						self.get_decoder()

  __lowerCAmelCase											=						WavaVecaProcessorWithLM(tokenizer=__lowerCamelCase      ,       feature_extractor=__lowerCamelCase      ,       decoder=__lowerCamelCase							)

  self.assertListEqual(
      processor.model_input_names      ,       feature_extractor.model_input_names      ,       msg="""`processor` and `feature_extractor` model input names do not match"""      ,       )
 @staticmethod
 def a					(      SCREAMING_SNAKE_CASE__   :	Any      ,       SCREAMING_SNAKE_CASE__   :	int							)  ->    int:
  __lowerCAmelCase											=						[d[key] for d in offsets]
  return retrieved_list
 def a					(      self   :	List[Any]							)  ->    int:
  __lowerCAmelCase											=						WavaVecaProcessorWithLM.from_pretrained("""hf-internal-testing/processor_with_lm"""							)
  __lowerCAmelCase											=						self._get_dummy_logits()[0]

  __lowerCAmelCase											=						processor.decode(__lowerCamelCase      ,       output_word_offsets=__lowerCamelCase							)
  # check Wav2Vec2CTCTokenizerOutput keys for word
  self.assertEqual(len(outputs.keys()							)      ,       4							)
  self.assertTrue("""text""" in outputs							)
  self.assertTrue("""word_offsets""" in outputs							)
  self.assertTrue(isinstance(__lowerCamelCase      ,       __lowerCamelCase							)							)

  self.assertEqual(""" """.join(self.get_from_offsets(outputs["""word_offsets"""]      ,       """word"""							)							)      ,       outputs.text							)
  self.assertListEqual(self.get_from_offsets(outputs["""word_offsets"""]      ,       """word"""							)      ,       ["""<s>""", """<s>""", """</s>"""]							)
  self.assertListEqual(self.get_from_offsets(outputs["""word_offsets"""]      ,       """start_offset"""							)      ,       [0, 2, 4]							)
  self.assertListEqual(self.get_from_offsets(outputs["""word_offsets"""]      ,       """end_offset"""							)      ,       [1, 3, 5]							)
 def a					(      self   :	List[Any]							)  ->    Any:
  __lowerCAmelCase											=						WavaVecaProcessorWithLM.from_pretrained("""hf-internal-testing/processor_with_lm"""							)
  __lowerCAmelCase											=						self._get_dummy_logits()

  __lowerCAmelCase											=						processor.batch_decode(__lowerCamelCase      ,       output_word_offsets=__lowerCamelCase							)

  # check Wav2Vec2CTCTokenizerOutput keys for word
  self.assertEqual(len(outputs.keys()							)      ,       4							)
  self.assertTrue("""text""" in outputs							)
  self.assertTrue("""word_offsets""" in outputs							)
  self.assertTrue(isinstance(__lowerCamelCase      ,       __lowerCamelCase							)							)

  self.assertListEqual(
      [""" """.join(self.get_from_offsets(__lowerCamelCase      ,       """word"""							)							) for o in outputs["""word_offsets"""]]      ,       outputs.text							)
  self.assertListEqual(self.get_from_offsets(outputs["""word_offsets"""][0]      ,       """word"""							)      ,       ["""<s>""", """<s>""", """</s>"""]							)
  self.assertListEqual(self.get_from_offsets(outputs["""word_offsets"""][0]      ,       """start_offset"""							)      ,       [0, 2, 4]							)
  self.assertListEqual(self.get_from_offsets(outputs["""word_offsets"""][0]      ,       """end_offset"""							)      ,       [1, 3, 5]							)





 @slow
 @require_torch
 @require_torchaudio
 def a					(      self   :	List[Any]							)  ->    List[Any]:
  import torch

  __lowerCAmelCase											=						load_dataset("""common_voice"""      ,       """en"""      ,       split="""train"""      ,       streaming=__lowerCamelCase							)
  __lowerCAmelCase											=						ds.cast_column("""audio"""      ,       datasets.Audio(sampling_rate=1_60_00							)							)
  __lowerCAmelCase											=						iter(__lowerCamelCase							)
  __lowerCAmelCase											=						next(__lowerCamelCase							)

  __lowerCAmelCase											=						AutoProcessor.from_pretrained("""patrickvonplaten/wav2vec2-base-100h-with-lm"""							)
  __lowerCAmelCase											=						WavaVecaForCTC.from_pretrained("""patrickvonplaten/wav2vec2-base-100h-with-lm"""							)

  # compare to filename `common_voice_en_100038.mp3` of dataset viewer on https://huggingface.co/datasets/common_voice/viewer/en/train
  __lowerCAmelCase											=						processor(sample["""audio"""]["""array"""]      ,       return_tensors="""pt"""							).input_values

  with torch.no_grad():
   __lowerCAmelCase											=						model(__lowerCamelCase							).logits.cpu().numpy()

  __lowerCAmelCase											=						processor.decode(logits[0]      ,       output_word_offsets=__lowerCamelCase							)

  __lowerCAmelCase											=						model.config.inputs_to_logits_ratio / processor.feature_extractor.sampling_rate
  __lowerCAmelCase											=						[
      {
          """start_time""": d["""start_offset"""] * time_offset,
          """end_time""": d["""end_offset"""] * time_offset,
          """word""": d["""word"""],
      }
      for d in output["""word_offsets"""]
  ]

  __lowerCAmelCase											=						"""WHY DOES MILISANDRA LOOK LIKE SHE WANTS TO CONSUME JOHN SNOW ON THE RIVER AT THE WALL"""

  # output words
  self.assertEqual(""" """.join(self.get_from_offsets(__lowerCamelCase      ,       """word"""							)							)      ,       __lowerCamelCase							)
  self.assertEqual(""" """.join(self.get_from_offsets(__lowerCamelCase      ,       """word"""							)							)      ,       output.text							)

  # output times
  __lowerCAmelCase											=						torch.tensor(self.get_from_offsets(__lowerCamelCase      ,       """start_time"""							)							)
  __lowerCAmelCase											=						torch.tensor(self.get_from_offsets(__lowerCamelCase      ,       """end_time"""							)							)

  # fmt: off
  __lowerCAmelCase											=						torch.tensor([1.4_1_9_9, 1.6_5_9_9, 2.2_5_9_9, 3.0, 3.2_4, 3.5_9_9_9, 3.7_9_9_9, 4.0_9_9_9, 4.2_6, 4.9_4, 5.2_8, 5.6_5_9_9, 5.7_8, 5.9_4, 6.3_2, 6.5_3_9_9, 6.6_5_9_9]							)
  __lowerCAmelCase											=						torch.tensor([1.5_3_9_9, 1.8_9_9_9, 2.9, 3.1_6, 3.5_3_9_9, 3.7_2, 4.0_1_9_9, 4.1_7_9_9, 4.7_6, 5.1_5_9_9, 5.5_5_9_9, 5.6_9_9_9, 5.8_6, 6.1_9_9_9, 6.3_8, 6.6_1_9_9, 6.9_4]							)
  # fmt: on

  self.assertTrue(torch.allclose(__lowerCamelCase      ,       __lowerCamelCase      ,       atol=0.0_1							)							)
  self.assertTrue(torch.allclose(__lowerCamelCase      ,       __lowerCamelCase      ,       atol=0.0_1							)							)












def 			__magic_name__				( A		:					str   ):






			'''simple docstring'''







			a    =			""
			for ch in key:
						if ch == " " or ch not in key_no_dups and ch.isalpha():
									key_no_dups += ch
			return key_no_dups




def 			__magic_name__				( A		:					str   ):






			'''simple docstring'''







			a    =			[chr(i + 65   ) for i in range(26   )]
			# Remove duplicate characters from key
			a    =			remove_duplicates(key.upper()   )
			a    =			len(A   )
			# First fill cipher with key characters
			a    =			{alphabet[i]: char for i, char in enumerate(A   )}
			# Then map remaining characters in alphabet to
			# the alphabet from the beginning
			for i in range(len(A   ),  26   ):
						a    =			alphabet[i - offset]
						# Ensure we are not mapping letters to letters previously mapped
						while char in key:
									offset -= 1
									a    =			alphabet[i - offset]
						a    =			char
			return cipher_alphabet




def 			__magic_name__				( A		:					str,  A		:					dict[str, str]   ):






			'''simple docstring'''







			return "".join(cipher_map.get(A,  A   ) for ch in message.upper()   )




def 			__magic_name__				( A		:					str,  A		:					dict[str, str]   ):






			'''simple docstring'''







			a    =			{v: k for k, v in cipher_map.items()}
			return "".join(rev_cipher_map.get(A,  A   ) for ch in message.upper()   )




def 			__magic_name__				( ):






			'''simple docstring'''







			a    =			input("Enter message to encode or decode: "   ).strip()
			a    =			input("Enter keyword: "   ).strip()
			a    =			input("Encipher or decipher? E/D:"   ).strip()[0].lower()
			try:
						a    =			{"e": encipher, "d": decipher}[option]
			except KeyError:
						raise KeyError("invalid input option"   )
			a    =			create_cipher_map(A   )
			print(func(A,  A   )   )


if __name__ == "__main__":
		import doctest

		doctest.testmod()
		main()






