






'''simple docstring'''


import os
import tempfile
from functools import partial
from unittest import TestCase
from unittest.mock import patch

import numpy as np
import pytest

from datasets.arrow_dataset import Dataset
from datasets.search import ElasticSearchIndex, FaissIndex, MissingIndex

from .utils import require_elasticsearch, require_faiss


lowerCamelCase_				: str    	=							pytest.mark.integration
@require_faiss
class    _SCREAMING_SNAKE_CASE							(		__lowerCamelCase	):


			'''simple docstring'''





			def 				A      (   self							:						int			)							->    List[str]:

									'''simple docstring'''







									UpperCamelCase__         = Dataset.from_dict({"""filename""": ["""my_name-train""" + """_""" + str(a_			) for x in np.arange(3_0			).tolist()]}			)
									return dset






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

									'''simple docstring'''







									import faiss

									UpperCamelCase__         = self._create_dummy_dataset()
									UpperCamelCase__         = dset.map(
									    lambda lowercase ,      lowercase			: {"vecs": i * np.ones(5 ,      dtype=np.floataa			)} ,      with_indices=a_ ,      keep_in_memory=a_			)
									UpperCamelCase__         = dset.add_faiss_index("""vecs""" ,      batch_size=1_0_0 ,      metric_type=faiss.METRIC_INNER_PRODUCT			)
									UpperCamelCase__         = dset.get_nearest_examples("""vecs""" ,      np.ones(5 ,      dtype=np.floataa			)			)
									self.assertEqual(examples["""filename"""][0] ,      """my_name-train_29"""			)
									dset.drop_index("""vecs"""			)






			def 				A      (   self							:						Dict			)							->    Any:

									'''simple docstring'''







									import faiss

									UpperCamelCase__         = self._create_dummy_dataset()
									dset.add_faiss_index_from_external_arrays(
									    external_arrays=np.ones((3_0, 5)			) * np.arange(3_0			).reshape(-1 ,      1			) ,      index_name="""vecs""" ,      batch_size=1_0_0 ,      metric_type=faiss.METRIC_INNER_PRODUCT ,      )
									UpperCamelCase__         = dset.get_nearest_examples("""vecs""" ,      np.ones(5 ,      dtype=np.floataa			)			)
									self.assertEqual(examples["""filename"""][0] ,      """my_name-train_29"""			)






			def 				A      (   self							:						Dict			)							->    Any:

									'''simple docstring'''







									import faiss

									UpperCamelCase__         = self._create_dummy_dataset()
									dset.add_faiss_index_from_external_arrays(
									    external_arrays=np.ones((3_0, 5)			) * np.arange(3_0			).reshape(-1 ,      1			) ,      index_name="""vecs""" ,      metric_type=faiss.METRIC_INNER_PRODUCT ,      )

									# Setting delete=False and unlinking manually is not pretty... but it is required on Windows to
									# ensure somewhat stable behaviour. If we don't, we get PermissionErrors. This is an age-old issue.
									# see https://bugs.python.org/issue14243 and
									# https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file/23212515
									with tempfile.NamedTemporaryFile(delete=a_			) as tmp_file:
															dset.save_faiss_index("""vecs""" ,      tmp_file.name			)
															dset.load_faiss_index("""vecs2""" ,      tmp_file.name			)
									os.unlink(tmp_file.name			)

									UpperCamelCase__         = dset.get_nearest_examples("""vecs2""" ,      np.ones(5 ,      dtype=np.floataa			)			)
									self.assertEqual(examples["""filename"""][0] ,      """my_name-train_29"""			)






			def 				A      (   self							:						Any			)							->    Dict:

									'''simple docstring'''







									UpperCamelCase__         = self._create_dummy_dataset()
									dset.add_faiss_index_from_external_arrays(
									    external_arrays=np.ones((3_0, 5)			) * np.arange(3_0			).reshape(-1 ,      1			) ,      index_name="""vecs"""			)
									dset.drop_index("""vecs"""			)
									self.assertRaises(a_ ,      partial(dset.get_nearest_examples ,      """vecs2""" ,      np.ones(5 ,      dtype=np.floataa			)			)			)







			def 				A      (   self							:						Optional[Any]			)							->    List[Any]:

									'''simple docstring'''







									from elasticsearch import Elasticsearch

									UpperCamelCase__         = self._create_dummy_dataset()
									with patch("""elasticsearch.Elasticsearch.search"""			) as mocked_search, patch(
									    """elasticsearch.client.IndicesClient.create"""			) as mocked_index_create, patch("""elasticsearch.helpers.streaming_bulk"""			) as mocked_bulk:
															UpperCamelCase__         = {"acknowledged": True}
															mocked_bulk.return_value([(True, None)] * 3_0			)
															UpperCamelCase__         = {"hits": {"hits": [{"_score": 1, "_id": 2_9}]}}
															UpperCamelCase__         = Elasticsearch()

															dset.add_elasticsearch_index("""filename""" ,      es_client=a_			)
															UpperCamelCase__         = dset.get_nearest_examples("""filename""" ,      """my_name-train_29"""			)
															self.assertEqual(examples["""filename"""][0] ,      """my_name-train_29"""			)
@require_faiss
class    _SCREAMING_SNAKE_CASE							(		__lowerCamelCase	):


			'''simple docstring'''





			def 				A      (   self							:						str			)							->    List[Any]:

									'''simple docstring'''







									import faiss

									UpperCamelCase__         = FaissIndex(metric_type=faiss.METRIC_INNER_PRODUCT			)

									# add vectors
									index.add_vectors(np.eye(5 ,      dtype=np.floataa			)			)
									self.assertIsNotNone(index.faiss_index			)
									self.assertEqual(index.faiss_index.ntotal ,      5			)
									index.add_vectors(np.zeros((5, 5) ,      dtype=np.floataa			)			)
									self.assertEqual(index.faiss_index.ntotal ,      1_0			)

									# single query
									UpperCamelCase__         = np.zeros(5 ,      dtype=np.floataa			)
									UpperCamelCase__         = 1
									UpperCamelCase__         = index.search(a_			)
									self.assertRaises(a_ ,      index.search ,      query.reshape(-1 ,      1			)			)
									self.assertGreater(scores[0] ,      0			)
									self.assertEqual(indices[0] ,      1			)

									# batched queries
									UpperCamelCase__         = np.eye(5 ,      dtype=np.floataa			)[::-1]
									UpperCamelCase__         = index.search_batch(a_			)
									self.assertRaises(a_ ,      index.search_batch ,      queries[0]			)
									UpperCamelCase__         = [scores[0] for scores in total_scores]
									UpperCamelCase__         = [indices[0] for indices in total_indices]
									self.assertGreater(np.min(a_			) ,      0			)
									self.assertListEqual([4, 3, 2, 1, 0] ,      a_			)






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

									'''simple docstring'''







									import faiss

									UpperCamelCase__         = FaissIndex(string_factory="""Flat"""			)
									index.add_vectors(np.eye(5 ,      dtype=np.floataa			)			)
									self.assertIsInstance(index.faiss_index ,      faiss.IndexFlat			)
									UpperCamelCase__         = FaissIndex(string_factory="""LSH"""			)
									index.add_vectors(np.eye(5 ,      dtype=np.floataa			)			)
									self.assertIsInstance(index.faiss_index ,      faiss.IndexLSH			)
									with self.assertRaises(a_			):
															UpperCamelCase__         = FaissIndex(string_factory="""Flat""" ,      custom_index=faiss.IndexFlat(5			)			)






			def 				A      (   self							:						Optional[int]			)							->    Dict:

									'''simple docstring'''







									import faiss

									UpperCamelCase__         = faiss.IndexFlat(5			)
									UpperCamelCase__         = FaissIndex(custom_index=a_			)
									index.add_vectors(np.eye(5 ,      dtype=np.floataa			)			)
									self.assertIsInstance(index.faiss_index ,      faiss.IndexFlat			)







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

									'''simple docstring'''







									import faiss

									UpperCamelCase__         = FaissIndex(metric_type=faiss.METRIC_INNER_PRODUCT			)
									index.add_vectors(np.eye(5 ,      dtype=np.floataa			)			)

									# Setting delete=False and unlinking manually is not pretty... but it is required on Windows to
									# ensure somewhat stable behaviour. If we don't, we get PermissionErrors. This is an age-old issue.
									# see https://bugs.python.org/issue14243 and
									# https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file/23212515
									with tempfile.NamedTemporaryFile(delete=a_			) as tmp_file:
															index.save(tmp_file.name			)
															UpperCamelCase__         = FaissIndex.load(tmp_file.name			)
									os.unlink(tmp_file.name			)

									UpperCamelCase__         = np.zeros(5 ,      dtype=np.floataa			)
									UpperCamelCase__         = 1
									UpperCamelCase__         = index.search(a_			)
									self.assertGreater(scores[0] ,      0			)
									self.assertEqual(indices[0] ,      1			)







@require_faiss
def 	__magic_name__( _A					):
						'''simple docstring'''





						import faiss

						UpperCamelCase__         = FaissIndex(metric_type=faiss.METRIC_INNER_PRODUCT					)
						index.add_vectors(np.eye(5						,      dtype=np.floataa					)					)

						UpperCamelCase__         = "index.faiss"
						UpperCamelCase__         = f"mock://{index_name}"
						index.save(lowerCAmelCase_						,      storage_options=mockfs.storage_options					)
						UpperCamelCase__         = FaissIndex.load(lowerCAmelCase_						,      storage_options=mockfs.storage_options					)

						UpperCamelCase__         = np.zeros(5						,      dtype=np.floataa					)
						UpperCamelCase__         = 1
						UpperCamelCase__         = index.search(lowerCAmelCase_					)
						assert scores[0] > 0
						assert indices[0] == 1







@require_elasticsearch
class    _SCREAMING_SNAKE_CASE							(		__lowerCamelCase	):


			'''simple docstring'''





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

									'''simple docstring'''







									from elasticsearch import Elasticsearch

									with patch("""elasticsearch.Elasticsearch.search"""			) as mocked_search, patch(
									    """elasticsearch.client.IndicesClient.create"""			) as mocked_index_create, patch("""elasticsearch.helpers.streaming_bulk"""			) as mocked_bulk:
															UpperCamelCase__         = Elasticsearch()
															UpperCamelCase__         = {"acknowledged": True}
															UpperCamelCase__         = ElasticSearchIndex(es_client=a_			)
															mocked_bulk.return_value([(True, None)] * 3			)
															index.add_documents(["""foo""", """bar""", """foobar"""]			)

															# single query
															UpperCamelCase__         = "foo"
															UpperCamelCase__         = {"hits": {"hits": [{"_score": 1, "_id": 0}]}}
															UpperCamelCase__         = index.search(a_			)
															self.assertEqual(scores[0] ,      1			)
															self.assertEqual(indices[0] ,      0			)

															# single query with timeout
															UpperCamelCase__         = "foo"
															UpperCamelCase__         = {"hits": {"hits": [{"_score": 1, "_id": 0}]}}
															UpperCamelCase__         = index.search(a_ ,      request_timeout=3_0			)
															self.assertEqual(scores[0] ,      1			)
															self.assertEqual(indices[0] ,      0			)

															# batched queries
															UpperCamelCase__         = ["foo", "bar", "foobar"]
															UpperCamelCase__         = {"hits": {"hits": [{"_score": 1, "_id": 1}]}}
															UpperCamelCase__         = index.search_batch(a_			)
															UpperCamelCase__         = [scores[0] for scores in total_scores]
															UpperCamelCase__         = [indices[0] for indices in total_indices]
															self.assertGreater(np.min(a_			) ,      0			)
															self.assertListEqual([1, 1, 1] ,      a_			)

															# batched queries with timeout
															UpperCamelCase__         = ["foo", "bar", "foobar"]
															UpperCamelCase__         = {"hits": {"hits": [{"_score": 1, "_id": 1}]}}
															UpperCamelCase__         = index.search_batch(a_ ,      request_timeout=3_0			)
															UpperCamelCase__         = [scores[0] for scores in total_scores]
															UpperCamelCase__         = [indices[0] for indices in total_indices]
															self.assertGreater(np.min(a_			) ,      0			)
															self.assertListEqual([1, 1, 1] ,      a_			)











'''simple docstring'''


from collections import defaultdict







def 	__magic_name__( _A					):
						'''simple docstring'''





						UpperCamelCase__         = 1
						UpperCamelCase__         = True
						for v in tree[start]:
												if v not in visited:
																		ret += dfs(_A					)
						if ret % 2 == 0:
												cuts.append(_A					)
						return ret







def 	__magic_name__( ):
						'''simple docstring'''





						dfs(1					)


if __name__ == "__main__":
					lowerCamelCase_	,     lowerCamelCase_				: int    	=							10, 9
					lowerCamelCase_				: int    	=							defaultdict(list)
					lowerCamelCase_				: dict[int, bool]    	=							{}
					lowerCamelCase_				: list[int]    	=							[]
					lowerCamelCase_				: Union[str, Any]    	=							0
					lowerCamelCase_				: Tuple    	=							[(2, 1), (3, 1), (4, 3), (5, 2), (6, 1), (7, 2), (8, 6), (9, 8), (10, 8)]
					for u, v in edges:
										tree[u].append(v)
										tree[v].append(u)
					even_tree()
					print(len(cuts) - 1)
