


"""simple docstring"""







import logging
import os

from .state import PartialState




class  UpperCamelCase_	( logging.LoggerAdapter):

	"""simple docstring"""





	@staticmethod
	def   UpperCAmelCase_      ( UpperCAmelCase__			:				Tuple   )       ->	str:
						__SCREAMING_SNAKE_CASE						   =				PartialState()
						return not main_process_only or (main_process_only and state.is_main_process)




	def   UpperCAmelCase_      ( self			:				Tuple			,			UpperCAmelCase__			:				Any			,			UpperCAmelCase__			:				Tuple			,			*UpperCAmelCase__			:				List[Any]			,			**UpperCAmelCase__			:				Dict   )       ->	Tuple:
						if PartialState._shared_state == {}:
											raise RuntimeError(
											    "You must initialize the accelerate state by calling either `PartialState()` or `Accelerator()` before using the logging utility."   )
						__SCREAMING_SNAKE_CASE						   =				kwargs.pop("main_process_only"			,			UpperCAmelCase__   )
						__SCREAMING_SNAKE_CASE						   =				kwargs.pop("in_order"			,			UpperCAmelCase__   )

						if self.isEnabledFor(UpperCAmelCase__   ):
											if self._should_log(UpperCAmelCase__   ):
																__SCREAMING_SNAKE_CASE   ,  __SCREAMING_SNAKE_CASE						   =				self.process(UpperCAmelCase__			,			UpperCAmelCase__   )
																self.logger.log(UpperCAmelCase__			,			UpperCAmelCase__			,			*UpperCAmelCase__			,			**UpperCAmelCase__   )

											elif in_order:
																__SCREAMING_SNAKE_CASE						   =				PartialState()
																for i in range(state.num_processes   ):
																					if i == state.process_index:
																										__SCREAMING_SNAKE_CASE   ,  __SCREAMING_SNAKE_CASE						   =				self.process(UpperCAmelCase__			,			UpperCAmelCase__   )
																										self.logger.log(UpperCAmelCase__			,			UpperCAmelCase__			,			*UpperCAmelCase__			,			**UpperCAmelCase__   )
																					state.wait_for_everyone()




def    UpperCAmelCase__       (lowerCAmelCase_  ,						lowerCAmelCase_ = None   ):




					'''simple docstring'''


					if log_level is None:
										__SCREAMING_SNAKE_CASE						   =				os.environ.get("ACCELERATE_LOG_LEVEL"  ,						lowerCAmelCase_   )
					__SCREAMING_SNAKE_CASE						   =				logging.getLogger(lowerCAmelCase_   )
					if log_level is not None:
										logger.setLevel(log_level.upper()   )
										logger.root.setLevel(log_level.upper()   )
					return MultiProcessAdapter(lowerCAmelCase_  ,						{}   )

'''simple docstring'''

import numpy as np
import qiskit







def      UpperCamelCase_						(					snake_case_       :       int = 8						,		snake_case_       :       int | None = None      )					->     str:






 '''simple docstring'''

 __lowerCAmelCase											=						np.random.default_rng(seed=snake_case_      )

 # Roughly 25% of the qubits will contribute to the key.
 # So we take more than we need.
 __lowerCAmelCase											=						6 * key_len
 # Measurement basis for Alice's qubits.
 __lowerCAmelCase											=						rng.integers(2						,		size=snake_case_      )
 # The set of states Alice will prepare.
 __lowerCAmelCase											=						rng.integers(2						,		size=snake_case_      )
 # Measurement basis for Bob's qubits.
 __lowerCAmelCase											=						rng.integers(2						,		size=snake_case_      )

 # Quantum Circuit to simulate BB84
 __lowerCAmelCase											=						qiskit.QuantumCircuit(snake_case_						,		name="""BB84"""      )

 # Alice prepares her qubits according to rules above.
 for index, _ in enumerate(snake_case_      ):
  if alice_state[index] == 1:
   bbaa_circ.x(snake_case_      )
  if alice_basis[index] == 1:
   bbaa_circ.h(snake_case_      )
 bbaa_circ.barrier()

 # Bob measures the received qubits according to rules above.
 for index, _ in enumerate(snake_case_      ):
  if bob_basis[index] == 1:
   bbaa_circ.h(snake_case_      )

 bbaa_circ.barrier()
 bbaa_circ.measure_all()

 # Simulate the quantum circuit.
 __lowerCAmelCase											=						qiskit.Aer.get_backend("""aer_simulator"""      )
 # We only need to run one shot because the key is unique.
 # Multiple shots will produce the same key.
 __lowerCAmelCase											=						qiskit.execute(snake_case_						,		snake_case_						,		shots=1						,		seed_simulator=snake_case_      )
 # Returns the result of measurement.
 __lowerCAmelCase											=						job.result().get_counts(snake_case_      ).most_frequent()

 # Extracting the generated key from the simulation results.
 # Only keep measurement results where Alice and Bob chose the same basis.
 __lowerCAmelCase											=						"""""".join(
     [
         result_bit
         for alice_basis_bit, bob_basis_bit, result_bit in zip(
             snake_case_						,		snake_case_						,		snake_case_      )
         if alice_basis_bit == bob_basis_bit
     ]      )

 # Get final key. Pad with 0 if too short, otherwise truncate.
 __lowerCAmelCase											=						gen_key[:key_len] if len(snake_case_      ) >= key_len else gen_key.ljust(snake_case_						,		"""0"""      )
 return key


if __name__ == "__main__":
 print(f'The generated key is : {bbaa(8, seed=0)}')
 from doctest import testmod

 testmod()






