




'''simple docstring'''


import timeit

import numpy as np

import datasets
from datasets.arrow_writer import ArrowWriter
from datasets.features.features import _ArrayXD






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




   def wrapper(*lowercase							: Union[str, Any]					,  **lowercase							: Dict    ):
      lowercase__       							=							timeit.default_timer()
      lowercase__       							=							func(*_lowerCAmelCase					,  **_lowerCAmelCase    )
      lowercase__       							=							timeit.default_timer() - starttime
      return delta

   lowercase__       							=							func.__name__

   return wrapper






def 		_lowerCAmelCase							(   lowercase							: Union[str, Any]					,  lowercase							: Any=1_0_0					,  lowercase							: List[str]=None    )			->Tuple:
   """simple docstring"""




   lowercase__       							=							[]
   lowercase__       							=							seq_shapes or {}
   for i in range(_lowerCAmelCase    ):
      lowercase__       							=							{}
      for col_id, (k, v) in enumerate(features.items()    ):
         if isinstance(_lowerCAmelCase					,  _ArrayXD    ):
            lowercase__       							=							np.random.rand(*v.shape    ).astype(v.dtype    )
         elif isinstance(_lowerCAmelCase					,  datasets.Value    ):
            if v.dtype == "string":
               lowercase__       							=							"The small grey turtle was surprisingly fast when challenged."
            else:
               lowercase__       							=							np.random.randint(1_0					,  size=1    ).astype(v.dtype    ).item()
         elif isinstance(_lowerCAmelCase					,  datasets.Sequence    ):
            while isinstance(_lowerCAmelCase					,  datasets.Sequence    ):
               lowercase__       							=							v.feature
            lowercase__       							=							seq_shapes[k]
            lowercase__       							=							np.random.rand(*_lowerCAmelCase    ).astype(v.dtype    )
         lowercase__       							=							data

      dummy_data.append((i, example)    )

   return dummy_data






def 		_lowerCAmelCase							(   lowercase							: Dict					,  lowercase							: Any					,  lowercase							: str=1_0_0					,  lowercase							: Optional[Any]=None    )			->Optional[Any]:
   """simple docstring"""




   lowercase__       							=							generate_examples(_lowerCAmelCase					,  num_examples=_lowerCAmelCase					,  seq_shapes=_lowerCAmelCase    )

   with ArrowWriter(features=_lowerCAmelCase					,  path=_lowerCAmelCase    ) as writer:
      for key, record in dummy_data:
         lowercase__       							=							features.encode_example(_lowerCAmelCase    )
         writer.write(_lowerCAmelCase    )

      lowercase__       							=							writer.finalize()

   if not num_final_examples == num_examples:
      raise ValueError(
          F'''Error writing the dataset, wrote {num_final_examples} examples but should have written {num_examples}.'''    )

   lowercase__       							=							datasets.Dataset.from_file(filename=_lowerCAmelCase					,  info=datasets.DatasetInfo(features=_lowerCAmelCase    )    )

   return dataset











import numpy as np
import qiskit



def 						A_							(	_lowerCAmelCase = 8				,  _lowerCAmelCase = None	)		->					str:
 UpperCamelCase      :   Tuple			      =  np.random.default_rng(seed=_lowerCAmelCase	)

 # Roughly 25% of the qubits will contribute to the key.
 # So we take more than we need.
 UpperCamelCase      :   List[str]			      =  6 * key_len
 # Measurement basis for Alice's qubits.
 UpperCamelCase      :   List[Any]			      =  rng.integers(2				,  size=_lowerCAmelCase	)
 # The set of states Alice will prepare.
 UpperCamelCase      :   List[Any]			      =  rng.integers(2				,  size=_lowerCAmelCase	)
 # Measurement basis for Bob's qubits.
 UpperCamelCase      :   Optional[int]			      =  rng.integers(2				,  size=_lowerCAmelCase	)

 # Quantum Circuit to simulate BB84
 UpperCamelCase      :   List[Any]			      =  qiskit.QuantumCircuit(_lowerCAmelCase				,  name="BB84"	)

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

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

 bbaa_circ.barrier()
 bbaa_circ.measure_all()

 # Simulate the quantum circuit.
 UpperCamelCase      :   Union[str, Any]			      =  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.
 UpperCamelCase      :   Tuple			      =  qiskit.execute(_lowerCAmelCase				,  _lowerCAmelCase				,  shots=1				,  seed_simulator=_lowerCAmelCase	)
 # Returns the result of measurement.
 UpperCamelCase      :   Optional[Any]			      =  job.result().get_counts(_lowerCAmelCase	).most_frequent()

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

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


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

    testmod()
