




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       UpperCAmelCase ( self      )						->							List[str]:
         snake_case :							Optional[int]           =			"""| <pad> <unk> <s> </s> a b c d e f g h i j k""".split()
         snake_case :							List[Any]           =			dict(zip(snake_case_							, range(len(snake_case_      )      )      )      )

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

         snake_case :							Optional[int]           =			tempfile.mkdtemp()
         snake_case :							Any           =			os.path.join(self.tmpdirname							, VOCAB_FILES_NAMES["""vocab_file"""]      )
         snake_case :							Union[str, Any]           =			os.path.join(self.tmpdirname							, snake_case_      )
         with open(self.vocab_file							, """w"""							, encoding="""utf-8"""      ) as fp:
            fp.write(json.dumps(snake_case_      ) + """\n"""      )

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

         # load decoder from hub
         snake_case :							Optional[int]           =			"""hf-internal-testing/ngram-beam-search-decoder"""

      def       UpperCAmelCase ( self							, **A      )						->							int:
         snake_case :							Dict           =			self.add_kwargs_tokens_map.copy()
         kwargs.update(snake_case_      )
         return WavaVecaCTCTokenizer.from_pretrained(self.tmpdirname							, **snake_case_      )

      def       UpperCAmelCase ( self							, **A      )						->							str:
         return WavaVecaFeatureExtractor.from_pretrained(self.tmpdirname							, **snake_case_      )

      def       UpperCAmelCase ( self							, **A      )						->							List[str]:
         return BeamSearchDecoderCTC.load_from_hf_hub(self.decoder_name							, **snake_case_      )

      def       UpperCAmelCase ( self      )						->							Optional[Any]:
         shutil.rmtree(self.tmpdirname      )

      def       UpperCAmelCase ( self      )						->							Tuple:
         snake_case :							str           =			self.get_tokenizer()
         snake_case :							Union[str, Any]           =			self.get_feature_extractor()
         snake_case :							Tuple           =			self.get_decoder()

         snake_case :							List[Any]           =			WavaVecaProcessorWithLM(tokenizer=snake_case_							, feature_extractor=snake_case_							, decoder=snake_case_      )

         processor.save_pretrained(self.tmpdirname      )
         snake_case :							Optional[Any]           =			WavaVecaProcessorWithLM.from_pretrained(self.tmpdirname      )

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

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

         # 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							, snake_case_      )

      def       UpperCAmelCase ( self      )						->							Optional[Any]:
         snake_case :							List[Any]           =			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
         snake_case :							int           =			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       UpperCAmelCase ( self      )						->							Any:
         snake_case :							Dict           =			self.get_tokenizer()
         # add token to trigger raise
         tokenizer.add_tokens(["""xx"""]      )
         with self.assertRaisesRegex(snake_case_							, """include"""      ):
            WavaVecaProcessorWithLM(
                tokenizer=snake_case_							, feature_extractor=self.get_feature_extractor()							, decoder=self.get_decoder()      )

      def       UpperCAmelCase ( self      )						->							Any:
         snake_case :							Union[str, Any]           =			self.get_feature_extractor()
         snake_case :							Any           =			self.get_tokenizer()
         snake_case :							List[str]           =			self.get_decoder()

         snake_case :							int           =			WavaVecaProcessorWithLM(tokenizer=snake_case_							, feature_extractor=snake_case_							, decoder=snake_case_      )

         snake_case :							List[str]           =			floats_list((3, 1_0_0_0)      )

         snake_case :							Any           =			feature_extractor(snake_case_							, return_tensors="""np"""      )
         snake_case :							Union[str, Any]           =			processor(snake_case_							, 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       UpperCAmelCase ( self      )						->							Union[str, Any]:
         snake_case :							Optional[Any]           =			self.get_feature_extractor()
         snake_case :							Union[str, Any]           =			self.get_tokenizer()
         snake_case :							Dict           =			self.get_decoder()

         snake_case :							Optional[Any]           =			WavaVecaProcessorWithLM(tokenizer=snake_case_							, feature_extractor=snake_case_							, decoder=snake_case_      )

         snake_case :							Dict           =			"""This is a test string"""

         snake_case :							Dict           =			processor(text=snake_case_      )

         snake_case :							Any           =			tokenizer(snake_case_      )

         for key in encoded_tok.keys():
            self.assertListEqual(encoded_tok[key]							, encoded_processor[key]      )

      def       UpperCAmelCase ( self							, A=(2, 1_0, 1_6)							, A=7_7      )						->							int:
         np.random.seed(snake_case_      )
         return np.random.rand(*snake_case_      )

      def       UpperCAmelCase ( self      )						->							Optional[int]:
         snake_case :							List[str]           =			self.get_feature_extractor()
         snake_case :							Optional[Any]           =			self.get_tokenizer()
         snake_case :							Optional[Any]           =			self.get_decoder()

         snake_case :							Dict           =			WavaVecaProcessorWithLM(tokenizer=snake_case_							, feature_extractor=snake_case_							, decoder=snake_case_      )

         snake_case :							Dict           =			self._get_dummy_logits(shape=(1_0, 1_6)							, seed=1_3      )

         snake_case :							Tuple           =			processor.decode(snake_case_      )

         snake_case :							Optional[Any]           =			decoder.decode_beams(snake_case_      )[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       UpperCAmelCase ( self							, A      )						->							str:
         snake_case :							List[str]           =			self.get_feature_extractor()
         snake_case :							str           =			self.get_tokenizer()
         snake_case :							Optional[int]           =			self.get_decoder()

         snake_case :							List[str]           =			WavaVecaProcessorWithLM(tokenizer=snake_case_							, feature_extractor=snake_case_							, decoder=snake_case_      )

         snake_case :							Union[str, Any]           =			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:
            snake_case :							Dict           =			processor.batch_decode(snake_case_      )
         else:
            with get_context(snake_case_      ).Pool() as pool:
               snake_case :							str           =			processor.batch_decode(snake_case_							, snake_case_      )

         snake_case :							str           =			list(snake_case_      )

         with get_context("""fork"""      ).Pool() as p:
            snake_case :							Optional[Any]           =			decoder.decode_beams_batch(snake_case_							, snake_case_      )

         snake_case      ,   snake_case      ,   snake_case :							Dict           =			[], [], []
         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(snake_case_							, decoded_processor.text      )
         self.assertListEqual(["""<s> <s> </s>""", """<s> <s> <s>"""]							, decoded_processor.text      )
         self.assertListEqual(snake_case_							, decoded_processor.logit_score      )
         self.assertListEqual(snake_case_							, decoded_processor.lm_score      )

      def       UpperCAmelCase ( self      )						->							Dict:
         snake_case :							List[Any]           =			self.get_feature_extractor()
         snake_case :							Any           =			self.get_tokenizer()
         snake_case :							int           =			self.get_decoder()

         snake_case :							Union[str, Any]           =			WavaVecaProcessorWithLM(tokenizer=snake_case_							, feature_extractor=snake_case_							, decoder=snake_case_      )

         snake_case :							Optional[Any]           =			self._get_dummy_logits()

         snake_case :							int           =			1_5
         snake_case :							Any           =			-2_0.0
         snake_case :							Any           =			-4.0

         snake_case :							List[Any]           =			processor.batch_decode(
             snake_case_							, beam_width=snake_case_							, beam_prune_logp=snake_case_							, token_min_logp=snake_case_							, )
         snake_case :							Dict           =			decoded_processor_out.text

         snake_case :							Optional[Any]           =			list(snake_case_      )

         with get_context("""fork"""      ).Pool() as pool:
            snake_case :							Dict           =			decoder.decode_beams_batch(
                snake_case_							, snake_case_							, beam_width=snake_case_							, beam_prune_logp=snake_case_							, token_min_logp=snake_case_							, )

         snake_case :							Optional[int]           =			[d[0][0] for d in decoded_decoder_out]
         snake_case :							Any           =			[d[0][2] for d in decoded_decoder_out]
         snake_case :							Optional[int]           =			[d[0][3] for d in decoded_decoder_out]

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

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

         self.assertTrue(np.array_equal(snake_case_							, decoded_processor_out.lm_score      )      )
         self.assertTrue(np.allclose([-1_5.5_5_4, -1_3.9_4_7_4]							, snake_case_							, atol=1e-3      )      )

      def       UpperCAmelCase ( self      )						->							Any:
         snake_case :							List[str]           =			self.get_feature_extractor()
         snake_case :							Optional[Any]           =			self.get_tokenizer()
         snake_case :							Optional[int]           =			self.get_decoder()

         snake_case :							List[str]           =			WavaVecaProcessorWithLM(tokenizer=snake_case_							, feature_extractor=snake_case_							, decoder=snake_case_      )

         snake_case :							Any           =			self._get_dummy_logits()

         snake_case :							int           =			2.0
         snake_case :							Dict           =			5.0
         snake_case :							Union[str, Any]           =			-2_0.0
         snake_case :							List[str]           =			True

         snake_case :							Optional[int]           =			processor.batch_decode(
             snake_case_							, alpha=snake_case_							, beta=snake_case_							, unk_score_offset=snake_case_							, lm_score_boundary=snake_case_							, )
         snake_case :							int           =			decoded_processor_out.text

         snake_case :							List[str]           =			list(snake_case_      )
         decoder.reset_params(
             alpha=snake_case_							, beta=snake_case_							, unk_score_offset=snake_case_							, lm_score_boundary=snake_case_							, )

         with get_context("""fork"""      ).Pool() as pool:
            snake_case :							Optional[Any]           =			decoder.decode_beams_batch(
                snake_case_							, snake_case_							, )

         snake_case :							List[Any]           =			[d[0][0] for d in decoded_decoder_out]

         self.assertListEqual(snake_case_							, snake_case_      )
         self.assertListEqual(["""<s> </s> <s> </s> </s>""", """</s> </s> <s> </s> </s>"""]							, snake_case_      )
         snake_case :							Dict           =			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							, snake_case_      )

      def       UpperCAmelCase ( self      )						->							List[str]:
         snake_case :							Dict           =			WavaVecaProcessorWithLM.from_pretrained("""hf-internal-testing/processor_with_lm"""      )

         snake_case :							List[str]           =			processor.decoder.model_container[processor.decoder._model_key]
         snake_case :							List[Any]           =			Path(language_model._kenlm_model.path.decode("""utf-8"""      )      ).parent.parent.absolute()

         snake_case :							List[Any]           =			os.listdir(snake_case_      )
         snake_case :							Union[str, Any]           =			["""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(snake_case_							, snake_case_      )

      def       UpperCAmelCase ( self      )						->							Any:
         snake_case :							Optional[int]           =			snapshot_download("""hf-internal-testing/processor_with_lm"""      )

         snake_case :							List[str]           =			WavaVecaProcessorWithLM.from_pretrained(snake_case_      )

         snake_case :							Optional[int]           =			processor.decoder.model_container[processor.decoder._model_key]
         snake_case :							Any           =			Path(language_model._kenlm_model.path.decode("""utf-8"""      )      ).parent.parent.absolute()

         snake_case :							List[Any]           =			os.listdir(snake_case_      )
         snake_case :							Union[str, Any]           =			os.listdir(snake_case_      )

         local_decoder_files.sort()
         expected_decoder_files.sort()

         # test that both decoder form hub and local files in cache are the same
         self.assertListEqual(snake_case_							, snake_case_      )

      def       UpperCAmelCase ( self      )						->							Optional[Any]:
         snake_case :							int           =			WavaVecaProcessorWithLM.from_pretrained("""hf-internal-testing/processor_with_lm"""      )
         snake_case :							str           =			AutoProcessor.from_pretrained("""hf-internal-testing/processor_with_lm"""      )

         snake_case :							int           =			floats_list((3, 1_0_0_0)      )

         snake_case :							Dict           =			processor_wavaveca(snake_case_							, return_tensors="""np"""      )
         snake_case :							int           =			processor_auto(snake_case_							, return_tensors="""np"""      )

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

         snake_case :							Optional[int]           =			self._get_dummy_logits()

         snake_case :							str           =			processor_wavaveca.batch_decode(snake_case_      )
         snake_case :							Union[str, Any]           =			processor_auto.batch_decode(snake_case_      )

         self.assertListEqual(decoded_wavaveca.text							, decoded_auto.text      )

      def       UpperCAmelCase ( self      )						->							List[str]:
         snake_case :							str           =			self.get_feature_extractor()
         snake_case :							Tuple           =			self.get_tokenizer()
         snake_case :							Dict           =			self.get_decoder()

         snake_case :							Optional[int]           =			WavaVecaProcessorWithLM(tokenizer=snake_case_							, feature_extractor=snake_case_							, decoder=snake_case_      )

         self.assertListEqual(
             processor.model_input_names							, feature_extractor.model_input_names							, msg="""`processor` and `feature_extractor` model input names do not match"""							, )

      @staticmethod
      def       UpperCAmelCase ( A							, A      )						->							int:
         snake_case :							Tuple           =			[d[key] for d in offsets]
         return retrieved_list

      def       UpperCAmelCase ( self      )						->							List[Any]:
         snake_case :							List[str]           =			WavaVecaProcessorWithLM.from_pretrained("""hf-internal-testing/processor_with_lm"""      )
         snake_case :							List[Any]           =			self._get_dummy_logits()[0]

         snake_case :							Dict           =			processor.decode(snake_case_							, output_word_offsets=snake_case_      )
         # 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(snake_case_							, snake_case_      )      )

         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       UpperCAmelCase ( self      )						->							Dict:
         snake_case :							Tuple           =			WavaVecaProcessorWithLM.from_pretrained("""hf-internal-testing/processor_with_lm"""      )
         snake_case :							str           =			self._get_dummy_logits()

         snake_case :							int           =			processor.batch_decode(snake_case_							, output_word_offsets=snake_case_      )

         # 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(snake_case_							, snake_case_      )      )

         self.assertListEqual(
             [""" """.join(self.get_from_offsets(snake_case_							, """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       UpperCAmelCase ( self      )						->							Any:
         import torch

         snake_case :							Tuple           =			load_dataset("""common_voice"""							, """en"""							, split="""train"""							, streaming=snake_case_      )
         snake_case :							List[Any]           =			ds.cast_column("""audio"""							, datasets.Audio(sampling_rate=1_6_0_0_0      )      )
         snake_case :							Tuple           =			iter(snake_case_      )
         snake_case :							Optional[int]           =			next(snake_case_      )

         snake_case :							List[str]           =			AutoProcessor.from_pretrained("""patrickvonplaten/wav2vec2-base-100h-with-lm"""      )
         snake_case :							List[Any]           =			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
         snake_case :							Dict           =			processor(sample["""audio"""]["""array"""]							, return_tensors="""pt"""      ).input_values

         with torch.no_grad():
            snake_case :							Union[str, Any]           =			model(snake_case_      ).logits.cpu().numpy()

         snake_case :							Optional[Any]           =			processor.decode(logits[0]							, output_word_offsets=snake_case_      )

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

         snake_case :							str           =			"""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(snake_case_							, """word"""      )      )							, snake_case_      )
         self.assertEqual(""" """.join(self.get_from_offsets(snake_case_							, """word"""      )      )							, output.text      )

         # output times
         snake_case :							List[str]           =			torch.tensor(self.get_from_offsets(snake_case_							, """start_time"""      )      )
         snake_case :							List[Any]           =			torch.tensor(self.get_from_offsets(snake_case_							, """end_time"""      )      )

         # fmt: off
         snake_case :							Any           =			torch.tensor([1.41_99, 1.65_99, 2.25_99, 3.0, 3.24, 3.59_99, 3.79_99, 4.09_99, 4.26, 4.94, 5.28, 5.65_99, 5.78, 5.94, 6.32, 6.53_99, 6.65_99]      )
         snake_case :							Optional[int]           =			torch.tensor([1.53_99, 1.89_99, 2.9, 3.16, 3.53_99, 3.72, 4.01_99, 4.17_99, 4.76, 5.15_99, 5.55_99, 5.69_99, 5.86, 6.19_99, 6.38, 6.61_99, 6.94]      )
         # fmt: on

         self.assertTrue(torch.allclose(snake_case_							, snake_case_							, atol=0.01      )      )
         self.assertTrue(torch.allclose(snake_case_							, snake_case_							, atol=0.01      )      )









a			:			Any												=					[sum(int(c, 10) ** 2 for c in i.__str__()) for i in range(100000)]


def 		lowercase_	(  _UpperCamelCase	):


			'''simple docstring'''







			__lowercase			       = 0
			while number:
						# Increased Speed Slightly by checking every 5 digits together.
						sum_of_digits_squared += DIGITS_SQUARED[number % 10_00_00]
						number //= 10_00_00

			return sum_of_digits_squared


# There are 2 Chains made,
# One ends with 89 with the chain member 58 being the one which when declared first,
# there will be the least number of iterations for all the members to be checked.

# The other one ends with 1 and has only one element 1.

# So 58 and 1 are chosen to be declared at the starting.

# Changed dictionary to an array to quicken the solution
a			:			list[bool | None]												=					[None] * 10000000
a			:			int												=					True
a			:			Any												=					False


def 		lowercase_	(  _UpperCamelCase	):


			'''simple docstring'''







			if CHAINS[number - 1] is not None:
						return CHAINS[number - 1]  # type: ignore

			__lowercase			       = chain(next_number(_UpperCamelCase	)	)
			__lowercase			       = number_chain

			while number < 10_00_00_00:
						__lowercase			       = number_chain
						number *= 10

			return number_chain


def 		lowercase_	(  _UpperCamelCase = 10_00_00_00	):


			'''simple docstring'''







			for i in range(1							,      _UpperCamelCase	):
						if CHAINS[i] is None:
									chain(i + 1	)

			return CHAINS[:number].count(_UpperCamelCase	)


if __name__ == "__main__":
	import doctest

	doctest.testmod()
	print(f'''{solution() = }''')


