
'''simple docstring'''
from importlib import import_module

from .logging import get_logger


__lowerCAmelCase     							=       get_logger(__name__)


class 			_lowerCAmelCase    :







							'''simple docstring'''

							def __init__(self  ,  UpperCAmelCase  ,  UpperCAmelCase=None  )     ->   int:
														_snake_case   =  attrs or []
														if module is not None:
																					for key in module.__dict__:
																												if key in attrs or not key.startswith("""__"""  ):
																																			setattr(self  ,  lowerCAmelCase__  ,  getattr(lowerCAmelCase__  ,  lowerCAmelCase__  )  )
														_snake_case   =  module._original_module if isinstance(lowerCAmelCase__  ,  _PatchedModuleObj  ) else module


class 			_lowerCAmelCase    :







							'''simple docstring'''

							lowerCAmelCase_											=						[]

							def __init__(self  ,  UpperCAmelCase  ,  UpperCAmelCase  ,  UpperCAmelCase  ,  UpperCAmelCase=None  )     ->   List[Any]:
														_snake_case   =  obj
														_snake_case   =  target
														_snake_case   =  new
														_snake_case   =  target.split("""."""  )[0]
														_snake_case   =  {}
														_snake_case   =  attrs or []

							def __enter__(self  )     ->   Dict:
														_snake_case   =  self.target.split("""."""  )

														# Patch modules:
														# it's used to patch attributes of submodules like "os.path.join";
														# in this case we need to patch "os" and "os.path"

														for i in range(len(lowerCAmelCase__  )  ):
																					try:
																												_snake_case   =  import_module(""".""".join(submodules[: i + 1]  )  )
																					except ModuleNotFoundError:
																												continue
																					# We iterate over all the globals in self.obj in case we find "os" or "os.path"
																					for attr in self.obj.__dir__():
																												_snake_case   =  getattr(self.obj  ,  lowerCAmelCase__  )
																												# We don't check for the name of the global, but rather if its value *is* "os" or "os.path".
																												# This allows to patch renamed modules like "from os import path as ospath".
																												if obj_attr is submodule or (
																												    (isinstance(lowerCAmelCase__  ,  _PatchedModuleObj  ) and obj_attr._original_module is submodule)
																												):
																																			_snake_case   =  obj_attr
																																			# patch at top level
																																			setattr(self.obj  ,  lowerCAmelCase__  ,  _PatchedModuleObj(lowerCAmelCase__  ,  attrs=self.attrs  )  )
																																			_snake_case   =  getattr(self.obj  ,  lowerCAmelCase__  )
																																			# construct lower levels patches
																																			for key in submodules[i + 1 :]:
																																										setattr(lowerCAmelCase__  ,  lowerCAmelCase__  ,  _PatchedModuleObj(getattr(lowerCAmelCase__  ,  lowerCAmelCase__  ,  lowerCAmelCase__  )  ,  attrs=self.attrs  )  )
																																										_snake_case   =  getattr(lowerCAmelCase__  ,  lowerCAmelCase__  )
																																			# finally set the target attribute
																																			setattr(lowerCAmelCase__  ,  lowerCAmelCase__  ,  self.new  )

        # Patch attribute itself:
        # it's used for builtins like "open",
        # and also to patch "os.path.join" we may also need to patch "join"
        # itself if it was imported as "from os.path import join".

														if submodules:  # if it's an attribute of a submodule like "os.path.join"
																					try:
																												_snake_case   =  getattr(import_module(""".""".join(lowerCAmelCase__  )  )  ,  lowerCAmelCase__  )
																					except (AttributeError, ModuleNotFoundError):
																												return
																					# We iterate over all the globals in self.obj in case we find "os.path.join"
																					for attr in self.obj.__dir__():
																												# We don't check for the name of the global, but rather if its value *is* "os.path.join".
																												# This allows to patch renamed attributes like "from os.path import join as pjoin".
																												if getattr(self.obj  ,  lowerCAmelCase__  ) is attr_value:
																																			_snake_case   =  getattr(self.obj  ,  lowerCAmelCase__  )
																																			setattr(self.obj  ,  lowerCAmelCase__  ,  self.new  )
														elif target_attr in globals()["__builtins__"]:  # if it'a s builtin like "open"
																					_snake_case   =  globals()['''__builtins__'''][target_attr]
																					setattr(self.obj  ,  lowerCAmelCase__  ,  self.new  )
														else:
																					raise RuntimeError(f"""Tried to patch attribute {target_attr} instead of a submodule."""  )

							def __exit__(self  ,  *UpperCAmelCase  )     ->   Optional[int]:
														for attr in list(self.original  ):
																					setattr(self.obj  ,  lowerCAmelCase__  ,  self.original.pop(lowerCAmelCase__  )  )

							def        lowercase							(self  )     ->   List[Any]:
														self.__enter__()
														self._active_patches.append(self  )





							def        lowercase							(self  )     ->   int:
														try:
																					self._active_patches.remove(self  )
														except ValueError:
																					# If the patch hasn't been started this will fail
																					return None

														return self.__exit__()



from __future__ import annotations

import bisect


def        _UpperCamelCase							(      lowercase__    ,       lowercase__    ,       lowercase__ = 0    ,       lowercase__ = -1      ):
						if hi < 0:
												__SCREAMING_SNAKE_CASE						:     Union[str, Any]					=		len(lowercase__      )

						while lo < hi:
												__SCREAMING_SNAKE_CASE						:     Any					=		lo + (hi - lo) // 2
												if sorted_collection[mid] < item:
																		__SCREAMING_SNAKE_CASE						:     Union[str, Any]					=		mid + 1
												else:
																		__SCREAMING_SNAKE_CASE						:     Optional[Any]					=		mid

						return lo


def        _UpperCamelCase							(      lowercase__    ,       lowercase__    ,       lowercase__ = 0    ,       lowercase__ = -1      ):
						if hi < 0:
												__SCREAMING_SNAKE_CASE						:     List[Any]					=		len(lowercase__      )

						while lo < hi:
												__SCREAMING_SNAKE_CASE						:     Optional[int]					=		lo + (hi - lo) // 2
												if sorted_collection[mid] <= item:
																		__SCREAMING_SNAKE_CASE						:     Any					=		mid + 1
												else:
																		__SCREAMING_SNAKE_CASE						:     Optional[int]					=		mid

						return lo


def        _UpperCamelCase							(      lowercase__    ,       lowercase__    ,       lowercase__ = 0    ,       lowercase__ = -1      ):
						sorted_collection.insert(bisect_left(lowercase__    ,       lowercase__    ,       lowercase__    ,       lowercase__      )    ,       lowercase__      )


def        _UpperCamelCase							(      lowercase__    ,       lowercase__    ,       lowercase__ = 0    ,       lowercase__ = -1      ):
						sorted_collection.insert(bisect_right(lowercase__    ,       lowercase__    ,       lowercase__    ,       lowercase__      )    ,       lowercase__      )


def        _UpperCamelCase							(      lowercase__    ,       lowercase__      ):
						__SCREAMING_SNAKE_CASE						:     Any					=		0
						__SCREAMING_SNAKE_CASE						:     List[Any]					=		len(lowercase__      ) - 1

						while left <= right:
												__SCREAMING_SNAKE_CASE						:     str					=		left + (right - left) // 2
												__SCREAMING_SNAKE_CASE						:     List[str]					=		sorted_collection[midpoint]
												if current_item == item:
																		return midpoint
												elif item < current_item:
																		__SCREAMING_SNAKE_CASE						:     int					=		midpoint - 1
												else:
																		__SCREAMING_SNAKE_CASE						:     Dict					=		midpoint + 1
						return None


def        _UpperCamelCase							(      lowercase__    ,       lowercase__      ):
						__SCREAMING_SNAKE_CASE						:     Union[str, Any]					=		bisect.bisect_left(lowercase__    ,       lowercase__      )
						if index != len(lowercase__      ) and sorted_collection[index] == item:
												return index
						return None


def        _UpperCamelCase							(      lowercase__    ,       lowercase__    ,       lowercase__    ,       lowercase__      ):
						if right < left:
												return None

						__SCREAMING_SNAKE_CASE						:     int					=		left + (right - left) // 2

						if sorted_collection[midpoint] == item:
												return midpoint
						elif sorted_collection[midpoint] > item:
												return binary_search_by_recursion(lowercase__    ,       lowercase__    ,       lowercase__    ,       midpoint - 1      )
						else:
												return binary_search_by_recursion(lowercase__    ,       lowercase__    ,       midpoint + 1    ,       lowercase__      )


if __name__ == "__main__":
						__lowerCAmelCase	: Dict  				=input('Enter numbers separated by comma:\n').strip()
						__lowerCAmelCase	: str  				=sorted(int(item) for item in user_input.split(','))
						__lowerCAmelCase	: Tuple  				=int(input('Enter a single number to be found in the list:\n'))
						__lowerCAmelCase	: Tuple  				=binary_search(collection, target)
						if result is None:
												print(f"""{target} was not found in {collection}.""")
						else:
												print(f"""{target} was found at position {result} in {collection}.""")
