code: def random_processor(M, N, L, qubit_yield, num_evil=0):
      
      # replacement for lambda in edge filter below that works with bot h
      def edge_filter(pq):
          # we have to unpack the (p,q) edge
          p, q = pq
          return q in qubits and p < q
  
      qubits = [(x, y, u, k) for x in range(M) for y in range(N) for u in [0, 1] for k in range(L)]
      nqubits = len(qubits)
      qubits = set(sample(qubits, int(nqubits * qubit_yield)))
      edges = ((p, q) for p in qubits for q in _chimera_neighbors(M, N, L, p))
      edges = list(filter(edge_filter, edges))
      possibly_evil_edges = [(p, q) for p, q in edges if p[:2] == q[:2]]
      num_evil = min(num_evil, len(possibly_evil_edges))
      evil_edges = sample(possibly_evil_edges, num_evil)
      return processor(set(edges) - set(evil_edges), M=M, N=N, L=L, linear=False)
docs: A utility function that generates a random :math:`C_{M,N,L}` missing some
      percentage of its qubits.
  
      INPUTS:
          M,N,L: the chimera parameters
          qubit_yield: ratio (0 <= qubit_yield <= 1) of #{qubits}/(2*M*N*L)
          num_evil: number of broken in-cell couplers between working qubits
  
      OUTPUT:
          proc (:class:`processor`): a :class:`processor` instance with a random
              collection of qubits and couplers as specified