





'''simple docstring'''




import numpy as np

from transformers import BatchFeature
from transformers.testing_utils import require_tf, require_torch

from .test_feature_extraction_common import FeatureExtractionSavingTestMixin


class 					SCREAMING_SNAKE_CASE       (a__				):
     # to overwrite at feature extractactor specific tests
     lowerCAmelCase						     =			None
     lowerCAmelCase						     =			None


     @property
     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          return self.feat_extract_tester.prepare_feat_extract_dict()


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					Tuple						=			self.feature_extraction_class(**self.feat_extract_dict)
          self.assertTrue(hasattr(_UpperCAmelCase		,      'feature_size'))
          self.assertTrue(hasattr(_UpperCAmelCase		,      'sampling_rate'))
          self.assertTrue(hasattr(_UpperCAmelCase		,      'padding_value'))


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					Any						=			self.feat_extract_tester.prepare_inputs_for_common()
          __A		:					Union[str, Any]						=			self.feature_extraction_class(**self.feat_extract_dict)
          __A		:					Optional[Any]						=			feat_extract.model_input_names[0]

          __A		:					Optional[Any]						=			BatchFeature({input_name: speech_inputs})

          self.assertTrue(all(len(_UpperCAmelCase) == len(_UpperCAmelCase) for x, y in zip(_UpperCAmelCase		,      processed_features[input_name])))

          __A		:					List[Any]						=			self.feat_extract_tester.prepare_inputs_for_common(equal_length=_UpperCAmelCase)
          __A		:					Optional[int]						=			BatchFeature({input_name: speech_inputs}		,      tensor_type='np')

          __A		:					Dict						=			processed_features[input_name]

          if len(batch_features_input.shape) < 3:
               __A		:					str						=			batch_features_input[:, :, None]

          self.assertTrue(
              batch_features_input.shape
              == (self.feat_extract_tester.batch_size, len(speech_inputs[0]), self.feat_extract_tester.feature_size))


     @require_torch
     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					int						=			self.feat_extract_tester.prepare_inputs_for_common(equal_length=_UpperCAmelCase)
          __A		:					Tuple						=			self.feature_extraction_class(**self.feat_extract_dict)
          __A		:					Dict						=			feat_extract.model_input_names[0]

          __A		:					Optional[Any]						=			BatchFeature({input_name: speech_inputs}		,      tensor_type='pt')

          __A		:					Tuple						=			processed_features[input_name]

          if len(batch_features_input.shape) < 3:
               __A		:					int						=			batch_features_input[:, :, None]

          self.assertTrue(
              batch_features_input.shape
              == (self.feat_extract_tester.batch_size, len(speech_inputs[0]), self.feat_extract_tester.feature_size))


     @require_tf
     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					Any						=			self.feat_extract_tester.prepare_inputs_for_common(equal_length=_UpperCAmelCase)
          __A		:					str						=			self.feature_extraction_class(**self.feat_extract_dict)
          __A		:					Dict						=			feat_extract.model_input_names[0]

          __A		:					int						=			BatchFeature({input_name: speech_inputs}		,      tensor_type='tf')

          __A		:					Tuple						=			processed_features[input_name]

          if len(batch_features_input.shape) < 3:
               __A		:					List[str]						=			batch_features_input[:, :, None]

          self.assertTrue(
              batch_features_input.shape
              == (self.feat_extract_tester.batch_size, len(speech_inputs[0]), self.feat_extract_tester.feature_size))


     def 				SCREAMING_SNAKE_CASE    (		self		,      _UpperCAmelCase=False):

          '''simple docstring'''






          def _inputs_have_equal_length(_UpperCAmelCase):
               __A		:					str						=			len(input[0])
               for input_slice in input[1:]:
                    if len(_UpperCAmelCase) != length:
                         return False
               return True

          def _inputs_are_equal(_UpperCAmelCase		,      _UpperCAmelCase):
               if len(_UpperCAmelCase) != len(_UpperCAmelCase):
                    return False

               for input_slice_a, input_slice_a in zip(_UpperCAmelCase		,      _UpperCAmelCase):
                    if not np.allclose(np.asarray(_UpperCAmelCase)		,      np.asarray(_UpperCAmelCase)		,      atol=1e-3):
                         return False
               return True

          __A		:					str						=			self.feature_extraction_class(**self.feat_extract_dict)
          __A		:					Union[str, Any]						=			self.feat_extract_tester.prepare_inputs_for_common(numpify=_UpperCAmelCase)
          __A		:					Optional[Any]						=			feat_extract.model_input_names[0]

          __A		:					Tuple						=			BatchFeature({input_name: speech_inputs})

          __A		:					str						=			self.feat_extract_tester.seq_length_diff
          __A		:					Tuple						=			self.feat_extract_tester.max_seq_length + pad_diff
          __A		:					Union[str, Any]						=			self.feat_extract_tester.min_seq_length
          __A		:					Union[str, Any]						=			self.feat_extract_tester.batch_size
          __A		:					Any						=			self.feat_extract_tester.feature_size

          # test padding for List[int] + numpy
          __A		:					str						=			feat_extract.pad(_UpperCAmelCase		,      padding=_UpperCAmelCase)
          __A		:					Optional[Any]						=			input_a[input_name]

          __A		:					List[Any]						=			feat_extract.pad(_UpperCAmelCase		,      padding='longest')
          __A		:					Optional[int]						=			input_a[input_name]

          __A		:					Optional[Any]						=			feat_extract.pad(_UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[-1]))
          __A		:					List[str]						=			input_a[input_name]

          __A		:					Tuple						=			feat_extract.pad(_UpperCAmelCase		,      padding='longest'		,      return_tensors='np')
          __A		:					List[str]						=			input_a[input_name]

          # max_length parameter has to be provided when setting `padding="max_length"`
          with self.assertRaises(_UpperCAmelCase):
               feat_extract.pad(_UpperCAmelCase		,      padding='max_length')[input_name]

          __A		:					Any						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=_UpperCAmelCase		,      return_tensors='np')
          __A		:					str						=			input_a[input_name]

          self.assertFalse(_inputs_have_equal_length(_UpperCAmelCase))
          self.assertTrue(_inputs_have_equal_length(_UpperCAmelCase))
          self.assertTrue(_inputs_have_equal_length(_UpperCAmelCase))
          self.assertTrue(_inputs_are_equal(_UpperCAmelCase		,      _UpperCAmelCase))
          self.assertTrue(len(input_a[0]) == pad_min_length)
          self.assertTrue(len(input_a[1]) == pad_min_length + pad_diff)
          self.assertTrue(input_a.shape[:2] == (batch_size, len(input_a[0])))
          self.assertTrue(input_a.shape[:2] == (batch_size, pad_max_length))

          if feature_size > 1:
               self.assertTrue(input_a.shape[2] == input_a.shape[2] == feature_size)

          # test padding for `pad_to_multiple_of` for List[int] + numpy
          __A		:					Dict						=			feat_extract.pad(_UpperCAmelCase		,      pad_to_multiple_of=10)
          __A		:					Optional[int]						=			input_a[input_name]

          __A		:					Any						=			feat_extract.pad(_UpperCAmelCase		,      padding='longest'		,      pad_to_multiple_of=10)
          __A		:					Optional[Any]						=			input_a[input_name]

          __A		:					List[str]						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      pad_to_multiple_of=10		,      max_length=_UpperCAmelCase)
          __A		:					Optional[int]						=			input_a[input_name]

          __A		:					Optional[Any]						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      pad_to_multiple_of=10		,      max_length=_UpperCAmelCase		,      return_tensors='np'		,      )
          __A		:					str						=			input_a[input_name]

          self.assertTrue(all(len(_UpperCAmelCase) % 10 == 0 for x in input_a))
          self.assertTrue(_inputs_are_equal(_UpperCAmelCase		,      _UpperCAmelCase))

          __A		:					List[str]						=			pad_max_length if pad_max_length % 10 == 0 else (pad_max_length // 10 + 1) * 10
          self.assertTrue(all(len(_UpperCAmelCase) == expected_mult_pad_length for x in input_a))
          self.assertEqual(input_a.shape[:2]		,      (batch_size, expected_mult_pad_length))

          if feature_size > 1:
               self.assertTrue(input_a.shape[2] == feature_size)

          # Check padding value is correct
          __A		:					int						=			(np.ones(self.feat_extract_tester.feature_size) * feat_extract.padding_value).sum()
          self.assertTrue(
              abs(np.asarray(input_a[0])[pad_min_length:].sum() - padding_vector_sum * (pad_max_length - pad_min_length))
              < 1e-3)
          self.assertTrue(
              abs(
                  np.asarray(input_a[1])[pad_min_length + pad_diff :].sum()
                  - padding_vector_sum * (pad_max_length - pad_min_length - pad_diff))
              < 1e-3)
          self.assertTrue(
              abs(
                  np.asarray(input_a[2])[pad_min_length + 2 * pad_diff :].sum()
                  - padding_vector_sum * (pad_max_length - pad_min_length - 2 * pad_diff))
              < 1e-3)
          self.assertTrue(
              abs(input_a[0, pad_min_length:].sum() - padding_vector_sum * (pad_max_length - pad_min_length)) < 1e-3)
          self.assertTrue(
              abs(input_a[0, pad_min_length:].sum() - padding_vector_sum * (expected_mult_pad_length - pad_min_length))
              < 1e-3)


     def 				SCREAMING_SNAKE_CASE    (		self		,      _UpperCAmelCase=False):

          '''simple docstring'''






          def _inputs_have_equal_length(_UpperCAmelCase):
               __A		:					Optional[Any]						=			len(input[0])
               for input_slice in input[1:]:
                    if len(_UpperCAmelCase) != length:
                         return False
               return True

          def _inputs_are_equal(_UpperCAmelCase		,      _UpperCAmelCase):
               if len(_UpperCAmelCase) != len(_UpperCAmelCase):
                    return False

               for input_slice_a, input_slice_a in zip(_UpperCAmelCase		,      _UpperCAmelCase):
                    if not np.allclose(np.asarray(_UpperCAmelCase)		,      np.asarray(_UpperCAmelCase)		,      atol=1e-3):
                         return False
               return True

          __A		:					str						=			self.feature_extraction_class(**self.feat_extract_dict)
          __A		:					Optional[Any]						=			self.feat_extract_tester.prepare_inputs_for_common(numpify=_UpperCAmelCase)
          __A		:					Optional[int]						=			feat_extract.model_input_names[0]

          __A		:					Union[str, Any]						=			BatchFeature({input_name: speech_inputs})

          # truncate to smallest
          __A		:					Tuple						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[0])		,      truncation=_UpperCAmelCase)
          __A		:					Tuple						=			input_a[input_name]

          __A		:					int						=			feat_extract.pad(_UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[0]))
          __A		:					int						=			input_a[input_name]

          self.assertTrue(_inputs_have_equal_length(_UpperCAmelCase))
          self.assertFalse(_inputs_have_equal_length(_UpperCAmelCase))

          # truncate to smallest with np
          __A		:					Tuple						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[0])		,      return_tensors='np'		,      truncation=_UpperCAmelCase		,      )
          __A		:					List[Any]						=			input_a[input_name]

          __A		:					Tuple						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[0])		,      return_tensors='np')
          __A		:					Any						=			input_a[input_name]

          self.assertTrue(_inputs_have_equal_length(_UpperCAmelCase))
          self.assertTrue(input_a.shape[1] == len(speech_inputs[0]))

          # since truncation forces padding to be smaller than longest input
          # function can't return `np.ndarray`, but has to return list
          self.assertFalse(_inputs_have_equal_length(_UpperCAmelCase))

          # truncate to middle
          __A		:					str						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[1])		,      truncation=_UpperCAmelCase		,      return_tensors='np'		,      )
          __A		:					List[str]						=			input_a[input_name]

          __A		:					Optional[Any]						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[1])		,      truncation=_UpperCAmelCase)
          __A		:					Any						=			input_a[input_name]

          __A		:					Any						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[1])		,      return_tensors='np')
          __A		:					Tuple						=			input_a[input_name]

          self.assertTrue(input_a.shape[1] == len(speech_inputs[1]))
          self.assertTrue(_inputs_have_equal_length(_UpperCAmelCase))
          self.assertTrue(_inputs_have_equal_length(_UpperCAmelCase))
          self.assertTrue(_inputs_are_equal(_UpperCAmelCase		,      _UpperCAmelCase))

          # since truncation forces padding to be smaller than longest input
          # function can't return `np.ndarray`, but has to return list
          self.assertFalse(_inputs_have_equal_length(_UpperCAmelCase))
          self.assertTrue(len(input_a[-1]) == len(speech_inputs[-1]))

          # padding has to be max_length when setting `truncation=True`
          with self.assertRaises(_UpperCAmelCase):
               feat_extract.pad(_UpperCAmelCase		,      truncation=_UpperCAmelCase)[input_name]

          # padding has to be max_length when setting `truncation=True`
          with self.assertRaises(_UpperCAmelCase):
               feat_extract.pad(_UpperCAmelCase		,      padding='longest'		,      truncation=_UpperCAmelCase)[input_name]

          # padding has to be max_length when setting `truncation=True`
          with self.assertRaises(_UpperCAmelCase):
               feat_extract.pad(_UpperCAmelCase		,      padding='longest'		,      truncation=_UpperCAmelCase)[input_name]

          # max_length parameter has to be provided when setting `truncation=True` and padding="max_length"
          with self.assertRaises(_UpperCAmelCase):
               feat_extract.pad(_UpperCAmelCase		,      padding='max_length'		,      truncation=_UpperCAmelCase)[input_name]

          # test truncation for `pad_to_multiple_of` for List[int] + numpy
          __A		:					int						=			12
          __A		:					Optional[Any]						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[0])		,      pad_to_multiple_of=_UpperCAmelCase		,      truncation=_UpperCAmelCase		,      )
          __A		:					str						=			input_a[input_name]

          __A		:					Union[str, Any]						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=len(speech_inputs[0])		,      pad_to_multiple_of=_UpperCAmelCase		,      )
          __A		:					Optional[Any]						=			input_a[input_name]

          # retrieve expected_length as multiple of pad_to_multiple_of
          __A		:					List[str]						=			len(speech_inputs[0])
          if expected_length % pad_to_multiple_of != 0:
               __A		:					Optional[Any]						=			((len(speech_inputs[0]) // pad_to_multiple_of) + 1) * pad_to_multiple_of

          self.assertTrue(len(input_a[0]) == expected_length)
          self.assertTrue(_inputs_have_equal_length(_UpperCAmelCase))
          self.assertFalse(_inputs_have_equal_length(_UpperCAmelCase))


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          self._check_padding(numpify=_UpperCAmelCase)


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          self._check_padding(numpify=_UpperCAmelCase)


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          self._check_truncation(numpify=_UpperCAmelCase)


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          self._check_truncation(numpify=_UpperCAmelCase)


     @require_torch
     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					List[Any]						=			self.feature_extraction_class(**self.feat_extract_dict)
          __A		:					int						=			self.feat_extract_tester.prepare_inputs_for_common()
          __A		:					Union[str, Any]						=			feat_extract.model_input_names[0]

          __A		:					str						=			BatchFeature({input_name: speech_inputs})

          __A		:					int						=			feat_extract.pad(_UpperCAmelCase		,      padding='longest'		,      return_tensors='np')[input_name]
          __A		:					Optional[int]						=			feat_extract.pad(_UpperCAmelCase		,      padding='longest'		,      return_tensors='pt')[input_name]

          self.assertTrue(abs(input_np.astype(np.floataa).sum() - input_pt.numpy().astype(np.floataa).sum()) < 1e-2)


     @require_tf
     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					Union[str, Any]						=			self.feature_extraction_class(**self.feat_extract_dict)
          __A		:					Tuple						=			self.feat_extract_tester.prepare_inputs_for_common()
          __A		:					Optional[Any]						=			feat_extract.model_input_names[0]

          __A		:					Union[str, Any]						=			BatchFeature({input_name: speech_inputs})

          __A		:					Optional[Any]						=			feat_extract.pad(_UpperCAmelCase		,      padding='longest'		,      return_tensors='np')[input_name]
          __A		:					str						=			feat_extract.pad(_UpperCAmelCase		,      padding='longest'		,      return_tensors='tf')[input_name]

          self.assertTrue(abs(input_np.astype(np.floataa).sum() - input_tf.numpy().astype(np.floataa).sum()) < 1e-2)


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					int						=			self.feat_extract_dict
          __A		:					List[str]						=			True
          __A		:					List[Any]						=			self.feature_extraction_class(**_UpperCAmelCase)
          __A		:					Optional[Any]						=			self.feat_extract_tester.prepare_inputs_for_common()
          __A		:					Optional[Any]						=			[len(_UpperCAmelCase) for x in speech_inputs]
          __A		:					Optional[Any]						=			feat_extract.model_input_names[0]

          __A		:					Optional[Any]						=			BatchFeature({input_name: speech_inputs})

          __A		:					List[str]						=			feat_extract.pad(_UpperCAmelCase		,      padding='longest'		,      return_tensors='np')
          self.assertIn('attention_mask'		,      _UpperCAmelCase)
          self.assertListEqual(list(processed.attention_mask.shape)		,      list(processed[input_name].shape[:2]))
          self.assertListEqual(processed.attention_mask.sum(-1).tolist()		,      _UpperCAmelCase)


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					List[str]						=			self.feat_extract_dict
          __A		:					Optional[int]						=			True
          __A		:					List[str]						=			self.feature_extraction_class(**_UpperCAmelCase)
          __A		:					Union[str, Any]						=			self.feat_extract_tester.prepare_inputs_for_common()
          __A		:					str						=			[len(_UpperCAmelCase) for x in speech_inputs]
          __A		:					Optional[Any]						=			feat_extract.model_input_names[0]

          __A		:					List[Any]						=			BatchFeature({input_name: speech_inputs})
          __A		:					Dict						=			min(_UpperCAmelCase)

          __A		:					List[str]						=			feat_extract.pad(
              _UpperCAmelCase		,      padding='max_length'		,      max_length=_UpperCAmelCase		,      truncation=_UpperCAmelCase		,      return_tensors='np')
          self.assertIn('attention_mask'		,      _UpperCAmelCase)
          self.assertListEqual(
              list(processed_pad.attention_mask.shape)		,      [processed_pad[input_name].shape[0], max_length])
          self.assertListEqual(
              processed_pad.attention_mask[:, :max_length].sum(-1).tolist()		,      [max_length for x in speech_inputs])






'''simple docstring'''




import mpmath  # for roots of unity
import numpy as np


class 					SCREAMING_SNAKE_CASE       :


     def __init__(		self		,      _UpperCAmelCase=None		,      _UpperCAmelCase=None):

          '''simple docstring'''






          __A		:					List[Any]						=			list(poly_a or [0])[:]
          __A		:					Optional[int]						=			list(poly_b or [0])[:]

          # Remove leading zero coefficients
          while self.polyA[-1] == 0:
               self.polyA.pop()
          __A		:					Union[str, Any]						=			len(self.polyA)

          while self.polyB[-1] == 0:
               self.polyB.pop()
          __A		:					Optional[int]						=			len(self.polyB)

          # Add 0 to make lengths equal a power of 2
          __A		:					Optional[Any]						=			int(
              2 ** np.ceil(np.loga(len(self.polyA) + len(self.polyB) - 1)))

          while len(self.polyA) < self.c_max_length:
               self.polyA.append(0)
          while len(self.polyB) < self.c_max_length:
               self.polyB.append(0)
          # A complex root used for the fourier transform
          __A		:					str						=			complex(mpmath.root(x=1		,      n=self.c_max_length		,      k=1))

          # The product
          __A		:					Tuple						=			self.__multiply()


     def 				SCREAMING_SNAKE_CASE    (		self		,      _UpperCAmelCase):

          '''simple docstring'''






          __A		:					Optional[int]						=			[[x] for x in self.polyA] if which == 'A' else [[x] for x in self.polyB]
          # Corner case
          if len(_UpperCAmelCase) <= 1:
               return dft[0]
          #
          __A		:					Dict						=			self.c_max_length // 2
          while next_ncol > 0:
               __A		:					Optional[Any]						=			[[] for i in range(_UpperCAmelCase)]
               __A		:					Tuple						=			self.root**next_ncol

               # First half of next step
               __A		:					Optional[Any]						=			1
               for j in range(self.c_max_length // (next_ncol * 2)):
                    for i in range(_UpperCAmelCase):
                         new_dft[i].append(dft[i][j] + current_root * dft[i + next_ncol][j])
                    current_root *= root
               # Second half of next step
               __A		:					List[str]						=			1
               for j in range(self.c_max_length // (next_ncol * 2)):
                    for i in range(_UpperCAmelCase):
                         new_dft[i].append(dft[i][j] - current_root * dft[i + next_ncol][j])
                    current_root *= root
               # Update
               __A		:					Optional[int]						=			new_dft
               __A		:					Tuple						=			next_ncol // 2
          return dft[0]


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					int						=			self.__dft('A')
          __A		:					Optional[Any]						=			self.__dft('B')
          __A		:					str						=			[[dft_a[i] * dft_b[i] for i in range(self.c_max_length)]]
          del dft_a
          del dft_b

          # Corner Case
          if len(inverce_c[0]) <= 1:
               return inverce_c[0]
          # Inverse DFT
          __A		:					Dict						=			2
          while next_ncol <= self.c_max_length:
               __A		:					Optional[int]						=			[[] for i in range(_UpperCAmelCase)]
               __A		:					Any						=			self.root ** (next_ncol // 2)
               __A		:					Tuple						=			1
               # First half of next step
               for j in range(self.c_max_length // next_ncol):
                    for i in range(next_ncol // 2):
                         # Even positions
                         new_inverse_c[i].append(
                             (
                                 inverce_c[i][j]
                                 + inverce_c[i][j + self.c_max_length // next_ncol]
                             )
                             / 2)
                         # Odd positions
                         new_inverse_c[i + next_ncol // 2].append(
                             (
                                 inverce_c[i][j]
                                 - inverce_c[i][j + self.c_max_length // next_ncol]
                             )
                             / (2 * current_root))
                    current_root *= root
               # Update
               __A		:					int						=			new_inverse_c
               next_ncol *= 2
          # Unpack
          __A		:					Optional[int]						=			[round(x[0].real		,      8) + round(x[0].imag		,      8) * 1j for x in inverce_c]

          # Remove leading 0's
          while inverce_c[-1] == 0:
               inverce_c.pop()
          return inverce_c


     def __str__(		self):

          '''simple docstring'''






          __A		:					int						=			'A = ' + ' + '.join(
              F'{coef}*x^{i}' for coef, i in enumerate(self.polyA[: self.len_A]))
          __A		:					Optional[Any]						=			'B = ' + ' + '.join(
              F'{coef}*x^{i}' for coef, i in enumerate(self.polyB[: self.len_B]))
          __A		:					str						=			'A*B = ' + ' + '.join(
              F'{coef}*x^{i}' for coef, i in enumerate(self.product))

          return F'{a}\n{b}\n{c}'


# Unit tests
if __name__ == "__main__":
  import doctest

  doctest.testmod()