




from __future__ import annotations

import inspect
import unittest

from transformers import MobileViTConfig
from transformers.file_utils import is_tf_available, is_vision_available
from transformers.testing_utils import require_tf, slow

from ...test_configuration_common import ConfigTester
from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_tf_available():
       import numpy as np
       import tensorflow as tf

       from transformers import TFMobileViTForImageClassification, TFMobileViTForSemanticSegmentation, TFMobileViTModel
       from transformers.models.mobilevit.modeling_tf_mobilevit import TF_MOBILEVIT_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
       from PIL import Image

       from transformers import MobileViTImageProcessor




class 	UpperCamelCase__			(lowerCAmelCase__  ):

    '''simple docstring'''



    def 					_lowercase  (					self  )  ->   Optional[Any]:
           lowerCamelCase     :   Tuple    				=      self.config_class(**self.inputs_dict  )
           self.parent.assertTrue(hasattr(UpperCamelCase__  ,						"hidden_sizes"  )  )
           self.parent.assertTrue(hasattr(UpperCamelCase__  ,						"neck_hidden_sizes"  )  )
           self.parent.assertTrue(hasattr(UpperCamelCase__  ,						"num_attention_heads"  )  )




class 	UpperCamelCase__			:

    '''simple docstring'''



    def __init__(					self  ,						UpperCamelCase__  ,						UpperCamelCase__=13  ,						UpperCamelCase__=32  ,						UpperCamelCase__=2  ,						UpperCamelCase__=3  ,						UpperCamelCase__=640  ,						UpperCamelCase__=4  ,						UpperCamelCase__="silu"  ,						UpperCamelCase__=3  ,						UpperCamelCase__=32  ,						UpperCamelCase__=0.1  ,						UpperCamelCase__=0.1  ,						UpperCamelCase__=0.1  ,						UpperCamelCase__=0.02  ,						UpperCamelCase__=True  ,						UpperCamelCase__=True  ,						UpperCamelCase__=10  ,						UpperCamelCase__=None  ,						)  ->   Union[str, Any]:
           lowerCamelCase     :   Optional[int]    				=      parent
           lowerCamelCase     :   str    				=      batch_size
           lowerCamelCase     :   Dict    				=      image_size
           lowerCamelCase     :   List[Any]    				=      patch_size
           lowerCamelCase     :   Optional[Any]    				=      num_channels
           lowerCamelCase     :   int    				=      last_hidden_size
           lowerCamelCase     :   List[Any]    				=      num_attention_heads
           lowerCamelCase     :   List[str]    				=      hidden_act
           lowerCamelCase     :   Optional[int]    				=      conv_kernel_size
           lowerCamelCase     :   str    				=      output_stride
           lowerCamelCase     :   Union[str, Any]    				=      hidden_dropout_prob
           lowerCamelCase     :   str    				=      attention_probs_dropout_prob
           lowerCamelCase     :   Dict    				=      classifier_dropout_prob
           lowerCamelCase     :   List[Any]    				=      use_labels
           lowerCamelCase     :   Optional[int]    				=      is_training
           lowerCamelCase     :   List[Any]    				=      num_labels
           lowerCamelCase     :   Optional[Any]    				=      initializer_range
           lowerCamelCase     :   Tuple    				=      scope







    def 					_lowercase  (					self  )  ->   str:
           lowerCamelCase     :   Dict    				=      floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]  )

           lowerCamelCase     :   str    				=      None
           lowerCamelCase     :   Tuple    				=      None
           if self.use_labels:
                  lowerCamelCase     :   Optional[Any]    				=      ids_tensor([self.batch_size]  ,						self.num_labels  )
                  lowerCamelCase     :   str    				=      ids_tensor([self.batch_size, self.image_size, self.image_size]  ,						self.num_labels  )

           lowerCamelCase     :   str    				=      self.get_config()

           return config, pixel_values, labels, pixel_labels







    def 					_lowercase  (					self  )  ->   int:
           return MobileViTConfig(
               image_size=self.image_size  ,						patch_size=self.patch_size  ,						num_channels=self.num_channels  ,						num_attention_heads=self.num_attention_heads  ,						hidden_act=self.hidden_act  ,						conv_kernel_size=self.conv_kernel_size  ,						output_stride=self.output_stride  ,						hidden_dropout_prob=self.hidden_dropout_prob  ,						attention_probs_dropout_prob=self.attention_probs_dropout_prob  ,						classifier_dropout_prob=self.classifier_dropout_prob  ,						initializer_range=self.initializer_range  ,						)







    def 					_lowercase  (					self  ,						UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__  )  ->   Optional[int]:
           lowerCamelCase     :   Optional[int]    				=      TFMobileViTModel(config=UpperCamelCase__  )
           lowerCamelCase     :   Optional[Any]    				=      model(UpperCamelCase__  ,						training=UpperCamelCase__  )
           lowerCamelCase     :   Tuple    				=      self.image_size // self.output_stride
           self.parent.assertEqual(
               result.last_hidden_state.shape  ,						(self.batch_size, self.last_hidden_size, expected_height, expected_width)  )







    def 					_lowercase  (					self  ,						UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__  )  ->   Dict:
           lowerCamelCase     :   Union[str, Any]    				=      self.num_labels
           lowerCamelCase     :   Dict    				=      TFMobileViTForImageClassification(UpperCamelCase__  )
           lowerCamelCase     :   Optional[int]    				=      model(UpperCamelCase__  ,						labels=UpperCamelCase__  ,						training=UpperCamelCase__  )
           self.parent.assertEqual(result.logits.shape  ,						(self.batch_size, self.num_labels)  )







    def 					_lowercase  (					self  ,						UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__  )  ->   Optional[Any]:
           lowerCamelCase     :   int    				=      self.num_labels
           lowerCamelCase     :   int    				=      TFMobileViTForSemanticSegmentation(UpperCamelCase__  )
           lowerCamelCase     :   List[Any]    				=      self.image_size // self.output_stride

           lowerCamelCase     :   int    				=      model(UpperCamelCase__  ,						training=UpperCamelCase__  )
           self.parent.assertEqual(
               result.logits.shape  ,						(self.batch_size, self.num_labels, expected_height, expected_width)  )

           lowerCamelCase     :   Union[str, Any]    				=      model(UpperCamelCase__  ,						labels=UpperCamelCase__  ,						training=UpperCamelCase__  )
           self.parent.assertEqual(
               result.logits.shape  ,						(self.batch_size, self.num_labels, expected_height, expected_width)  )







    def 					_lowercase  (					self  )  ->   Dict:
           lowerCamelCase     :   Tuple    				=      self.prepare_config_and_inputs()
           lowerCamelCase				,   lowerCamelCase				,   lowerCamelCase				,   lowerCamelCase     :   Any    				=      config_and_inputs
           lowerCamelCase     :   Optional[int]    				=      {"pixel_values": pixel_values}
           return config, inputs_dict




@require_tf
class 	UpperCamelCase__			(lowerCAmelCase__					,       lowerCAmelCase__					,       unittest.TestCase  ):

    '''simple docstring'''



    lowerCamelCase_   :			Tuple			  =   (
        (TFMobileViTModel, TFMobileViTForImageClassification, TFMobileViTForSemanticSegmentation)
        if is_tf_available()
        else ()
    )
    lowerCamelCase_   :			Any			  =   (
        {"""feature-extraction""": TFMobileViTModel, """image-classification""": TFMobileViTForImageClassification}
        if is_tf_available()
        else {}
    )

    lowerCamelCase_   :			int			  =   False
    lowerCamelCase_   :			List[Any]			  =   False
    lowerCamelCase_   :			List[str]			  =   False
    lowerCamelCase_   :			int			  =   False
    lowerCamelCase_   :			str			  =   False







    def 					_lowercase  (					self  )  ->   Dict:
           lowerCamelCase     :   Union[str, Any]    				=      TFMobileViTModelTester(self  )
           lowerCamelCase     :   Optional[Any]    				=      TFMobileViTConfigTester(self  ,						config_class=UpperCamelCase__  ,						has_text_modality=UpperCamelCase__  )







    def 					_lowercase  (					self  )  ->   int:
           self.config_tester.run_common_tests()







    @unittest.skip(reason="MobileViT does not use inputs_embeds"  )
    def 					_lowercase  (					self  )  ->   Union[str, Any]:
           pass







    @unittest.skip(reason="MobileViT does not support input and output embeddings"  )
    def 					_lowercase  (					self  )  ->   Any:
           pass







    @unittest.skip(reason="MobileViT does not output attentions"  )
    def 					_lowercase  (					self  )  ->   List[str]:
           pass







    def 					_lowercase  (					self  )  ->   Union[str, Any]:
           lowerCamelCase				,   lowerCamelCase     :   Optional[int]    				=      self.model_tester.prepare_config_and_inputs_for_common()

           for model_class in self.all_model_classes:
                  lowerCamelCase     :   List[Any]    				=      model_class(UpperCamelCase__  )
                  lowerCamelCase     :   str    				=      inspect.signature(model.call  )
                  # signature.parameters is an OrderedDict => so arg_names order is deterministic
                  lowerCamelCase     :   int    				=      [*signature.parameters.keys()]

                  lowerCamelCase     :   List[str]    				=      ["pixel_values"]
                  self.assertListEqual(arg_names[:1]  ,						UpperCamelCase__  )







    def 					_lowercase  (					self  )  ->   List[Any]:
           lowerCamelCase     :   Dict    				=      self.model_tester.prepare_config_and_inputs()
           self.model_tester.create_and_check_model(*UpperCamelCase__  )







    def 					_lowercase  (					self  )  ->   Optional[int]:
           def check_hidden_states_output(UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__  ):
                  lowerCamelCase     :   Union[str, Any]    				=      model_class(UpperCamelCase__  )

                  lowerCamelCase     :   Any    				=      model(**self._prepare_for_class(UpperCamelCase__  ,						UpperCamelCase__  )  )

                  lowerCamelCase     :   Any    				=      outputs.hidden_states

                  lowerCamelCase     :   Union[str, Any]    				=      5
                  self.assertEqual(len(UpperCamelCase__  )  ,						UpperCamelCase__  )

                  # MobileViT's feature maps are of shape (batch_size, num_channels, height, width)
                  # with the width and height being successively divided by 2.
                  lowerCamelCase     :   Any    				=      2
                  for i in range(len(UpperCamelCase__  )  ):
                         self.assertListEqual(
                             list(hidden_states[i].shape[-2:]  )  ,						[self.model_tester.image_size // divisor, self.model_tester.image_size // divisor]  ,						)
                         divisor *= 2

                  self.assertEqual(self.model_tester.output_stride  ,						divisor // 2  )

           lowerCamelCase				,   lowerCamelCase     :   Optional[Any]    				=      self.model_tester.prepare_config_and_inputs_for_common()

           for model_class in self.all_model_classes:
                  lowerCamelCase     :   List[Any]    				=      True
                  check_hidden_states_output(UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__  )

                  # check that output_hidden_states also work using config
                  del inputs_dict["output_hidden_states"]
                  lowerCamelCase     :   Dict    				=      True

                  check_hidden_states_output(UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__  )







    def 					_lowercase  (					self  )  ->   Optional[int]:
           lowerCamelCase     :   int    				=      self.model_tester.prepare_config_and_inputs()
           self.model_tester.create_and_check_for_image_classification(*UpperCamelCase__  )







    def 					_lowercase  (					self  )  ->   str:
           lowerCamelCase     :   Any    				=      self.model_tester.prepare_config_and_inputs()
           self.model_tester.create_and_check_for_semantic_segmentation(*UpperCamelCase__  )







    @unittest.skipIf(
        not is_tf_available() or len(tf.config.list_physical_devices("GPU"  )  ) == 0  ,						reason="TF does not support backprop for grouped convolutions on CPU."  ,						)
    def 					_lowercase  (					self  )  ->   Any:
           super().test_dataset_conversion()







    def 					_lowercase  (					self  ,						UpperCamelCase__  ,						UpperCamelCase__  ,						UpperCamelCase__=2e-1  ,						UpperCamelCase__=2e-1  )  ->   List[Any]:
           self.assertTrue(np.allclose(UpperCamelCase__  ,						UpperCamelCase__  ,						atol=UpperCamelCase__  ,						rtol=UpperCamelCase__  )  )







    @unittest.skipIf(
        not is_tf_available() or len(tf.config.list_physical_devices("GPU"  )  ) == 0  ,						reason="TF does not support backprop for grouped convolutions on CPU."  ,						)
    @slow
    def 					_lowercase  (					self  )  ->   int:
           lowerCamelCase				,   lowerCamelCase     :   Tuple    				=      self.model_tester.prepare_config_and_inputs_for_common()

           for model_class in self.all_model_classes:
                  # Since `TFMobileViTModel` cannot operate with the default `fit()` method.
                  if model_class.__name__ != "TFMobileViTModel":
                         lowerCamelCase     :   Tuple    				=      model_class(UpperCamelCase__  )
                         if getattr(UpperCamelCase__  ,						"hf_compute_loss"  ,						UpperCamelCase__  ):
                                super().test_keras_fit()







    def 					_lowercase  (					self  )  ->   List[str]:
           lowerCamelCase				,   lowerCamelCase     :   Any    				=      self.model_tester.prepare_config_and_inputs_for_common()
           for model_class in self.all_model_classes:
                  # set an ignore index to correctly test the masked loss used in
                  # `TFMobileViTForSemanticSegmentation`.
                  if model_class.__name__ != "TFMobileViTForSemanticSegmentation":
                         lowerCamelCase     :   List[str]    				=      5

                  lowerCamelCase     :   int    				=      model_class(UpperCamelCase__  )
                  if getattr(UpperCamelCase__  ,						"hf_compute_loss"  ,						UpperCamelCase__  ):
                         # The number of elements in the loss should be the same as the number of elements in the label
                         lowerCamelCase     :   List[Any]    				=      self._prepare_for_class(inputs_dict.copy()  ,						UpperCamelCase__  ,						return_labels=UpperCamelCase__  )
                         lowerCamelCase     :   List[Any]    				=      prepared_for_class[
                             sorted(prepared_for_class.keys() - inputs_dict.keys()  ,						reverse=UpperCamelCase__  )[0]
                         ]
                         lowerCamelCase     :   Tuple    				=      added_label.shape.as_list()[:1]

                         # Test that model correctly compute the loss with kwargs
                         lowerCamelCase     :   int    				=      self._prepare_for_class(inputs_dict.copy()  ,						UpperCamelCase__  ,						return_labels=UpperCamelCase__  )
                         lowerCamelCase     :   Dict    				=      {"input_ids", "pixel_values", "input_features"}
                         lowerCamelCase     :   Union[str, Any]    				=      possible_input_names.intersection(set(UpperCamelCase__  )  ).pop()
                         lowerCamelCase     :   Tuple    				=      prepared_for_class.pop(UpperCamelCase__  )

                         lowerCamelCase     :   List[Any]    				=      model(UpperCamelCase__  ,						**UpperCamelCase__  )[0]
                         self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]  )

                         # Test that model correctly compute the loss when we mask some positions
                         lowerCamelCase     :   Any    				=      self._prepare_for_class(inputs_dict.copy()  ,						UpperCamelCase__  ,						return_labels=UpperCamelCase__  )
                         lowerCamelCase     :   int    				=      {"input_ids", "pixel_values", "input_features"}
                         lowerCamelCase     :   str    				=      possible_input_names.intersection(set(UpperCamelCase__  )  ).pop()
                         lowerCamelCase     :   Optional[int]    				=      prepared_for_class.pop(UpperCamelCase__  )
                         if "labels" in prepared_for_class:
                                lowerCamelCase     :   Optional[Any]    				=      prepared_for_class["labels"].numpy()
                                if len(labels.shape  ) > 1 and labels.shape[1] != 1:
                                       # labels[0] = -100
                                       lowerCamelCase     :   str    				=      tf.convert_to_tensor(UpperCamelCase__  )
                                       lowerCamelCase     :   str    				=      model(UpperCamelCase__  ,						**UpperCamelCase__  )[0]
                                       self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]  )
                                       self.assertTrue(not np.any(np.isnan(loss.numpy()  )  )  )

                # Test that model correctly compute the loss with a dict
                         lowerCamelCase     :   Optional[int]    				=      self._prepare_for_class(inputs_dict.copy()  ,						UpperCamelCase__  ,						return_labels=UpperCamelCase__  )
                         lowerCamelCase     :   Tuple    				=      model(UpperCamelCase__  )[0]
                         self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]  )

                         # Test that model correctly compute the loss with a tuple
                         lowerCamelCase     :   Optional[Any]    				=      self._prepare_for_class(inputs_dict.copy()  ,						UpperCamelCase__  ,						return_labels=UpperCamelCase__  )

                         # Get keys that were added with the _prepare_for_class function
                         lowerCamelCase     :   Dict    				=      prepared_for_class.keys() - inputs_dict.keys()
                         lowerCamelCase     :   int    				=      inspect.signature(model.call  ).parameters
                         lowerCamelCase     :   Optional[int]    				=      list(signature.keys()  )

                         # Create a dictionary holding the location of the tensors in the tuple
                         lowerCamelCase     :   List[Any]    				=      {0: input_name}
                         for label_key in label_keys:
                                lowerCamelCase     :   int    				=      signature_names.index(UpperCamelCase__  )
                                lowerCamelCase     :   Tuple    				=      label_key
                         lowerCamelCase     :   Dict    				=      sorted(tuple_index_mapping.items()  )
                         # Initialize a list with their default values, update the values and convert to a tuple
                         lowerCamelCase     :   List[str]    				=      []

                         for name in signature_names:
                                if name != "kwargs":
                                       list_input.append(signature[name].default  )

                         for index, value in sorted_tuple_index_mapping:
                                lowerCamelCase     :   Dict    				=      prepared_for_class[value]

                         lowerCamelCase     :   Optional[Any]    				=      tuple(UpperCamelCase__  )

                         # Send to model
                         lowerCamelCase     :   int    				=      model(tuple_input[:-1]  )[0]

                         self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1]  )







    @slow
    def 					_lowercase  (					self  )  ->   Union[str, Any]:
           for model_name in TF_MOBILEVIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
                  lowerCamelCase     :   int    				=      TFMobileViTModel.from_pretrained(UpperCamelCase__  )
                  self.assertIsNotNone(UpperCamelCase__  )




def   A   (   )			->				Tuple:
       lowerCamelCase     :   int    				=      Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png"					)
       return image




@require_tf
class 	UpperCamelCase__			(unittest.TestCase  ):

    '''simple docstring'''



    @slow
    def 					_lowercase  (					self  )  ->   List[Any]:
           lowerCamelCase     :   Dict    				=      TFMobileViTForImageClassification.from_pretrained("apple/mobilevit-xx-small"  )

           lowerCamelCase     :   Optional[Any]    				=      MobileViTImageProcessor.from_pretrained("apple/mobilevit-xx-small"  )
           lowerCamelCase     :   Optional[Any]    				=      prepare_img()
           lowerCamelCase     :   List[Any]    				=      image_processor(images=UpperCamelCase__  ,						return_tensors="tf"  )

           # forward pass
           lowerCamelCase     :   Union[str, Any]    				=      model(**UpperCamelCase__  ,						training=UpperCamelCase__  )

           # verify the logits
           lowerCamelCase     :   List[str]    				=      tf.TensorShape((1, 1000)  )
           self.assertEqual(outputs.logits.shape  ,						UpperCamelCase__  )

           lowerCamelCase     :   List[Any]    				=      tf.constant([-1.9364, -1.2327, -0.4653]  )

           tf.debugging.assert_near(outputs.logits[0, :3]  ,						UpperCamelCase__  ,						atol=1e-4  ,						rtol=1e-04  )







    @slow
    def 					_lowercase  (					self  )  ->   Optional[Any]:
           # `from_pt` will be removed
           lowerCamelCase     :   int    				=      TFMobileViTForSemanticSegmentation.from_pretrained("apple/deeplabv3-mobilevit-xx-small"  )

           lowerCamelCase     :   Optional[Any]    				=      MobileViTImageProcessor.from_pretrained("apple/deeplabv3-mobilevit-xx-small"  )

           lowerCamelCase     :   Optional[int]    				=      prepare_img()
           lowerCamelCase     :   Optional[int]    				=      image_processor(images=UpperCamelCase__  ,						return_tensors="tf"  )

           # forward pass
           lowerCamelCase     :   List[Any]    				=      model(inputs.pixel_values  ,						training=UpperCamelCase__  )
           lowerCamelCase     :   int    				=      outputs.logits

           # verify the logits
           lowerCamelCase     :   int    				=      tf.TensorShape((1, 21, 32, 32)  )
           self.assertEqual(logits.shape  ,						UpperCamelCase__  )

           lowerCamelCase     :   List[Any]    				=      tf.constant(
               [
                   [[6.9713, 6.9786, 7.2422], [7.2893, 7.2825, 7.4446], [7.6580, 7.8797, 7.9420]],
                   [[-10.6869, -10.3250, -10.3471], [-10.4228, -9.9868, -9.7132], [-11.0405, -11.0221, -10.7318]],
                   [[-3.3089, -2.8539, -2.6740], [-3.2706, -2.5621, -2.5108], [-3.2534, -2.6615, -2.6651]],
               ]  )

           tf.debugging.assert_near(logits[0, :3, :3, :3]  ,						UpperCamelCase__  ,						rtol=1e-4  ,						atol=1e-4  )












from __future__ import annotations

def   A   (   _SCREAMING_SNAKE_CASE				,_SCREAMING_SNAKE_CASE					)			->				list:
       lowerCamelCase     :   int    				=      [None] * (len(_SCREAMING_SNAKE_CASE					) + len(_SCREAMING_SNAKE_CASE					))

       lowerCamelCase     :   Any    				=      0  # pointer to current index for left Half
       lowerCamelCase     :   int    				=      0  # pointer to current index for the right Half
       lowerCamelCase     :   Optional[int]    				=      0  # pointer to current index for the sorted array Half

       while pointera < len(_SCREAMING_SNAKE_CASE					) and pointera < len(_SCREAMING_SNAKE_CASE					):
              if left_half[pointera] < right_half[pointera]:
                     lowerCamelCase     :   Any    				=      left_half[pointera]
                     pointera += 1
                     index += 1
              else:
                     lowerCamelCase     :   Any    				=      right_half[pointera]
                     pointera += 1
                     index += 1
       while pointera < len(_SCREAMING_SNAKE_CASE					):
              lowerCamelCase     :   Optional[Any]    				=      left_half[pointera]
              pointera += 1
              index += 1

       while pointera < len(_SCREAMING_SNAKE_CASE					):
              lowerCamelCase     :   str    				=      right_half[pointera]
              pointera += 1
              index += 1

       return sorted_array

def   A   (   _SCREAMING_SNAKE_CASE					)			->				list:
       if len(_SCREAMING_SNAKE_CASE					) <= 1:
              return array
       # the actual formula to calculate the middle element = left + (right - left) // 2
       # this avoids integer overflow in case of large N
       lowerCamelCase     :   int    				=      0 + (len(_SCREAMING_SNAKE_CASE					) - 0) // 2

       # Split the array into halves till the array length becomes equal to One
       # merge the arrays of single length returned by mergeSort function and
       # pass them into the merge arrays function which merges the array
       lowerCamelCase     :   Optional[Any]    				=      array[:middle]
       lowerCamelCase     :   Optional[Any]    				=      array[middle:]

       return merge(merge_sort(_SCREAMING_SNAKE_CASE					)				,merge_sort(_SCREAMING_SNAKE_CASE					)					)


if __name__ == "__main__":
       import doctest

       doctest.testmod()






