import qiskit
qiskit.__qiskit_version__

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister

qr = QuantumRegister(2)
cr = ClassicalRegister(2)

qc = QuantumCircuit(qr,cr)

qc.draw()

qc.h(qr[0])


qc.draw()

qc = QuantumCircuit(qr,cr)
qc.h(qr[0])
qc.cx(qr[0],qr[1])

qc.measure(qr,cr)

qc.draw()

from qiskit import execute

from qiskit import Aer
print(Aer.backends()) #, nicer printout below:
backend_list  = Aer.backends()
for be in backend_list:
    print(be)


backend = Aer.get_backend('qasm_simulator')

job = execute(qc,backend,shots=100000)

print(job)

my_results = job.result()

print(my_results)

print(my_results.get_counts())

# with shots=1, you will get a count of 1 either on 00 or on 11
job = execute(qc,backend, shots=111)
my_results = job.result()
print(my_results.get_counts(qc))

from qiskit.tools.visualization import plot_histogram
plot_histogram(my_results.get_counts(qc))

qr = QuantumRegister(2)
cr = ClassicalRegister(2)
qc = QuantumCircuit(qr,cr)


qc.x(qr[0])
qc.id(qr[1])

qc.measure(qr,cr)

qc.draw()

# with shots=1, you will get a count of 1 either on 00 or on 11
job = execute(qc,backend, shots=1024)
my_results = job.result()
print(my_results.get_counts(qc))

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, execute

qr = QuantumRegister(2)
cr = ClassicalRegister(2)
qc = QuantumCircuit(qr,cr)

qc.h(qr[0])
qc.cx(qr[0],qr[1])
qc.measure(qr,cr)
qc.draw(output='latex')


# how to use the machines and simulator in the cloud

from qiskit import IBMQ
MY_API_TOKEN= 'e5f5ed26c560465a044adb6bbbad67743cd41365ff700fe7ab7104ef83518ccff6b28b4b52ecd827de2df397aba6a6e8eb88cc154842ab203f1aadfbdff3f024'
IBMQ.save_account(MY_API_TOKEN, overwrite=True)
IBMQ.load_account()


sp = IBMQ.get_provider(hub='ibm-q')

# list backends available for this provider
print(sp.backends())

sp = IBMQ.get_provider(hub='ibm-q')   # selected provider

backends_set = set()
for b in selected_provider.backends():
    backends_set.add(str(b))
   
print("backend name                    queue qubits operational status message")
print("------------------------------- ----- ------ ----------- --------------")
for b in backends_set: 
    be = sp.get_backend(b)
    pj = be.status().pending_jobs
    qb = be.configuration().n_qubits
    op = be.status().operational 
    sm = be.status().status_msg
    print(f"{b:32} {pj:4} {qb:6}{op:12} {sm:6}")
print("------------------------------ ----- ------ ----------- --------------")

backend = selected_provider.get_backend('simulator_statevector')


# IBMQ for access to online devices and helps manage your IBM Q account data from your workstation. 
from qiskit import IBMQ

MY_API_TOKEN= 'e5f5ed26c560465a044adb6bbbad67743cd41365ff700fe7ab7104ef83518ccff6b28b4b52ecd827de2df397aba6a6e8eb88cc154842ab203f1aadfbdff3f024'
IBMQ.save_account(MY_API_TOKEN, overwrite=True)

IBMQ.load_account()

# choose one available provider
selected_provider = IBMQ.get_provider(hub='ibm-q')

# list backends available for this provider
selected_provider.backends()

# small program to get backends configs and status
# using least_busy() is more straightforward, this is to show
# how we get info from the provider's backends

sp = IBMQ.get_provider(hub='ibm-q')   # selected provider

backends_set = set()
for b in selected_provider.backends():
    backends_set.add(str(b))
   
print("backend name                    queue qubits operational status message")
print("------------------------------- ----- ------ ----------- --------------")
for b in backends_set: 
    be = sp.get_backend(b)
    pj = be.status().pending_jobs
    qb = be.configuration().n_qubits
    op = be.status().operational 
    sm = be.status().status_msg
    print(f"{b:32} {pj:4} {qb:6}{op:12} {sm:6}")
print("------------------------------ ----- ------ ----------- --------------")

backend = sp.get_backend('ibmq_belem')
backend.name()

# we want more than 1 qubit (we need 2), on an operationnal backend which is not a simulator
from qiskit.providers.ibmq import least_busy

backend = least_busy(sp.backends(filters = lambda x: x.configuration().n_qubits >= 2 and 
                                       not x.configuration().simulator and x.status().operational == True))

print("least busy backend: ", backend)

# execution
from qiskit.tools.monitor import job_monitor

job = execute(qc,backend)
print(job.job_id())
job_monitor(job)

res = job.result()
from qiskit.tools.visualization import plot_histogram

d = (res.get_counts(qc))
d

plot_histogram(d)





import numpy as np

from qiskit import Aer, QuantumCircuit, execute
from qiskit.visualization import plot_histogram, plot_state_qsphere
from qiskit.quantum_info import Statevector
from IPython.display import display, Math, Latex



# 1
def create_circuit():
    qc = QuantumCircuit(1)
    #
    # FILL YOUR CODE IN HERE
    #
    #
    return qc

# check solution

qc = create_circuit()

sv = Statevector.from_label('0')
sv = sv.evolve(qc)

plot_state_qsphere(sv.data, show_state_labels=True, show_state_phases=True) 

# 2
def create_circuit():
    qc = QuantumCircuit(1)
    #
    #
    # FILL YOUR CODE IN HERE
    #
    #
    return qc

qc = create_circuit()
sv = Statevector.from_label('0')
sv = sv.evolve(qc)
plot_state_qsphere(sv.data, show_state_labels=True, show_state_phases=True) 

# 3
def create_circuit():
    qc = QuantumCircuit(1)
    #
    #
    # FILL YOUR CODE IN HERE
    #
    #
    return qc

qc = create_circuit()
sv = Statevector.from_label('0')
sv = sv.evolve(qc)
plot_state_qsphere(sv.data, show_state_labels=True, show_state_phases=True) 

# 4
def create_circuit():
    qc = QuantumCircuit(1)
    #
    #
    # FILL YOUR CODE IN HERE
    # 
    #
    #
    return qc

qc = create_circuit()
sv = Statevector.from_label('0')
sv = sv.evolve(qc)
plot_state_qsphere(sv.data, show_state_labels=True, show_state_phases=True) 

# 5
def create_circuit():
    qc = QuantumCircuit(2)
    #
    #
    # FILL YOUR CODE IN HERE
    qc.h(0)
    qc.cx(0,1)
    #
    return qc

qc = create_circuit()
sv = Statevector.from_label('00')
sv = sv.evolve(qc)
plot_state_qsphere(sv.data, show_state_labels=True, show_state_phases=True) 

# 6
def create_circuit():
    qc = QuantumCircuit(2,2) # this time, we not only want two qubits, but also 
                             # two classical bits for the measurement later
    #
    #
    # FILL YOUR CODE IN HERE
    #
    
    return qc

qc = create_circuit()
sv = Statevector.from_label('00')
sv = sv.evolve(qc)
print(sv)
plot_state_qsphere(sv.data, show_state_labels=True, show_state_phases=True) 

# 7
qc.measure(0, 0) # we perform a measurement on qubit q_0 and store the information on the classical bit c_0
qc.measure(1, 1) # we perform a measurement on qubit q_1 and store the information on the classical bit c_1
qc.draw(output='mpl') # we draw the circuit

# 8
def run_circuit(qc):
    backend = Aer.get_backend('qasm_simulator') # we choose the simulator as our backend
    result = execute(qc, backend, shots = 1000).result() # we run the simulation
    counts = result.get_counts() # we get the counts
    return counts

counts = run_circuit(qc)
print(counts)
plot_histogram(counts) # let us plot a histogram to see the possible outcomes and corresponding probabilities

# 9
def create_circuit():
    qc = QuantumCircuit(2)
    ## initializing part
    qc.rx(np.pi/3,0)
    qc.x(1)
    ## end of initializing
    #
    #
    # FILL YOUR CODE IN HERE
    #
    #
    
    return qc


qc = create_circuit()
sv = Statevector.from_label('00')
sv = sv.evolve(qc)
print(sv)
plot_state_qsphere(sv.data, show_state_labels=True, show_state_phases=True) 

# 10
#
#
# FILL YOUR CODE IN HERE
#
#


#
#
# FILL YOUR CODE IN HERE
#
#    

from qiskit import ClassicalRegister, QuantumRegister
from qiskit import QuantumCircuit, execute
from qiskit.tools.visualization import plot_histogram
from qiskit import IBMQ, BasicAer
from qiskit.tools.jupyter import *
import matplotlib.pyplot as plt
%matplotlib inline

####


backend = BasicAer.get_backend('qasm_simulator')
shots_sim = 10

job_sim = execute(qc, backend, shots=shots_sim)
stats_sim = job_sim.result().get_counts()

def plot_letter (stats, shots):
    ### code from the qiskit.org smiley demo
    for bitString in stats:
        char = chr(int( bitString[0:7] ,2)) # get string of the leftmost 7 bits and convert to an ASCII character
        prob = stats[bitString] / shots # fraction of shots for which this result occurred
        # create plot with all characters on top of each other with alpha given by how often it turned up in the output
        plt.annotate( char, (0.5,0.5), va="center", ha="center", color = (0,0,0, prob ), size = 300)
        if (prob>0.05): # list prob and char for the dominant results (occurred for more than 5% of shots)
            print(str(prob)+"\t"+char)
    plt.axis('off')
    plt.show()
    
print(shots_sim) 
print(stats_sim)
plot_letter(stats_sim, shots_sim)