# Buggy code
def num_connected_components(self, unitary_only=False):
    """How many non-entangled subcircuits can the circuit be factored to.

    Args:
        unitary_only (bool): Compute only unitary part of graph.

    Returns:
        int: Number of connected components in circuit.
    """
    # Convert registers to ints (as done in depth).
    reg_offset = 0
    reg_map = {}

    if unitary_only:
        regs = self.qregs
    else:
        regs = self.qregs + self.cregs

    for reg in regs:
        reg_map[reg.name] = reg_offset
        reg_offset += reg.size
    # Start with each qubit or cbit being its own subgraph.
    sub_graphs = [[bit] for bit in range(reg_offset)]

    num_sub_graphs = len(sub_graphs)

    # Here we are traversing the gates and looking to see
    # which of the sub_graphs the gate joins together.
    for op in self.data:
        if unitary_only:
            args = op[1]
            num_qargs = len(args)
        else:
            args = op[1] + op[2]
            num_qargs = len(args) + (1 if op[0].control else 0)

        if num_qargs >= 2 and op[0].name not in ["barrier", "snapshot"]:
            graphs_touched = []
            num_touched = 0
            # Controls necessarily join all the cbits in the
            # register that they use.
            if op[0].control and not unitary_only:
                creg = op[0].control[0]
                creg_int = reg_map[creg.name]
                for coff in range(creg.size):
                    temp_int = creg_int + coff
                    for k in range(num_sub_graphs):
                        if temp_int in sub_graphs[k]:
                            graphs_touched.append(k)
                            num_touched += 1
                            break

            for item in args:
                reg_int = reg_map[item[0].name] + item[1]
                for k in range(num_sub_graphs):
                    if reg_int in sub_graphs[k]:
                        if k not in graphs_touched:
                            graphs_touched.append(k)
                            num_touched += 1
                            break

            # If the gate touches more than one subgraph
            # join those graphs together and return
            # reduced number of subgraphs
            if num_touched > 1:
                connections = []
                for idx in graphs_touched:
                    connections.extend(sub_graphs[idx])
                _sub_graphs = []
                for idx in range(num_sub_graphs):
                    if idx not in graphs_touched:
                        _sub_graphs.append(sub_graphs[idx])
                _sub_graphs.append(connections)
                sub_graphs = _sub_graphs
                num_sub_graphs -= num_touched - 1
        # Cannot go lower than one so break
        if num_sub_graphs == 1:
            break
    return num_sub_graphs


# Traceback (AttributeError)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-20-18ab26fa2a60> in <module>
7 #circuit.h(q[2])
8 #circuit.h(q[3])
----> 9 circuit.size()
10 circuit.draw(output='mpl',style=style)

c:\users\francoisvarchon\anaconda3\envs\qis09z\lib\site-packages\qiskit_terra-0.8.0-py3.7-win-amd64.egg\qiskit\circuit\quantumcircuit.py in size(self)
436         gate_ops = 0
437         for item in self.data:
--> 438             if item.name not in ['barrier', 'snapshot']:
439                 gate_ops += 1
440         return gate_ops

AttributeError: 'tuple' object has no attribute 'name'

# Fixed code
def num_connected_components(self, unitary_only=False):
    """How many non-entangled subcircuits can the circuit be factored to.

    Args:
        unitary_only (bool): Compute only unitary part of graph.

    Returns:
        int: Number of connected components in circuit.
    """
    # Convert registers to ints (as done in depth).
    reg_offset = 0
    reg_map = {}

    if unitary_only:
        regs = self.qregs
    else:
        regs = self.qregs + self.cregs

    for reg in regs:
        reg_map[reg.name] = reg_offset
        reg_offset += reg.size
    # Start with each qubit or cbit being its own subgraph.
    sub_graphs = [[bit] for bit in range(reg_offset)]

    num_sub_graphs = len(sub_graphs)

    # Here we are traversing the gates and looking to see
    # which of the sub_graphs the gate joins together.
    for instr, qargs, cargs in self.data:
        if unitary_only:
            args = qargs
            num_qargs = len(args)
        else:
            args = qargs + cargs
            num_qargs = len(args) + (1 if instr.control else 0)

        if num_qargs >= 2 and instr.name not in ["barrier", "snapshot"]:
            graphs_touched = []
            num_touched = 0
            # Controls necessarily join all the cbits in the
            # register that they use.
            if instr.control and not unitary_only:
                creg = instr.control[0]
                creg_int = reg_map[creg.name]
                for coff in range(creg.size):
                    temp_int = creg_int + coff
                    for k in range(num_sub_graphs):
                        if temp_int in sub_graphs[k]:
                            graphs_touched.append(k)
                            num_touched += 1
                            break

            for item in args:
                reg_int = reg_map[item[0].name] + item[1]
                for k in range(num_sub_graphs):
                    if reg_int in sub_graphs[k]:
                        if k not in graphs_touched:
                            graphs_touched.append(k)
                            num_touched += 1
                            break

            # If the gate touches more than one subgraph
            # join those graphs together and return
            # reduced number of subgraphs
            if num_touched > 1:
                connections = []
                for idx in graphs_touched:
                    connections.extend(sub_graphs[idx])
                _sub_graphs = []
                for idx in range(num_sub_graphs):
                    if idx not in graphs_touched:
                        _sub_graphs.append(sub_graphs[idx])
                _sub_graphs.append(connections)
                sub_graphs = _sub_graphs
                num_sub_graphs -= num_touched - 1
        # Cannot go lower than one so break
        if num_sub_graphs == 1:
            break
    return num_sub_graphs