






from __future__ import annotations

from collections.abc import Iterator
from typing import Any





class 					A__     :

     '''simple docstring'''






     def __init__( self      :    Union[str, Any]   ,						_SCREAMING_SNAKE_CASE      :    Any ):






           """simple docstring"""




           UpperCamelCase					       =  data
           UpperCamelCase					       =  None





class 					A__     :

     '''simple docstring'''






     def __init__( self      :    Optional[int] ):






           """simple docstring"""




           UpperCamelCase					       =  None
           UpperCamelCase					       =  None







     def __iter__( self      :    Optional[int] ):






           """simple docstring"""




           UpperCamelCase					       =  self.head
           while self.head:
                 yield node.data
                 UpperCamelCase					       =  node.next
                 if node == self.head:
                       break







     def __len__( self      :    Tuple ):






           """simple docstring"""




           return sum(1 for _ in self )







     def __repr__( self      :    str ):






           """simple docstring"""




           return "->".join(str(_SCREAMING_SNAKE_CASE ) for item in iter(self ) )







     def   _SCREAMING_SNAKE_CASE     ( self      :    Optional[int]   ,						_SCREAMING_SNAKE_CASE      :    Any ):






           """simple docstring"""




           self.insert_nth(len(self )   ,						_SCREAMING_SNAKE_CASE )







     def   _SCREAMING_SNAKE_CASE     ( self      :    Dict   ,						_SCREAMING_SNAKE_CASE      :    Any ):






           """simple docstring"""




           self.insert_nth(0   ,						_SCREAMING_SNAKE_CASE )







     def   _SCREAMING_SNAKE_CASE     ( self      :    Optional[Any]   ,						_SCREAMING_SNAKE_CASE      :    int   ,						_SCREAMING_SNAKE_CASE      :    Any ):






           """simple docstring"""




           if index < 0 or index > len(self ):
                 raise IndexError('list index out of range.' )
           UpperCamelCase					       =  Node(_SCREAMING_SNAKE_CASE )
           if self.head is None:
                 UpperCamelCase					       =  new_node  # first node points itself
                 UpperCamelCase					       =  UpperCamelCase					       =  new_node
           elif index == 0:  # insert at head
                 UpperCamelCase					       =  self.head
                 UpperCamelCase					       =  UpperCamelCase					       =  new_node
           else:
                 UpperCamelCase					       =  self.head
                 for _ in range(index - 1 ):
                       UpperCamelCase					       =  temp.next
                 UpperCamelCase					       =  temp.next
                 UpperCamelCase					       =  new_node
                 if index == len(self ) - 1:  # insert at tail
                       UpperCamelCase					       =  new_node







     def   _SCREAMING_SNAKE_CASE     ( self      :    Any ):






           """simple docstring"""




           return self.delete_nth(0 )







     def   _SCREAMING_SNAKE_CASE     ( self      :    Optional[Any] ):






           """simple docstring"""




           return self.delete_nth(len(self ) - 1 )







     def   _SCREAMING_SNAKE_CASE     ( self      :    int   ,						_SCREAMING_SNAKE_CASE      :    int = 0 ):






           """simple docstring"""




           if not 0 <= index < len(self ):
                 raise IndexError('list index out of range.' )
           UpperCamelCase					       =  self.head
           if self.head == self.tail:  # just one node
                 UpperCamelCase					       =  UpperCamelCase					       =  None
           elif index == 0:  # delete head node
                 UpperCamelCase					       =  self.tail.next.next
                 UpperCamelCase					       =  self.head.next
           else:
                 UpperCamelCase					       =  self.head
                 for _ in range(index - 1 ):
                       UpperCamelCase					       =  temp.next
                 UpperCamelCase					       =  temp.next
                 UpperCamelCase					       =  temp.next.next
                 if index == len(self ) - 1:  # delete at tail
                       UpperCamelCase					       =  temp
           return delete_node.data







     def   _SCREAMING_SNAKE_CASE     ( self      :    int ):






           """simple docstring"""




           return len(self ) == 0

def 		lowercase__  (				) ->			Union[str, Any]:
      """simple docstring"""

      UpperCamelCase					       =  CircularLinkedList()
      assert len(lowerCamelCase_) == 0
      assert circular_linked_list.is_empty() is True
      assert str(lowerCamelCase_) == ""

      try:
            circular_linked_list.delete_front()
            raise AssertionError  # This should not happen
      except IndexError:
            assert True  # This should happen

      try:
            circular_linked_list.delete_tail()
            raise AssertionError  # This should not happen
      except IndexError:
            assert True  # This should happen

      try:
            circular_linked_list.delete_nth(-1)
            raise AssertionError
      except IndexError:
            assert True

      try:
            circular_linked_list.delete_nth(0)
            raise AssertionError
      except IndexError:
            assert True

      assert circular_linked_list.is_empty() is True
      for i in range(5):
            assert len(lowerCamelCase_) == i
            circular_linked_list.insert_nth(lowerCamelCase_       ,							i + 1)
      assert str(lowerCamelCase_) == "->".join(str(lowerCamelCase_) for i in range(1       ,							6))

      circular_linked_list.insert_tail(6)
      assert str(lowerCamelCase_) == "->".join(str(lowerCamelCase_) for i in range(1       ,							7))
      circular_linked_list.insert_head(0)
      assert str(lowerCamelCase_) == "->".join(str(lowerCamelCase_) for i in range(0       ,							7))

      assert circular_linked_list.delete_front() == 0
      assert circular_linked_list.delete_tail() == 6
      assert str(lowerCamelCase_) == "->".join(str(lowerCamelCase_) for i in range(1       ,							6))
      assert circular_linked_list.delete_nth(2) == 3

      circular_linked_list.insert_nth(2       ,							3)
      assert str(lowerCamelCase_) == "->".join(str(lowerCamelCase_) for i in range(1       ,							6))

      assert circular_linked_list.is_empty() is False


if __name__ == "__main__":
       import doctest

       doctest.testmod()











import numpy as np

import datasets


A__      :     int       =					'\nCompute the Mahalanobis Distance\n\nMahalonobis distance is the distance between a point and a distribution.\nAnd not between two distinct points. It is effectively a multivariate equivalent of the Euclidean distance.\nIt was introduced by Prof. P. C. Mahalanobis in 1936\nand has been used in various statistical applications ever since\n[source: https://www.machinelearningplus.com/statistics/mahalanobis-distance/]\n'

A__      :     Optional[int]       =					'\\n@article{de2000mahalanobis,\n  title={The mahalanobis distance},\n  author={De Maesschalck, Roy and Jouan-Rimbaud, Delphine and Massart, D{\'e}sir{\'e} L},\n  journal={Chemometrics and intelligent laboratory systems},\n  volume={50},\n  number={1},\n  pages={1--18},\n  year={2000},\n  publisher={Elsevier}\n}\n'

A__      :     Optional[int]       =					'\nArgs:\n    X: List of datapoints to be compared with the `reference_distribution`.\n    reference_distribution: List of datapoints from the reference distribution we want to compare to.\nReturns:\n    mahalanobis: The Mahalonobis distance for each datapoint in `X`.\nExamples:\n\n    >>> mahalanobis_metric = datasets.load_metric("mahalanobis")\n    >>> results = mahalanobis_metric.compute(reference_distribution=[[0, 1], [1, 0]], X=[[0, 1]])\n    >>> print(results)\n    {\'mahalanobis\': array([0.5])}\n'
@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION						,_KWARGS_DESCRIPTION      )
class  _UpperCAmelCase   (			datasets.Metric      ):

				"""simple docstring"""




				def 							lowercase__  (	self		:       str    ):

								'''simple docstring'''
								return datasets.MetricInfo(
								    description=_DESCRIPTION,    citation=_CITATION,    inputs_description=_KWARGS_DESCRIPTION,    features=datasets.Features(
								        {
								            '''X''': datasets.Sequence(datasets.Value('''float''',    id='''sequence'''    ),    id='''X'''    ),
								        }    ),    )




				def 							lowercase__  (	self		:       Dict,    lowerCamelCase		:       int,    lowerCamelCase		:       Optional[int]    ):

								'''simple docstring'''
								# convert to numpy arrays
								lowercase__  					=     np.array(lowerCamelCase    )
								lowercase__  					=     np.array(lowerCamelCase    )

								# Assert that arrays are 2D
								if len(X.shape    ) != 2:
												raise ValueError('''Expected `X` to be a 2D vector'''    )
								if len(reference_distribution.shape    ) != 2:
												raise ValueError('''Expected `reference_distribution` to be a 2D vector'''    )
								if reference_distribution.shape[0] < 2:
												raise ValueError(
												    '''Expected `reference_distribution` to be a 2D vector with more than one element in the first dimension'''    )

								# Get mahalanobis distance for each prediction
								lowercase__  					=     X - np.mean(lowerCamelCase    )
								lowercase__  					=     np.cov(reference_distribution.T    )
								try:
												lowercase__  					=     np.linalg.inv(lowerCamelCase    )
								except np.linalg.LinAlgError:
												lowercase__  					=     np.linalg.pinv(lowerCamelCase    )
								lowercase__  					=     np.dot(lowerCamelCase,    lowerCamelCase    )
								lowercase__  					=     np.dot(lowerCamelCase,    X_minus_mu.T    ).diagonal()

								return {"mahalanobis": mahal_dist}




