code: def sample_assignment_probs(qubits, nsamples, cxn):
      
      num_qubits = len(qubits)
      dimension = 2 ** num_qubits
      hists = []
      preps = basis_state_preps(*qubits)
  
      jobs = []
      _log.info('Submitting jobs...')
      for jj, p in izip(TRANGE(dimension), preps):
          jobs.append(cxn.run_and_measure_async(p, qubits, nsamples))
  
      _log.info('Waiting for results...')
      for jj, job_id in izip(TRANGE(dimension), jobs):
          job = cxn.wait_for_job(job_id)
          results = job.result()
          idxs = list(map(bitlist_to_int, results))
          hists.append(make_histogram(idxs, dimension))
      return estimate_assignment_probs(hists)
docs: Sample the assignment probabilities of qubits using nsamples per measurement, and then compute
      the estimated assignment probability matrix. See the docstring for estimate_assignment_probs for
      more information.
  
      :param list qubits: Qubits to sample the assignment probabilities for.
      :param int nsamples: The number of samples to use in each measurement.
      :param QPUConnection|QVMConnection cxn: The Connection object to connect to Forest.
      :return: The assignment probability matrix.
      :rtype: numpy.ndarray