





import inspect
import unittest

from datasets import load_dataset
from packaging import version

from transformers import BeitConfig
from transformers.models.auto import get_values
from transformers.testing_utils import require_torch, require_torch_multi_gpu, require_vision, slow, torch_device
from transformers.utils import cached_property, is_torch_available, is_vision_available

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
       import torch
       from torch import nn

       from transformers import (
           MODEL_MAPPING,
           BeitForImageClassification,
           BeitForMaskedImageModeling,
           BeitForSemanticSegmentation,
           BeitModel,
       )
       from transformers.models.beit.modeling_beit import BEIT_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
       import PIL
       from PIL import Image

       from transformers import BeitImageProcessor







class       __A							:




      """simple docstring"""







      def __init__(		self   ,				a__   ,				a__=100   ,				a__=13   ,				a__=30   ,				a__=2   ,				a__=3   ,				a__=True   ,				a__=True   ,				a__=32   ,				a__=4   ,				a__=4   ,				a__=37   ,				a__="gelu"   ,				a__=0.1   ,				a__=0.1   ,				a__=10   ,				a__=0.02   ,				a__=3   ,				a__=None   ,				a__=[0, 1, 2, 3]   ,				):



             """simple docstring"""





             _lowerCamelCase				:  Tuple						=		parent
             _lowerCamelCase				:  Optional[int]						=		100
             _lowerCamelCase				:  str						=		batch_size
             _lowerCamelCase				:  Optional[Any]						=		image_size
             _lowerCamelCase				:  int						=		patch_size
             _lowerCamelCase				:  Optional[int]						=		num_channels
             _lowerCamelCase				:  str						=		is_training
             _lowerCamelCase				:  Optional[Any]						=		use_labels
             _lowerCamelCase				:  Optional[int]						=		hidden_size
             _lowerCamelCase				:  List[Any]						=		num_hidden_layers
             _lowerCamelCase				:  Tuple						=		num_attention_heads
             _lowerCamelCase				:  str						=		intermediate_size
             _lowerCamelCase				:  Dict						=		hidden_act
             _lowerCamelCase				:  str						=		hidden_dropout_prob
             _lowerCamelCase				:  Dict						=		attention_probs_dropout_prob
             _lowerCamelCase				:  Dict						=		type_sequence_label_size
             _lowerCamelCase				:  Union[str, Any]						=		initializer_range
             _lowerCamelCase				:  List[str]						=		scope
             _lowerCamelCase				:  Optional[Any]						=		out_indices
             _lowerCamelCase				:  Tuple						=		num_labels

             # in BeiT, the seq length equals the number of patches + 1 (we add 1 for the [CLS] token)
             _lowerCamelCase				:  str						=		(image_size // patch_size) ** 2
             _lowerCamelCase				:  Optional[Any]						=		num_patches + 1


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  Tuple						=		floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size])

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

             _lowerCamelCase				:  int						=		self.get_config()

             return config, pixel_values, labels, pixel_labels


      def 					__snake_case      (		self):



             """simple docstring"""





             return BeitConfig(
                 vocab_size=self.vocab_size   ,				image_size=self.image_size   ,				patch_size=self.patch_size   ,				num_channels=self.num_channels   ,				hidden_size=self.hidden_size   ,				num_hidden_layers=self.num_hidden_layers   ,				num_attention_heads=self.num_attention_heads   ,				intermediate_size=self.intermediate_size   ,				hidden_act=self.hidden_act   ,				hidden_dropout_prob=self.hidden_dropout_prob   ,				attention_probs_dropout_prob=self.attention_probs_dropout_prob   ,				is_decoder=a__   ,				initializer_range=self.initializer_range   ,				out_indices=self.out_indices   ,				)


      def 					__snake_case      (		self   ,				a__   ,				a__   ,				a__   ,				a__):



             """simple docstring"""





             _lowerCamelCase				:  Optional[int]						=		BeitModel(config=a__)
             model.to(a__)
             model.eval()
             _lowerCamelCase				:  Dict						=		model(a__)
             self.parent.assertEqual(result.last_hidden_state.shape   ,				(self.batch_size, self.seq_length, self.hidden_size))


      def 					__snake_case      (		self   ,				a__   ,				a__   ,				a__   ,				a__):



             """simple docstring"""





             _lowerCamelCase				:  Optional[int]						=		BeitForMaskedImageModeling(config=a__)
             model.to(a__)
             model.eval()
             _lowerCamelCase				:  Optional[Any]						=		model(a__)
             self.parent.assertEqual(result.logits.shape   ,				(self.batch_size, self.seq_length - 1, self.vocab_size))


      def 					__snake_case      (		self   ,				a__   ,				a__   ,				a__   ,				a__):



             """simple docstring"""





             _lowerCamelCase				:  int						=		self.type_sequence_label_size
             _lowerCamelCase				:  Any						=		BeitForImageClassification(a__)
             model.to(a__)
             model.eval()
             _lowerCamelCase				:  List[Any]						=		model(a__   ,				labels=a__)
             self.parent.assertEqual(result.logits.shape   ,				(self.batch_size, self.type_sequence_label_size))

             # test greyscale images
             _lowerCamelCase				:  Dict						=		1
             _lowerCamelCase				:  str						=		BeitForImageClassification(a__)
             model.to(a__)
             model.eval()

             _lowerCamelCase				:  Optional[int]						=		floats_tensor([self.batch_size, 1, self.image_size, self.image_size])
             _lowerCamelCase				:  Any						=		model(a__   ,				labels=a__)
             self.parent.assertEqual(result.logits.shape   ,				(self.batch_size, self.type_sequence_label_size))


      def 					__snake_case      (		self   ,				a__   ,				a__   ,				a__   ,				a__):



             """simple docstring"""





             _lowerCamelCase				:  Optional[int]						=		self.num_labels
             _lowerCamelCase				:  List[Any]						=		BeitForSemanticSegmentation(a__)
             model.to(a__)
             model.eval()
             _lowerCamelCase				:  Optional[int]						=		model(a__)
             self.parent.assertEqual(
                 result.logits.shape   ,				(self.batch_size, self.num_labels, self.image_size * 2, self.image_size * 2))
             _lowerCamelCase				:  int						=		model(a__   ,				labels=a__)
             self.parent.assertEqual(
                 result.logits.shape   ,				(self.batch_size, self.num_labels, self.image_size * 2, self.image_size * 2))



      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  Any						=		self.prepare_config_and_inputs()
             _lowerCamelCase,	_lowerCamelCase,	_lowerCamelCase,	_lowerCamelCase				:  Optional[int]						=		config_and_inputs
             _lowerCamelCase				:  List[Any]						=		{'''pixel_values''': pixel_values}
             return config, inputs_dict







@require_torch
class       __A							(   lowerCamelCase__			,lowerCamelCase__			,unittest.TestCase	):




      """simple docstring"""







      UpperCAmelCase__							=   (
          (BeitModel, BeitForImageClassification, BeitForMaskedImageModeling, BeitForSemanticSegmentation)
          if is_torch_available()
          else ()
      )
      UpperCAmelCase__							=   (
          {
              """feature-extraction""": BeitModel,
              """image-classification""": BeitForImageClassification,
              """image-segmentation""": BeitForSemanticSegmentation,
          }
          if is_torch_available()
          else {}
      )

      UpperCAmelCase__							=   False
      UpperCAmelCase__							=   False
      UpperCAmelCase__							=   False


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  Optional[int]						=		BeitModelTester(self)
             _lowerCamelCase				:  List[str]						=		ConfigTester(self   ,				config_class=a__   ,				has_text_modality=a__   ,				hidden_size=37)


      def 					__snake_case      (		self):



             """simple docstring"""





             self.config_tester.run_common_tests()


      @unittest.skip(reason='''BEiT does not use inputs_embeds''')
      def 					__snake_case      (		self):



             """simple docstring"""





             pass


      @require_torch_multi_gpu
      @unittest.skip(reason='''BEiT has some layers using `add_module` which doesn\'t work well with `nn.DataParallel`''')
      def 					__snake_case      (		self):



             """simple docstring"""





             pass


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase,	_lowerCamelCase				:  Tuple						=		self.model_tester.prepare_config_and_inputs_for_common()

             for model_class in self.all_model_classes:
                    _lowerCamelCase				:  List[Any]						=		model_class(a__)
                    self.assertIsInstance(model.get_input_embeddings()   ,				(nn.Module))
                    _lowerCamelCase				:  str						=		model.get_output_embeddings()
                    self.assertTrue(x is None or isinstance(a__   ,				nn.Linear))


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase,	_lowerCamelCase				:  Optional[int]						=		self.model_tester.prepare_config_and_inputs_for_common()

             for model_class in self.all_model_classes:
                    _lowerCamelCase				:  Dict						=		model_class(a__)
                    _lowerCamelCase				:  Optional[Any]						=		inspect.signature(model.forward)
                    # signature.parameters is an OrderedDict => so arg_names order is deterministic
                    _lowerCamelCase				:  Tuple						=		[*signature.parameters.keys()]

                    _lowerCamelCase				:  Optional[Any]						=		['''pixel_values''']
                    self.assertListEqual(arg_names[:1]   ,				a__)


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  Optional[int]						=		self.model_tester.prepare_config_and_inputs()
             self.model_tester.create_and_check_model(*a__)


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  Union[str, Any]						=		self.model_tester.prepare_config_and_inputs()
             self.model_tester.create_and_check_for_masked_lm(*a__)


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  int						=		self.model_tester.prepare_config_and_inputs()
             self.model_tester.create_and_check_for_image_classification(*a__)


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  Optional[int]						=		self.model_tester.prepare_config_and_inputs()
             self.model_tester.create_and_check_for_semantic_segmentation(*a__)


      def 					__snake_case      (		self):



             """simple docstring"""





             if not self.model_tester.is_training:
                    return

             _lowerCamelCase,	_lowerCamelCase				:  Union[str, Any]						=		self.model_tester.prepare_config_and_inputs_for_common()
             _lowerCamelCase				:  Union[str, Any]						=		True

             for model_class in self.all_model_classes:
                    # we don't test BeitForMaskedImageModeling
                    if model_class in [*get_values(a__), BeitForMaskedImageModeling]:
                           continue

                    _lowerCamelCase				:  List[str]						=		model_class(a__)
                    model.to(a__)
                    model.train()
                    _lowerCamelCase				:  Optional[Any]						=		self._prepare_for_class(a__   ,				a__   ,				return_labels=a__)
                    _lowerCamelCase				:  Tuple						=		model(**a__).loss
                    loss.backward()


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase,	_lowerCamelCase				:  Tuple						=		self.model_tester.prepare_config_and_inputs_for_common()
             if not self.model_tester.is_training:
                    return

             _lowerCamelCase				:  Tuple						=		False
             _lowerCamelCase				:  Any						=		True

             for model_class in self.all_model_classes:
                    # we don't test BeitForMaskedImageModeling
                    if (
                        model_class in [*get_values(a__), BeitForMaskedImageModeling]
                        or not model_class.supports_gradient_checkpointing
                    ):
                           continue

                    _lowerCamelCase				:  str						=		model_class(a__)
                    model.gradient_checkpointing_enable()
                    model.to(a__)
                    model.train()
                    _lowerCamelCase				:  List[str]						=		self._prepare_for_class(a__   ,				a__   ,				return_labels=a__)
                    _lowerCamelCase				:  List[str]						=		model(**a__).loss
                    loss.backward()


      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase,	_lowerCamelCase				:  Optional[int]						=		self.model_tester.prepare_config_and_inputs_for_common()

             _lowerCamelCase				:  List[Any]						=		_config_zero_init(a__)
             for model_class in self.all_model_classes:
                    _lowerCamelCase				:  Optional[Any]						=		model_class(config=a__)
                    for name, param in model.named_parameters():
                           # we skip lambda parameters as these require special initial values
                           # determined by config.layer_scale_init_value
                           if "lambda" in name:
                                  continue
                           if param.requires_grad:
                                  self.assertIn(
                                      ((param.data.mean() * 1e9).round() / 1e9).item()   ,				[0.0, 1.0]   ,				msg=F"""Parameter {name} of model {model_class} seems not properly initialized"""   ,				)



      @slow
      def 					__snake_case      (		self):



             """simple docstring"""





             for model_name in BEIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
                    _lowerCamelCase				:  str						=		BeitModel.from_pretrained(a__)
                    self.assertIsNotNone(a__)




def  __UpperCAmelCase(   ):
       _lowerCamelCase				:  List[Any]						=		Image.open('''./tests/fixtures/tests_samples/COCO/000000039769.png'''   )
       return image







@require_torch
@require_vision
class       __A							(   unittest.TestCase	):




      """simple docstring"""







      @cached_property
      def 					__snake_case      (		self):



             """simple docstring"""





             return BeitImageProcessor.from_pretrained('''microsoft/beit-base-patch16-224''') if is_vision_available() else None


      @slow
      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  Dict						=		BeitForMaskedImageModeling.from_pretrained('''microsoft/beit-base-patch16-224-pt22k''').to(a__)

             _lowerCamelCase				:  str						=		self.default_image_processor
             _lowerCamelCase				:  Optional[int]						=		prepare_img()
             _lowerCamelCase				:  Optional[int]						=		image_processor(images=a__   ,				return_tensors='''pt''').pixel_values.to(a__)

             # prepare bool_masked_pos
             _lowerCamelCase				:  Tuple						=		torch.ones((1, 196)   ,				dtype=torch.bool).to(a__)

             # forward pass
             with torch.no_grad():
                    _lowerCamelCase				:  int						=		model(pixel_values=a__   ,				bool_masked_pos=a__)
             _lowerCamelCase				:  str						=		outputs.logits

             # verify the logits
             _lowerCamelCase				:  Union[str, Any]						=		torch.Size((1, 196, 8192))
             self.assertEqual(logits.shape   ,				a__)

             _lowerCamelCase				:  int						=		torch.tensor(
                 [[-3.2437, 0.5072, -13.9174], [-3.2456, 0.4948, -13.9401], [-3.2033, 0.5121, -13.8550]]).to(a__)

             self.assertTrue(torch.allclose(logits[bool_masked_pos][:3, :3]   ,				a__   ,				atol=1e-2))


      @slow
      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  str						=		BeitForImageClassification.from_pretrained('''microsoft/beit-base-patch16-224''').to(a__)

             _lowerCamelCase				:  List[str]						=		self.default_image_processor
             _lowerCamelCase				:  Optional[int]						=		prepare_img()
             _lowerCamelCase				:  List[Any]						=		image_processor(images=a__   ,				return_tensors='''pt''').to(a__)

             # forward pass
             with torch.no_grad():
                    _lowerCamelCase				:  Union[str, Any]						=		model(**a__)
             _lowerCamelCase				:  Dict						=		outputs.logits

             # verify the logits
             _lowerCamelCase				:  Optional[Any]						=		torch.Size((1, 1000))
             self.assertEqual(logits.shape   ,				a__)

             _lowerCamelCase				:  str						=		torch.tensor([-1.2385, -1.0987, -1.0108]).to(a__)

             self.assertTrue(torch.allclose(logits[0, :3]   ,				a__   ,				atol=1e-4))

             _lowerCamelCase				:  Optional[Any]						=		281
             self.assertEqual(logits.argmax(-1).item()   ,				a__)


      @slow
      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  List[str]						=		BeitForImageClassification.from_pretrained('''microsoft/beit-large-patch16-224-pt22k-ft22k''').to(
                 a__)

             _lowerCamelCase				:  Any						=		self.default_image_processor
             _lowerCamelCase				:  Dict						=		prepare_img()
             _lowerCamelCase				:  str						=		image_processor(images=a__   ,				return_tensors='''pt''').to(a__)

             # forward pass
             with torch.no_grad():
                    _lowerCamelCase				:  str						=		model(**a__)
             _lowerCamelCase				:  Any						=		outputs.logits

             # verify the logits
             _lowerCamelCase				:  int						=		torch.Size((1, 2_1841))
             self.assertEqual(logits.shape   ,				a__)

             _lowerCamelCase				:  Optional[Any]						=		torch.tensor([1.6881, -0.2787, 0.5901]).to(a__)

             self.assertTrue(torch.allclose(logits[0, :3]   ,				a__   ,				atol=1e-4))

             _lowerCamelCase				:  int						=		2396
             self.assertEqual(logits.argmax(-1).item()   ,				a__)


      @slow
      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  str						=		BeitForSemanticSegmentation.from_pretrained('''microsoft/beit-base-finetuned-ade-640-640''')
             _lowerCamelCase				:  int						=		model.to(a__)

             _lowerCamelCase				:  Any						=		BeitImageProcessor(do_resize=a__   ,				size=640   ,				do_center_crop=a__)

             _lowerCamelCase				:  List[Any]						=		load_dataset('''hf-internal-testing/fixtures_ade20k'''   ,				split='''test''')
             _lowerCamelCase				:  List[Any]						=		Image.open(ds[0]['''file'''])
             _lowerCamelCase				:  List[str]						=		image_processor(images=a__   ,				return_tensors='''pt''').to(a__)

             # forward pass
             with torch.no_grad():
                    _lowerCamelCase				:  int						=		model(**a__)
             _lowerCamelCase				:  Optional[int]						=		outputs.logits

             # verify the logits
             _lowerCamelCase				:  Tuple						=		torch.Size((1, 150, 160, 160))
             self.assertEqual(logits.shape   ,				a__)

             _lowerCamelCase				:  List[str]						=		version.parse(PIL.__version__) < version.parse('''9.0.0''')

             if is_pillow_less_than_a:
                    _lowerCamelCase				:  int						=		torch.tensor(
                        [
                            [[-4.9225, -2.3954, -3.0522], [-2.8822, -1.0046, -1.7561], [-2.9549, -1.3228, -2.1347]],
                            [[-5.8168, -3.4129, -4.0778], [-3.8651, -2.2214, -3.0277], [-3.8356, -2.4643, -3.3535]],
                            [[-0.0078, 3.9952, 4.0754], [2.9856, 4.6944, 5.0035], [3.2413, 4.7813, 4.9969]],
                        ]   ,				device=a__   ,				)
             else:
                    _lowerCamelCase				:  List[str]						=		torch.tensor(
                        [
                            [[-4.8960, -2.3688, -3.0355], [-2.8478, -0.9836, -1.7418], [-2.9449, -1.3332, -2.1456]],
                            [[-5.8081, -3.4124, -4.1006], [-3.8561, -2.2081, -3.0323], [-3.8365, -2.4601, -3.3669]],
                            [[-0.0309, 3.9868, 4.0540], [2.9640, 4.6877, 4.9976], [3.2081, 4.7690, 4.9942]],
                        ]   ,				device=a__   ,				)

             self.assertTrue(torch.allclose(logits[0, :3, :3, :3]   ,				a__   ,				atol=1e-4))



      @slow
      def 					__snake_case      (		self):



             """simple docstring"""





             _lowerCamelCase				:  str						=		BeitForSemanticSegmentation.from_pretrained('''microsoft/beit-base-finetuned-ade-640-640''')
             _lowerCamelCase				:  Union[str, Any]						=		model.to(a__)

             _lowerCamelCase				:  List[Any]						=		BeitImageProcessor(do_resize=a__   ,				size=640   ,				do_center_crop=a__)

             _lowerCamelCase				:  List[str]						=		load_dataset('''hf-internal-testing/fixtures_ade20k'''   ,				split='''test''')
             _lowerCamelCase				:  Any						=		Image.open(ds[0]['''file'''])
             _lowerCamelCase				:  Union[str, Any]						=		image_processor(images=a__   ,				return_tensors='''pt''').to(a__)

             # forward pass
             with torch.no_grad():
                    _lowerCamelCase				:  Union[str, Any]						=		model(**a__)

             _lowerCamelCase				:  Tuple						=		outputs.logits.detach().cpu()

             _lowerCamelCase				:  Dict						=		image_processor.post_process_semantic_segmentation(outputs=a__   ,				target_sizes=[(500, 300)])
             _lowerCamelCase				:  str						=		torch.Size((500, 300))
             self.assertEqual(segmentation[0].shape   ,				a__)

             _lowerCamelCase				:  Tuple						=		image_processor.post_process_semantic_segmentation(outputs=a__)
             _lowerCamelCase				:  Optional[int]						=		torch.Size((160, 160))
             self.assertEqual(segmentation[0].shape   ,				a__)








from __future__ import annotations

from scipy.special import comb  # type: ignore







class       __A							:




      """simple docstring"""







      def __init__(		self   ,				a__):



             """simple docstring"""





             _lowerCamelCase				:  str						=		list_of_points
             # Degree determines the flexibility of the curve.
             # Degree = 1 will produce a straight line.
             _lowerCamelCase				:  List[Any]						=		len(a__) - 1


      def 					__snake_case      (		self   ,				a__):



             """simple docstring"""





             assert 0 <= t <= 1, "Time t must be between 0 and 1."
             _lowerCamelCase				:  list[float]						=		[]
             for i in range(len(self.list_of_points)):
                    # basis function for each i
                    output_values.append(
                        comb(self.degree   ,				a__) * ((1 - t) ** (self.degree - i)) * (t**i))
             # the basis must sum up to 1 for it to produce a valid Bezier curve.
             assert round(sum(a__)   ,				5) == 1
             return output_values


      def 					__snake_case      (		self   ,				a__):



             """simple docstring"""





             assert 0 <= t <= 1, "Time t must be between 0 and 1."

             _lowerCamelCase				:  Any						=		self.basis_function(a__)
             _lowerCamelCase				:  List[Any]						=		0.0
             _lowerCamelCase				:  List[Any]						=		0.0
             for i in range(len(self.list_of_points)):
                    # For all points, sum up the product of i-th basis function and i-th point.
                    x += basis_function[i] * self.list_of_points[i][0]
                    y += basis_function[i] * self.list_of_points[i][1]
             return (x, y)



      def 					__snake_case      (		self   ,				a__ = 0.01):



             """simple docstring"""





             from matplotlib import pyplot as plt  # type: ignore

             _lowerCamelCase				:  list[float]						=		[]  # x coordinates of points to plot
             _lowerCamelCase				:  list[float]						=		[]  # y coordinates of points to plot

             _lowerCamelCase				:  List[Any]						=		0.0
             while t <= 1:
                    _lowerCamelCase				:  Tuple						=		self.bezier_curve_function(a__)
                    to_plot_x.append(value[0])
                    to_plot_y.append(value[1])
                    t += step_size

             _lowerCamelCase				:  List[Any]						=		[i[0] for i in self.list_of_points]
             _lowerCamelCase				:  Union[str, Any]						=		[i[1] for i in self.list_of_points]

             plt.plot(
                 a__   ,				a__   ,				color='''blue'''   ,				label='''Curve of Degree ''' + str(self.degree)   ,				)
             plt.scatter(a__   ,				a__   ,				color='''red'''   ,				label='''Control Points''')
             plt.legend()
             plt.show()


if __name__ == "__main__":
       import doctest

       doctest.testmod()

       BezierCurve([(1, 2), (3, 5)]).plot_curve()  # degree 1
       BezierCurve([(0, 0), (5, 5), (5, 0)]).plot_curve()  # degree 2
       BezierCurve([(0, 0), (5, 5), (5, 0), (2.5, -2.5)]).plot_curve()  # degree 3

