from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, execute, Aer, IBMQ, BasicAer
import math
from qiskit.visualization import plot_histogram

backend = BasicAer.get_backend('statevector_simulator')

from wordcloud import WordCloud
import numpy as np  
import pandas as pd # primary data structure library
import matplotlib.pyplot as plt

reg = QuantumRegister(8, name='reg') # The quantum register of the qubits, in this case 8 qubits
reg_c = ClassicalRegister(8, name='regc') # Where the measurements of the qubits will be saved
qc = QuantumCircuit(reg, reg_c) 

qc.h(reg)              # Apply Hadamard gate to put it into a superposition of 0 and 1 all the qubits 
qc.measure(reg, reg_c) # read the result as a digital bit

job = execute(qc, backend) # Execute the circuit in the statevector_simulator 
result = job.result() 
outputstate = result.get_statevector(qc, decimals=5) 
counts = result.get_counts(qc)

#print(outputstate)

qc.draw() 

state, value = list(counts.items())[0] # key is de state of the system after the measuremnt, for example '11100001'
state

number = int(state, 2)  # The state is converted into a number
ASCII_Character = chr(number) # The number in  ASCII character
print('The random number is:',number)
print('The random ASCII character:',ASCII_Character)



def Quantum_random_number_and_ASCII_Character_generator(n):
    
    reg = QuantumRegister(n, name='reg') # The quantum register of the n qubits
    reg_c = ClassicalRegister(n, name='regc')# Where the measurements of the qubits will be saved
    qc = QuantumCircuit(reg, reg_c) 
    
    qc.h(reg)              # put it into a superposition of 0 and 1
    qc.measure(reg, reg_c) # read the result as a digital bit
    
    job = execute(qc, backend)
    result = job.result()
    counts = result.get_counts(qc)
    key, value = list(counts.items())[0]
    
    number = int(key, 2)
    ASCII_Character = chr(number)
    
    
    return ASCII_Character, number

Quantum_random_number_and_ASCII_Character_generator(8)[0] # Resturns the ASCII Character

Quantum_random_number_and_ASCII_Character_generator(8)[1] # Resturns the Random number

L  = []
num = []
counter = []
for x in range(800):
    string = Quantum_random_number_and_ASCII_Character_generator(8)[0] # ASCII_Character
    number = Quantum_random_number_and_ASCII_Character_generator(8)[1] # Random_number
    L.append(string) # Save the ASCII_Character in a the list "L"
    num.append(number) # Save the Random_number in a the list "number"
    counter.append(x)

# Convert the list to a dataframe 
df1 = pd.DataFrame(counter, columns=['Counter'])
df2 = pd.DataFrame(L, columns=['Random_Character'])
df3 = pd.DataFrame(num, columns=['Random_Number'])

#Join the results in a dataframe
re = df1.join(df2)
Quantum_Random = re.join(df3)

Quantum_Random.head()

Quantum_Random.plot(x='Counter', y='Random_Number', figsize=(25,6.5), xlabel='Iteration', ylabel='Randon Number', legend = False, grid = True, fontsize = 14)

Quantum_Random['Random_Number'].describe()



#generate the word cloud
wordcloud = WordCloud(background_color='white').generate(' '.join(Quantum_Random['Random_Character']))

# display the word cloud
fig = plt.figure()
fig.set_figwidth(14)
fig.set_figheight(18)

plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()

