from qiskit import QuantumCircuit # imports only QuantumCircuit function from qiskit 
# from qiskit import * --> import all the fuction defined under qiskit library including QuantumCircuit

# Creating an empty quantum circuit object with 3 qubits and 3 classical bits
qc = QuantumCircuit(3,3)
qc.draw()

# For better visualization use matplotlib as 'mpl'
qc.draw(output = "mpl")

qc_trial = QuantumCircuit(3,3)
qc_trial.draw(output = "mpl")

qc_trial.measure_all()

qc_trial.draw(output = "mpl")

qc_trial2 = QuantumCircuit(3)
qc_trial2.draw(output = "mpl")

qc_trial2.measure_all()
qc_trial2.draw(output = "mpl")

qc_trial3 = QuantumCircuit(3,3)
# if you get bored typing QuantumCircuit all the time try this: from qiskit import QuantumCircuit as qc

qc_trial3.draw(output = "mpl") 


qc_trial3.measure(0,0) # measure(qubit,clbit)
qc_trial3.draw(output = "mpl")

# alternative to give a command to measure multiple qubits at the same time
qc_trial3 = QuantumCircuit(3,3)
qc_trial3.measure([0,2],[0,2])# measure([qubits],[clbits]), order matters,here qubit0-->clbit0,qubit2 --> clbit2
qc_trial3.draw( output = "mpl")



#To demonstrate significance of order
qc_trial3 = QuantumCircuit(3,3)
qc_trial3.measure([0,1],[0,2])# measure([qubits],[clbits]), order here qubit0-->clbit0,qubit1 --> clbit2
qc_trial3.draw( output = "mpl")



# To measure all the qubits
qc_trial3 = QuantumCircuit(3,3)
qc_trial3.measure([0,1,2],[0,1,2])# measure([qubits],[clbits]), order here qubit0-->clbit0,qubit1 --> clbit1,qubit2 --> clbit2
qc_trial3.draw( output = "mpl")



#measure() requires pre-written classical register
qc_trial4 = QuantumCircuit(3)
qc_trial4.measure([0,1,2],[0,1,2])
qc_trial4.draw(output = "mpl")

qc_trial5 = QuantumCircuit(3,3)
qc_trial5.measure(0,1,2)
qc_trial5.draw(output = "mpl")

# We can also use"range" function 
qc_trial5 = QuantumCircuit(3,3)
qc_trial5.measure(range(3),range(3))
qc_trial5.draw(output = "mpl")

qc.draw(output = "mpl")

qc.measure([0,1,2], [0,1,2])
qc.draw(output = "mpl")

qc_op2 = QuantumCircuit(3,3)
qc_op2.measure([0,0], [1,1], [2,2])


qc_op2.measure([0,0], [1,1])

qc_op2.draw(output = "mpl")

# It just implemented 2 measurements on the same qubit as the instruction read [(qubit0,qubit0),(clbit1,clbit1)]
# so qubit0 --> clbit0, and again qubit0--> clbit1

qc_op3 =  QuantumCircuit(3,3)
qc_op3.measure_all()
qc_op3.draw(output = "mpl")

# Two classical registers('c' and 'meas')

qc_op4 = QuantumCircuit(3,3)
qc_op4.measure(0,1,2)
qc_op4.draw(output = "mpl")

