


import inspect
import unittest

import numpy as np

from tests.test_modeling_common import floats_tensor
from transformers import DetrConfig, MaskFormerConfig, SwinConfig, is_torch_available, is_vision_available
from transformers.testing_utils import require_torch, require_torch_multi_gpu, require_vision, slow, torch_device
from transformers.utils import cached_property

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
 import torch

 from transformers import MaskFormerForInstanceSegmentation, MaskFormerModel

 if is_vision_available():
  from transformers import MaskFormerImageProcessor

if is_vision_available():
 from PIL import Image






class   __lowercase				:





      def __init__(		self						:					int					,       __lowerCamelCase						:					Tuple					,       __lowerCamelCase						:					List[str]=2					,       __lowerCamelCase						:					List[str]=True					,       __lowerCamelCase						:					Tuple=False					,       __lowerCamelCase						:					Optional[Any]=1_0					,       __lowerCamelCase						:					Tuple=3					,       __lowerCamelCase						:					Any=3_2 * 4					,       __lowerCamelCase						:					List[Any]=3_2 * 6					,       __lowerCamelCase						:					str=4					,       __lowerCamelCase						:					List[str]=3_2					,       )    ->   Any:






         """simple docstring"""







         UpperCAmelCase							=     parent
         UpperCAmelCase							=     batch_size
         UpperCAmelCase							=     is_training
         UpperCAmelCase							=     use_auxiliary_loss
         UpperCAmelCase							=     num_queries
         UpperCAmelCase							=     num_channels
         UpperCAmelCase							=     min_size
         UpperCAmelCase							=     max_size
         UpperCAmelCase							=     num_labels
         UpperCAmelCase							=     mask_feature_size





      def        _lowercase				(		self						:					int       )    ->   Any:






         """simple docstring"""







         UpperCAmelCase							=     floats_tensor([self.batch_size, self.num_channels, self.min_size, self.max_size]       ).to(
             snake_case_       )

         UpperCAmelCase							=     torch.ones([self.batch_size, self.min_size, self.max_size]					,       device=snake_case_       )

         UpperCAmelCase							=     (
             torch.rand([self.batch_size, self.num_labels, self.min_size, self.max_size]					,       device=snake_case_       ) > 0.5
         ).float()
         UpperCAmelCase							=     (torch.rand((self.batch_size, self.num_labels)					,       device=snake_case_       ) > 0.5).long()

         UpperCAmelCase							=     self.get_config()
         return config, pixel_values, pixel_mask, mask_labels, class_labels





      def        _lowercase				(		self						:					str       )    ->   Optional[int]:






         """simple docstring"""







         return MaskFormerConfig.from_backbone_and_decoder_configs(
             backbone_config=SwinConfig(
                 depths=[1, 1, 1, 1]					,       )					,       decoder_config=DetrConfig(
                 decoder_ffn_dim=1_2_8					,       num_queries=self.num_queries					,       decoder_attention_heads=2					,       d_model=self.mask_feature_size					,       )					,       mask_feature_size=self.mask_feature_size					,       fpn_feature_size=self.mask_feature_size					,       num_channels=self.num_channels					,       num_labels=self.num_labels					,       )





      def        _lowercase				(		self						:					Dict       )    ->   Dict:






         """simple docstring"""







         UpperCAmelCase				,  UpperCAmelCase				,  UpperCAmelCase				,  UpperCAmelCase				,  UpperCAmelCase							=     self.prepare_config_and_inputs()
         UpperCAmelCase							=     {"""pixel_values""": pixel_values, """pixel_mask""": pixel_mask}
         return config, inputs_dict





      def        _lowercase				(		self						:					str					,       __lowerCamelCase						:					int					,       __lowerCamelCase						:					Dict       )    ->   int:






         """simple docstring"""







         UpperCAmelCase							=     output.encoder_hidden_states
         UpperCAmelCase							=     output.pixel_decoder_hidden_states
         UpperCAmelCase							=     output.transformer_decoder_hidden_states

         self.parent.assertTrue(len(snake_case_       )					,       len(config.backbone_config.depths       )       )
         self.parent.assertTrue(len(snake_case_       )					,       len(config.backbone_config.depths       )       )
         self.parent.assertTrue(len(snake_case_       )					,       config.decoder_config.decoder_layers       )





      def        _lowercase				(		self						:					Union[str, Any]					,       __lowerCamelCase						:					str					,       __lowerCamelCase						:					List[Any]					,       __lowerCamelCase						:					Optional[int]					,       __lowerCamelCase						:					List[Any]=False       )    ->   Optional[Any]:






         """simple docstring"""







         with torch.no_grad():
            UpperCAmelCase							=     MaskFormerModel(config=snake_case_       )
            model.to(snake_case_       )
            model.eval()

            UpperCAmelCase							=     model(pixel_values=snake_case_					,       pixel_mask=snake_case_       )
            UpperCAmelCase							=     model(snake_case_					,       output_hidden_states=snake_case_       )
         # the correct shape of output.transformer_decoder_hidden_states ensure the correcteness of the
         # encoder and pixel decoder
         self.parent.assertEqual(
             output.transformer_decoder_last_hidden_state.shape					,       (self.batch_size, self.num_queries, self.mask_feature_size)					,       )
         # let's ensure the other two hidden state exists
         self.parent.assertTrue(output.pixel_decoder_last_hidden_state is not None       )
         self.parent.assertTrue(output.encoder_last_hidden_state is not None       )

         if output_hidden_states:
            self.check_output_hidden_state(snake_case_					,       snake_case_       )





      def        _lowercase				(		self						:					Optional[Any]					,       __lowerCamelCase						:					List[str]					,       __lowerCamelCase						:					int					,       __lowerCamelCase						:					Optional[int]					,       __lowerCamelCase						:					List[str]					,       __lowerCamelCase						:					str       )    ->   str:






         """simple docstring"""







         UpperCAmelCase							=     MaskFormerForInstanceSegmentation(config=snake_case_       )
         model.to(snake_case_       )
         model.eval()

         def comm_check_on_output(__lowerCamelCase						:					Optional[int]       ):
            # let's still check that all the required stuff is there
            self.parent.assertTrue(result.transformer_decoder_last_hidden_state is not None       )
            self.parent.assertTrue(result.pixel_decoder_last_hidden_state is not None       )
            self.parent.assertTrue(result.encoder_last_hidden_state is not None       )
            # okay, now we need to check the logits shape
            # due to the encoder compression, masks have a //4 spatial size
            self.parent.assertEqual(
                result.masks_queries_logits.shape					,       (self.batch_size, self.num_queries, self.min_size // 4, self.max_size // 4)					,       )
            # + 1 for null class
            self.parent.assertEqual(
                result.class_queries_logits.shape					,       (self.batch_size, self.num_queries, self.num_labels + 1)       )

         with torch.no_grad():
            UpperCAmelCase							=     model(pixel_values=snake_case_					,       pixel_mask=snake_case_       )
            UpperCAmelCase							=     model(snake_case_       )

            comm_check_on_output(snake_case_       )

            UpperCAmelCase							=     model(
                pixel_values=snake_case_					,       pixel_mask=snake_case_					,       mask_labels=snake_case_					,       class_labels=snake_case_       )

         comm_check_on_output(snake_case_       )

         self.parent.assertTrue(result.loss is not None       )
         self.parent.assertEqual(result.loss.shape					,       torch.Size([1]       )       )






@require_torch
class   __lowercase				(  _a ,					_a ,					unittest.TestCase  ):
      UpperCamelCase								=       (MaskFormerModel, MaskFormerForInstanceSegmentation) if is_torch_available() else ()
      UpperCamelCase								=       (
          {"""feature-extraction""": MaskFormerModel, """image-segmentation""": MaskFormerForInstanceSegmentation}
          if is_torch_available()
          else {}
      )

      UpperCamelCase								=       False
      UpperCamelCase								=       False
      UpperCamelCase								=       False
      UpperCamelCase								=       False





      def        _lowercase				(		self						:					Dict       )    ->   Union[str, Any]:






         """simple docstring"""







         UpperCAmelCase							=     MaskFormerModelTester(self       )
         UpperCAmelCase							=     ConfigTester(self					,       config_class=snake_case_					,       has_text_modality=snake_case_       )





      def        _lowercase				(		self						:					str       )    ->   Any:






         """simple docstring"""







         self.config_tester.run_common_tests()





      def        _lowercase				(		self						:					Optional[int]       )    ->   Optional[int]:






         """simple docstring"""







         UpperCAmelCase				,  UpperCAmelCase							=     self.model_tester.prepare_config_and_inputs_for_common()
         self.model_tester.create_and_check_maskformer_model(snake_case_					,       **snake_case_					,       output_hidden_states=snake_case_       )





      def        _lowercase				(		self						:					int       )    ->   str:






         """simple docstring"""







         UpperCAmelCase							=     self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_maskformer_instance_segmentation_head_model(*snake_case_       )





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






         """simple docstring"""







         pass





      @unittest.skip(reason="""MaskFormer does not have a get_input_embeddings method"""       )
      def        _lowercase				(		self						:					Optional[Any]       )    ->   str:






         """simple docstring"""







         pass





      @unittest.skip(reason="""MaskFormer is not a generative model"""       )
      def        _lowercase				(		self						:					Dict       )    ->   int:






         """simple docstring"""







         pass





      @unittest.skip(reason="""MaskFormer does not use token embeddings"""       )
      def        _lowercase				(		self						:					Dict       )    ->   int:






         """simple docstring"""







         pass





      @require_torch_multi_gpu
      @unittest.skip(
          reason="""MaskFormer has some layers using `add_module` which doesn\'t work well with `nn.DataParallel`"""       )
      def        _lowercase				(		self						:					Tuple       )    ->   Dict:






         """simple docstring"""







         pass





      @unittest.skip("""Will be fixed soon by reducing the size of the model used for common tests."""       )
      def        _lowercase				(		self						:					int       )    ->   Any:






         """simple docstring"""







         pass





      def        _lowercase				(		self						:					Any       )    ->   List[Any]:






         """simple docstring"""







         UpperCAmelCase				,  UpperCAmelCase							=     self.model_tester.prepare_config_and_inputs_for_common()

         for model_class in self.all_model_classes:
            UpperCAmelCase							=     model_class(snake_case_       )
            UpperCAmelCase							=     inspect.signature(model.forward       )
            # signature.parameters is an OrderedDict => so arg_names order is deterministic
            UpperCAmelCase							=     [*signature.parameters.keys()]

            UpperCAmelCase							=     ["""pixel_values"""]
            self.assertListEqual(arg_names[:1]					,       snake_case_       )





      @slow
      def        _lowercase				(		self						:					Optional[int]       )    ->   Dict:






         """simple docstring"""







         for model_name in ["facebook/maskformer-swin-small-coco"]:
            UpperCAmelCase							=     MaskFormerModel.from_pretrained(snake_case_       )
            self.assertIsNotNone(snake_case_       )





      def        _lowercase				(		self						:					Dict       )    ->   int:






         """simple docstring"""







         UpperCAmelCase							=     (self.model_tester.min_size,) * 2
         UpperCAmelCase							=     {
             """pixel_values""": torch.randn((2, 3, *size)					,       device=snake_case_       ),
             """mask_labels""": torch.randn((2, 1_0, *size)					,       device=snake_case_       ),
             """class_labels""": torch.zeros(2					,       1_0					,       device=snake_case_       ).long(),
         }

         UpperCAmelCase							=     MaskFormerForInstanceSegmentation(MaskFormerConfig()       ).to(snake_case_       )
         UpperCAmelCase							=     model(**snake_case_       )
         self.assertTrue(outputs.loss is not None       )





      def        _lowercase				(		self						:					str       )    ->   Dict:






         """simple docstring"""







         UpperCAmelCase				,  UpperCAmelCase							=     self.model_tester.prepare_config_and_inputs_for_common()
         self.model_tester.create_and_check_maskformer_model(snake_case_					,       **snake_case_					,       output_hidden_states=snake_case_       )





      def        _lowercase				(		self						:					List[str]       )    ->   List[str]:






         """simple docstring"""







         UpperCAmelCase				,  UpperCAmelCase							=     self.model_tester.prepare_config_and_inputs_for_common()

         for model_class in self.all_model_classes:
            UpperCAmelCase							=     model_class(snake_case_       ).to(snake_case_       )
            UpperCAmelCase							=     model(**snake_case_					,       output_attentions=snake_case_       )
            self.assertTrue(outputs.attentions is not None       )





      def        _lowercase				(		self						:					Optional[Any]       )    ->   str:






         """simple docstring"""







         if not self.model_tester.is_training:
            return
         # only MaskFormerForInstanceSegmentation has the loss
         UpperCAmelCase							=     self.all_model_classes[1]
         UpperCAmelCase				,  UpperCAmelCase				,  UpperCAmelCase				,  UpperCAmelCase				,  UpperCAmelCase							=     self.model_tester.prepare_config_and_inputs()

         UpperCAmelCase							=     model_class(snake_case_       )
         model.to(snake_case_       )
         model.train()

         UpperCAmelCase							=     model(snake_case_					,       mask_labels=snake_case_					,       class_labels=snake_case_       ).loss
         loss.backward()





      def        _lowercase				(		self						:					Optional[Any]       )    ->   int:






         """simple docstring"""







         UpperCAmelCase							=     self.all_model_classes[1]
         UpperCAmelCase				,  UpperCAmelCase				,  UpperCAmelCase				,  UpperCAmelCase				,  UpperCAmelCase							=     self.model_tester.prepare_config_and_inputs()
         UpperCAmelCase							=     True
         UpperCAmelCase							=     True

         UpperCAmelCase							=     model_class(snake_case_       )
         model.to(snake_case_       )
         model.train()

         UpperCAmelCase							=     model(snake_case_					,       mask_labels=snake_case_					,       class_labels=snake_case_       )

         UpperCAmelCase							=     outputs.encoder_hidden_states[0]
         encoder_hidden_states.retain_grad()

         UpperCAmelCase							=     outputs.pixel_decoder_hidden_states[0]
         pixel_decoder_hidden_states.retain_grad()
         # we requires_grad=True in inputs_embeds (line 2152), the original implementation don't
         UpperCAmelCase							=     outputs.transformer_decoder_hidden_states[0]
         transformer_decoder_hidden_states.retain_grad()

         UpperCAmelCase							=     outputs.attentions[0]
         attentions.retain_grad()

         outputs.loss.backward(retain_graph=snake_case_       )

         self.assertIsNotNone(encoder_hidden_states.grad       )
         self.assertIsNotNone(pixel_decoder_hidden_states.grad       )
         self.assertIsNotNone(transformer_decoder_hidden_states.grad       )
         self.assertIsNotNone(attentions.grad       )

__a     =			1E-4
def   _UpperCamelCase				(						)						->List[str]:
   UpperCAmelCase							=     Image.open("""./tests/fixtures/tests_samples/COCO/000000039769.png"""   )
   return image







@require_vision
@slow
class   __lowercase				(  unittest.TestCase  ):





      @cached_property
      def        _lowercase				(		self						:					Union[str, Any]       )    ->   Optional[Any]:






         """simple docstring"""







         return (
             MaskFormerImageProcessor.from_pretrained("""facebook/maskformer-swin-small-coco"""       )
             if is_vision_available()
             else None
         )





      def        _lowercase				(		self						:					Union[str, Any]       )    ->   Optional[Any]:






         """simple docstring"""







         UpperCAmelCase							=     MaskFormerModel.from_pretrained("""facebook/maskformer-swin-small-coco"""       ).to(snake_case_       )
         UpperCAmelCase							=     self.default_image_processor
         UpperCAmelCase							=     prepare_img()
         UpperCAmelCase							=     image_processor(snake_case_					,       return_tensors="""pt"""       ).to(snake_case_       )
         UpperCAmelCase							=     inputs["""pixel_values"""].shape
         # check size is divisible by 32
         self.assertTrue((inputs_shape[-1] % 3_2) == 0 and (inputs_shape[-2] % 3_2) == 0       )
         # check size
         self.assertEqual(snake_case_					,       (1, 3, 8_0_0, 1_0_8_8)       )

         with torch.no_grad():
            UpperCAmelCase							=     model(**snake_case_       )

         UpperCAmelCase							=     torch.tensor(
             [[-0.0_482, 0.9_228, 0.4_951], [-0.2_547, 0.8_017, 0.8_527], [-0.0_069, 0.3_385, -0.0_089]]       ).to(snake_case_       )
         self.assertTrue(
             torch.allclose(
                 outputs.encoder_last_hidden_state[0, 0, :3, :3]					,       snake_case_					,       atol=snake_case_       )       )

         UpperCAmelCase							=     torch.tensor(
             [[-0.8_422, -0.8_434, -0.9_718], [-1.0_144, -0.5_565, -0.4_195], [-1.0_038, -0.4_484, -0.1_961]]       ).to(snake_case_       )
         self.assertTrue(
             torch.allclose(
                 outputs.pixel_decoder_last_hidden_state[0, 0, :3, :3]					,       snake_case_					,       atol=snake_case_       )       )

         UpperCAmelCase							=     torch.tensor(
             [[0.2_852, -0.0_159, 0.9_735], [0.6_254, 0.1_858, 0.8_529], [-0.0_680, -0.4_116, 1.8_413]]       ).to(snake_case_       )
         self.assertTrue(
             torch.allclose(
                 outputs.transformer_decoder_last_hidden_state[0, :3, :3]					,       snake_case_					,       atol=snake_case_       )       )





      def        _lowercase				(		self						:					Any       )    ->   Optional[int]:






         """simple docstring"""







         UpperCAmelCase							=     (
             MaskFormerForInstanceSegmentation.from_pretrained("""facebook/maskformer-swin-small-coco"""       )
             .to(snake_case_       )
             .eval()
         )
         UpperCAmelCase							=     self.default_image_processor
         UpperCAmelCase							=     prepare_img()
         UpperCAmelCase							=     image_processor(snake_case_					,       return_tensors="""pt"""       ).to(snake_case_       )
         UpperCAmelCase							=     inputs["""pixel_values"""].shape
         # check size is divisible by 32
         self.assertTrue((inputs_shape[-1] % 3_2) == 0 and (inputs_shape[-2] % 3_2) == 0       )
         # check size
         self.assertEqual(snake_case_					,       (1, 3, 8_0_0, 1_0_8_8)       )

         with torch.no_grad():
            UpperCAmelCase							=     model(**snake_case_       )
         # masks_queries_logits
         UpperCAmelCase							=     outputs.masks_queries_logits
         self.assertEqual(
             masks_queries_logits.shape					,       (1, model.config.decoder_config.num_queries, inputs_shape[-2] // 4, inputs_shape[-1] // 4)					,       )
         UpperCAmelCase							=     [
             [-1.3_737_124, -1.7_724_937, -1.9_364_233],
             [-1.5_977_281, -1.9_867_939, -2.1_523_695],
             [-1.5_795_398, -1.9_269_832, -2.093_942],
         ]
         UpperCAmelCase							=     torch.tensor(snake_case_       ).to(snake_case_       )
         self.assertTrue(torch.allclose(masks_queries_logits[0, 0, :3, :3]					,       snake_case_					,       atol=snake_case_       )       )
         # class_queries_logits
         UpperCAmelCase							=     outputs.class_queries_logits
         self.assertEqual(
             class_queries_logits.shape					,       (1, model.config.decoder_config.num_queries, model.config.num_labels + 1)       )
         UpperCAmelCase							=     torch.tensor(
             [
                 [1.6_5_1_2e0_0, -5.2_5_7_2e0_0, -3.3_5_1_9e0_0],
                 [3.6_1_6_9e-0_2, -5.9_0_2_5e0_0, -2.9_3_1_3e0_0],
                 [1.0_7_6_6e-0_4, -7.7_6_3_0e0_0, -5.1_2_6_3e0_0],
             ]       ).to(snake_case_       )
         self.assertTrue(torch.allclose(outputs.class_queries_logits[0, :3, :3]					,       snake_case_					,       atol=snake_case_       )       )





      def        _lowercase				(		self						:					Tuple       )    ->   List[str]:






         """simple docstring"""







         UpperCAmelCase							=     (
             MaskFormerForInstanceSegmentation.from_pretrained("""facebook/maskformer-resnet101-coco-stuff"""       )
             .to(snake_case_       )
             .eval()
         )
         UpperCAmelCase							=     self.default_image_processor
         UpperCAmelCase							=     prepare_img()
         UpperCAmelCase							=     image_processor(snake_case_					,       return_tensors="""pt"""       ).to(snake_case_       )
         UpperCAmelCase							=     inputs["""pixel_values"""].shape
         # check size is divisible by 32
         self.assertTrue((inputs_shape[-1] % 3_2) == 0 and (inputs_shape[-2] % 3_2) == 0       )
         # check size
         self.assertEqual(snake_case_					,       (1, 3, 8_0_0, 1_0_8_8)       )

         with torch.no_grad():
            UpperCAmelCase							=     model(**snake_case_       )
         # masks_queries_logits
         UpperCAmelCase							=     outputs.masks_queries_logits
         self.assertEqual(
             masks_queries_logits.shape					,       (1, model.config.decoder_config.num_queries, inputs_shape[-2] // 4, inputs_shape[-1] // 4)					,       )
         UpperCAmelCase							=     [[-0.9_046, -2.6_366, -4.6_062], [-3.4_179, -5.7_890, -8.8_057], [-4.9_179, -7.6_560, -10.7_711]]
         UpperCAmelCase							=     torch.tensor(snake_case_       ).to(snake_case_       )
         self.assertTrue(torch.allclose(masks_queries_logits[0, 0, :3, :3]					,       snake_case_					,       atol=snake_case_       )       )
         # class_queries_logits
         UpperCAmelCase							=     outputs.class_queries_logits
         self.assertEqual(
             class_queries_logits.shape					,       (1, model.config.decoder_config.num_queries, model.config.num_labels + 1)       )
         UpperCAmelCase							=     torch.tensor(
             [[4.7_188, -3.2_585, -2.8_857], [6.6_871, -2.9_181, -1.2_487], [7.2_449, -2.2_764, -2.1_874]]       ).to(snake_case_       )
         self.assertTrue(torch.allclose(outputs.class_queries_logits[0, :3, :3]					,       snake_case_					,       atol=snake_case_       )       )





      def        _lowercase				(		self						:					Optional[Any]       )    ->   Any:






         """simple docstring"""







         UpperCAmelCase							=     (
             MaskFormerForInstanceSegmentation.from_pretrained("""facebook/maskformer-swin-small-coco"""       )
             .to(snake_case_       )
             .eval()
         )
         UpperCAmelCase							=     self.default_image_processor

         UpperCAmelCase							=     image_processor(
             [np.zeros((3, 8_0_0, 1_3_3_3)       ), np.zeros((3, 8_0_0, 1_3_3_3)       )]					,       segmentation_maps=[np.zeros((3_8_4, 3_8_4)       ).astype(np.floataa       ), np.zeros((3_8_4, 3_8_4)       ).astype(np.floataa       )]					,       return_tensors="""pt"""					,       )

         UpperCAmelCase							=     inputs["""pixel_values"""].to(snake_case_       )
         UpperCAmelCase							=     [el.to(snake_case_       ) for el in inputs["""mask_labels"""]]
         UpperCAmelCase							=     [el.to(snake_case_       ) for el in inputs["""class_labels"""]]

         with torch.no_grad():
            UpperCAmelCase							=     model(**snake_case_       )

         self.assertTrue(outputs.loss is not None       )








__a     =			[
    (1000, """M"""),
    (900, """CM"""),
    (500, """D"""),
    (400, """CD"""),
    (100, """C"""),
    (90, """XC"""),
    (50, """L"""),
    (40, """XL"""),
    (10, """X"""),
    (9, """IX"""),
    (5, """V"""),
    (4, """IV"""),
    (1, """I"""),
]
def   _UpperCamelCase				(						lowerCAmelCase_   )						->int:
   UpperCAmelCase							=     {"""I""": 1, """V""": 5, """X""": 1_0, """L""": 5_0, """C""": 1_0_0, """D""": 5_0_0, """M""": 1_0_0_0}
   UpperCAmelCase							=     0
   UpperCAmelCase							=     0
   while place < len(lowerCAmelCase_   ):
      if (place + 1 < len(lowerCAmelCase_   )) and (vals[roman[place]] < vals[roman[place + 1]]):
         total += vals[roman[place + 1]] - vals[roman[place]]
         place += 2
      else:
         total += vals[roman[place]]
         place += 1
   return total
def   _UpperCamelCase				(						lowerCAmelCase_   )						->str:
   UpperCAmelCase							=     []
   for arabic, roman in ROMAN:
      ((UpperCAmelCase)				,  (UpperCAmelCase))							=     divmod(lowerCAmelCase_  ,						lowerCAmelCase_   )
      result.append(roman * factor   )
      if number == 0:
         break
   return "".join(lowerCAmelCase_   )


if __name__ == "__main__":
 import doctest

 doctest.testmod()



