docs: def sample_following_dist(handle_iter, n, totalf):
      """Samples n passwords following the distribution from the handle
      @handle_iter is an iterator that gives (pw,f) @n is the total
      number of samle asked for @totalf is the total number of users,
      which is euqal to sum(f for pw,f in handle_iter)
      As, handle_iterator is an iterator and can only traverse once. 
  
      @totalf needs to be supplied to the funciton.
      @handle_iter must be sorted in decreasing order
  
      Returns, an array of @n tuples (id, pw) sampled from @handle_iter.
  
      """
      multiplier = 1.0
      if totalf == 1.0:
          multiplier = 1e8
          # print "WARNING!! I don't except probabilities"
  
      totalf = totalf * multiplier
      # print("# Population Size", totalf)
      A = gen_n_random_num(n, totalf, unique=False)
      A.sort(reverse=True)
      # Uniqueness check, non necessarily required, but not very
      # computationally intensive
      assert len(A) == n, "Not enough randomnumbers generated" \
                          "Requried {}, generated only {}".format(n, len(A))
      # if not all(A[i] != A[i-1] for i in range(1,n,1)):
      #     for i in range(1,n,1):
      #         if A[i] == A[i-1]:
      #             print i, A[i], A[i-1]
      j, sampled = 0, 0
      val = A.pop()
      # print(handle_iter)
      for w, f in handle_iter:
          j += f * multiplier
          while val < j:
              sampled += 1
              if sampled % 5000 == 0:
                  print("Sampled:", sampled)
              yield (val, w)
              if A:
                  val = A.pop()
              else:
                  val = -1
                  break
          if not A and val == -1:
              break
  
      # print("# Stopped at:", w, f, j, '\n', file=sys.stderr)
      while A and val < j:
          yield (val, w)
          if A:
              i, val = A.pop()
          else:
              break