from qiskit.circuit.random import random_circuit

circuit = random_circuit(2, 2, seed=0).decompose(reps=1)
display(circuit.draw("mpl"))

from qiskit.quantum_info import SparsePauliOp

observable = SparsePauliOp("XZ")
print(f"  > Observable: {observable.paulis}")

from qiskit.primitives import Estimator

estimator = Estimator()

job = estimator.run(circuit, observable)
print(f">>> {job.job_id()}")
print(f">>> {job.status()}")

result = job.result()
print(f">>> {result}")

expval = result.values[0]
metadatum = result.metadata[0]

print(f"  > Expectation value: {expval}")
print(f"  > Metadata: {metadatum}")

circuit = random_circuit(2, 2, seed=1).decompose(reps=1)
observable = SparsePauliOp("IY")

job = estimator.run(circuit, observable)
result = job.result()

display(circuit.draw("mpl"))
print(f"  > Observable: {observable.paulis}")
print(f"  > Expectation value: {result.values[0]}")
print(f"  > Metadata: {result.metadata[0]}")

circuits = (
    random_circuit(2, 2, seed=0).decompose(reps=1),
    random_circuit(2, 2, seed=1).decompose(reps=1),
)
observables = (
    SparsePauliOp("XZ"),
    SparsePauliOp("IY"),
)

job = estimator.run(circuits, observables)
result = job.result()

[display(cir.draw("mpl")) for cir in circuits]
print(f"  > Observables: {[obs.paulis for obs in observables]}")
print(f"  > Expectation values: {result.values.tolist()}")
print(f"  > Metadata: {result.metadata}")

circuits = (
    random_circuit(2, 2, seed=0).decompose(reps=1),
    random_circuit(2, 2, seed=1).decompose(reps=1),
)
observables = (
    SparsePauliOp("XZ"),
    SparsePauliOp("IY"),
)

job_0 = estimator.run(circuits[0], observables[0])
job_1 = estimator.run(circuits[1], observables[1])

result_0 = job_0.result()
result_1 = job_1.result()

[display(cir.draw("mpl")) for cir in circuits]
print(f"  > Observables: {[obs.paulis for obs in observables]}") 
print(f"  > Expectation values [0]: {result_0.values.tolist()[0]}") 
print(f"  > Metadata [0]: {result_0.metadata[0]}")
print(f"  > Expectation values [1]: {result_1.values.tolist()[0]}") 
print(f"  > Metadata [1]: {result_1.metadata[0]}")

from qiskit.circuit.library import RealAmplitudes

circuit = RealAmplitudes(num_qubits=2, reps=2).decompose(reps=1)
observable = SparsePauliOp("ZI")
parameter_values = [0, 1, 2, 3, 4, 5]

job = estimator.run(circuit, observable, parameter_values)
result = job.result()

display(circuit.draw("mpl"))
print(f"  > Observable: {observable.paulis}")
print(f"  > Parameter values: {parameter_values}")
print(f"  > Expectation value: {result.values[0]}")
print(f"  > Metadata: {result.metadata[0]}")

estimator = Estimator(options={"shots": 2048})  # Defaults !!!

circuit = random_circuit(2, 2, seed=0).decompose(reps=1)
observable = SparsePauliOp("XZ")

job = estimator.run(circuit, observable)
result = job.result()

display(circuit.draw("mpl"))
print(f"  > Observable: {observable.paulis}")
print(f"  > Expectation value: {result.values[0]}")
print(f"  > Metadata: {result.metadata[0]}")

circuit = random_circuit(2, 2, seed=0).decompose(reps=1)
observable = SparsePauliOp("XZ")

job = estimator.run(circuit, observable, shots=1024)  # Job-only !!!
result = job.result()

display(circuit.draw("mpl"))
print(f"  > Observable: {observable.paulis}")
print(f"  > Expectation value: {result.values[0]}")
print(f"  > Metadata: {result.metadata[0]}")

from qiskit.primitives import BackendEstimator
from qiskit.providers.fake_provider import FakeNairobi  # Bring the noise!

backend = FakeNairobi()
estimator = BackendEstimator(backend)

circuit = random_circuit(2, 2, seed=0).decompose(reps=1)
observable = SparsePauliOp("XZ")

job = estimator.run(circuit, observable)
result = job.result()

display(circuit.draw("mpl"))
print(f"  > Observable: {observable.paulis}")
print(f"  > Expectation value: {result.values[0]}")
print(f"  > Metadata: {result.metadata[0]}")

import qiskit.tools.jupyter  # pylint: disable=unused-import,wrong-import-order

%qiskit_version_table
%qiskit_copyright