from IPython.display import HTML

HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code for QISKit exercises."></form>''')

from qiskit import *

# Quantum program setup 
Q_program = QuantumProgram()

# Creating registers
q = Q_program.create_quantum_register('q', 5)
c0 = Q_program.create_classical_register('c0', 1)
c1 = Q_program.create_classical_register('c1', 1)
c2 = Q_program.create_classical_register('c2', 1)

# Creates the quantum circuit
bit_flip = Q_program.create_circuit('bit_flip', [q], [c0,c1,c2])

# Prepares qubit in the desired initial state 
bit_flip.h(q[0])

# Encodes the qubit in a three-qubit entangled state  
bit_flip.cx(q[0], q[1])
bit_flip.cx(q[0], q[2])

# Bit-flip error on the second qubit
bit_flip.x(q[1])

# Adds additional two qubits for error-correction
bit_flip.cx(q[0], q[3])
bit_flip.cx(q[1], q[3])
bit_flip.cx(q[0], q[4])
bit_flip.cx(q[2], q[4])

# Measure the two additional qubits
bit_flip.measure(q[3], c0[0])
bit_flip.measure(q[4], c1[0])

# Do error correction
bit_flip.x(q[1]).c_if(c0, 1)
bit_flip.x(q[2]).c_if(c1, 1)

# Decodes the qubit from the three-qubit entangled state  
bit_flip.cx(q[0], q[1])
bit_flip.cx(q[0], q[2])

# Check the state of the initial qubit
bit_flip.measure(q[0], c2[0])

# Shows gates of the circuit
circuits = ['bit_flip']
print(Q_program.get_qasms(circuits)[0])

# Parameters for execution on simulator
backend = 'local_qasm_simulator' 
shots = 1024 # the number of shots in the experiment 

# Run the algorithm
result = Q_program.execute(circuits, backend=backend, shots=shots)

#Shows the results obtained from the quantum algorithm 
counts = result.get_counts('bit_flip')

print('\nThe measured outcomes of the circuits are:', counts)

from qiskit import *

# Quantum program setup 
Q_program = QuantumProgram()

# Creating registers
q = Q_program.create_quantum_register('q', 5)
c0 = Q_program.create_classical_register('c0', 1)
c1 = Q_program.create_classical_register('c1', 1)
c2 = Q_program.create_classical_register('c2', 1)

# Creates the quantum circuit
bit_flip = Q_program.create_circuit('bit_flip', [q], [c0,c1,c2])

# Prepares qubit in the desired initial state 
bit_flip.h(q[0])

# Encodes the qubit in a three-qubit entangled state  
bit_flip.cx(q[0], q[1])
bit_flip.cx(q[0], q[2])

# Go to Hadamard basis
bit_flip.h(q[0])
bit_flip.h(q[1])
bit_flip.h(q[2])

# Phase error on the second qubit
bit_flip.z(q[1])

# Converts phase error in bit-flip error
bit_flip.h(q[0])
bit_flip.h(q[1])
bit_flip.h(q[2])

# Adds additional two qubits for error-correction
bit_flip.cx(q[0], q[3])
bit_flip.cx(q[1], q[3])
bit_flip.cx(q[0], q[4])
bit_flip.cx(q[2], q[4])

# Measure the two additional qubits
bit_flip.measure(q[3], c0[0])
bit_flip.measure(q[4], c1[0])

# Do error correction
bit_flip.x(q[1]).c_if(c0, 1)
bit_flip.x(q[2]).c_if(c1, 1)

# Decodes the qubit from the three-qubit entangled state  
bit_flip.cx(q[0], q[1])
bit_flip.cx(q[0], q[2])

# Check the state of the initial qubit
bit_flip.measure(q[0], c2[0])

# Shows gates of the circuit
circuits = ['bit_flip']
print(Q_program.get_qasms(circuits)[0])

# Parameters for execution on simulator
backend = 'local_qasm_simulator' 
shots = 1024 # the number of shots in the experiment 

# Run the algorithm
result = Q_program.execute(circuits, backend=backend, shots=shots)

#Shows the results obtained from the quantum algorithm 
counts = result.get_counts('bit_flip')

print('\nThe measured outcomes of the circuits are:', counts)