from hide_toggle import hide_toggle
#usage: 
#1 create a cell with: hide_toggle(for_next=True)
#2 put the commented solution in the next cell

#import latex
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import execute, BasicAer
import numpy as np
%matplotlib inline

#define a 2 qubit register and QuantumCircuit


hide_toggle(for_next=True)

# 2 bit registry creation.
#qr = QuantumRegister(2, 'qr')

# Circuit creation 
#qc = QuantumCircuit(qr)

#solution:
#had_tr = QuantumCircuit(qr)

hide_toggle(for_next=True)

# Circuit creation of the Hadamard Transform
#had_tr = QuantumCircuit(qr)

#had_tr.h(qr[0])
#had_tr.h(qr[1])
#had_tr.barrier()


#qc = had_tr
#qc.draw(output='mpl')

#run the circuit on statevector_simulator, save result to state_superposition variable

hide_toggle(for_next=True)

# execute the quantum circuit on simulator 
#backend = BasicAer.get_backend('statevector_simulator')

#job = execute(qc, backend)

#state_superposition = job.result().get_statevector(qc)
#print(state_superposition)

from qiskit.tools.visualization import plot_bloch_multivector

rho_superposition= np.outer(state_superposition, state_superposition.conj())
plot_bloch_multivector(rho_superposition)

print("\n\n\n\n===== Welcome! =====\n\n")
print("  ~~ Let's take this test ~~ ")
print("\n\n")
print("Select the winner among:")
print("a) Hearts")
print("b) Pictures")
print("c) Flowers")
print("d) Spades")
chosen = 0
while (chosen==0):
#	scelta = getpass.getpass("make your choise. (a, b, c, d, e or f)\n")
    scelta = input("Choose your card (a, b, c, d)\n")
    if scelta == "a":
        bit = "|00>"
        print("Choice: a) Hearts")
    if scelta == "b":
        bit = "|01>"
        print("Choice: b) Pictures")
    if scelta == "c":
        bit = "|10>"
        print("Choice: c) Flowers")
    if scelta == "d":
        bit = "|11>"
        print("Choice: d) Spades")
    if scelta in ["a","b","c","d"]:
        chosen = 1
        
        print ("Linked to:", bit)
    else:
        print("wrong selection, retry")

#create the circuit orac
#orac = QuantumCircuit(qr)

hide_toggle(for_next=True)

#orac = QuantumCircuit(qr)

#orac.h(qr[1])
#orac.cx(qr[0],qr[1])
#orac.h(qr[1])
#orac.barrier()

#orac.draw(output='mpl')

# The Qiskit circuit object supports concatenating circuits with the addition operator.

qc = had_tr + orac

qc.draw(output='mpl')

orac = QuantumCircuit(qr)

if scelta == "a": # |00>
    orac.x(qr[0])
    orac.x(qr[1])
    orac.h(qr[1])
    orac.cx(qr[0],qr[1])
    orac.h(qr[1])
    orac.x(qr[0])
    orac.x(qr[1])
    orac.barrier()

if scelta == "b": # |01>
    orac.x(qr[1])
    orac.h(qr[1])
    orac.cx(qr[0],qr[1])
    orac.h(qr[1])
    orac.x(qr[1])
    orac.barrier()

if scelta == "c": # |10>
    orac.x(qr[0])
    orac.h(qr[1])
    orac.cx(qr[0],qr[1])
    orac.h(qr[1])
    orac.x(qr[0])
    orac.barrier()

if scelta == "d":  # |11>
    orac.h(qr[1])
    orac.cx(qr[0],qr[1])
    orac.h(qr[1])
    orac.barrier()

orac.draw(output='mpl')

qc = had_tr
qc.draw(output='mpl')

backend = BasicAer.get_backend('statevector_simulator')
job = execute(qc, backend)

state = job.result().get_statevector(qc)
state

qc = had_tr + orac
qc.draw(output='mpl')

job = execute(qc, backend)

state = job.result().get_statevector(qc)
state

cphase = QuantumCircuit(qr)

cphase.x(qr[0])
cphase.x(qr[1])

cphase.h(qr[1])
cphase.cx(qr[0],qr[1])
cphase.h(qr[1])

cphase.x(qr[0])
cphase.x(qr[1])
cphase.barrier()

qc = cphase

qc.draw(output='mpl')

qc = had_tr + orac + had_tr + cphase + had_tr

qc.draw(output='mpl')

#solution:
#add classical bit register and meas, draw the circuit

hide_toggle(for_next=True)

# Create a Classical Register with 2 bits.
#cr = ClassicalRegister(2, 'cr')
# Create a Quantum Circuit
#meas = QuantumCircuit(qr, cr)

# add measurement operators
#meas.measure(qr,cr)

#qc = had_tr + orac + had_tr + cphase + had_tr + meas

#drawing the circuit
#qc.draw(output='mpl')

#solution:
#from qiskit import BasicAer
#...
#...
#print("Results : ", counts)

hide_toggle(for_next=True)

# Import Aer
#from qiskit import BasicAer

# Use Aer's qasm_simulator
#backend_sim = BasicAer.get_backend('qasm_simulator')

# Execute the circuit on the qasm simulator.
# We've set the number of repeats of the circuit
# to be 1024, which is the default.
#job = execute(qc, backend_sim)

# Grab the results from the job.
#result = job.result()

#counts = result.get_counts(qc)
#print("Results : ", counts)

from qiskit.tools.visualization import plot_histogram
plot_histogram(counts)

#1
from qiskit import IBMQ
#IBMQ.delete_accounts()
#IBMQ.save_account('API_TOKEN')

#2
provider = IBMQ.load_account()

#3
#solution:

hide_toggle(for_next=True)

#3
#print("Available backends:")
#provider.backends()
#from qiskit.tools.monitor import job_monitor, backend_monitor, backend_overview
#from qiskit.providers.ibmq import least_busy
#backend = least_busy(provider.backends(filters=lambda x: not x.configuration().simulator))
#backend.name()
#shots = 1024           # Number of shots to run the program (experiment); maximum is 8192 shots.
#max_credits = 3        # Maximum number of credits to spend on executions. 

#job_exp = execute(qc, backend=backend, shots=shots, max_credits=max_credits)
#job_monitor(job_exp)
#result_real = job_exp.result()
#counts_real = result_real.get_counts(qc)

plot_histogram(counts_real)

#formulate the classical solution

hide_toggle(for_next=True)

#counter=0
#for i in ["a","b","c","d"]:
	#counter=counter+1
	#if i == scelta:
		#print("winner found after ", counter) 

import webbrowser
url_1target = 'https://www.nature.com/articles/s41467-017-01904-7/tables/1'
url_2target = 'https://www.nature.com/articles/s41467-017-01904-7/tables/2'
webbrowser.open(url_1target)
webbrowser.open(url_2target)