#
# your code is here 
#    (you may find the values by hand (in mind) as well)
#
# vector |v>

print("vector |v>")

values = [-0.1, -0.3, 0.4, 0.5]

total = 0 # summation of squares
for i in range(len(values)):
    total += values[i]**2; # add the square of each value
print("total is ",total)
print("the missing part is",1-total)
print("so, the value of 'a' can be",(1-total)**0.5,"or",-(1-total)**0.5) # square root of the missing part

print()
print("vector |u>")

values = [1/(2**0.5), -1/(3**0.5)]

total = 0 # summation of squares
for i in range(len(values)):
    total += values[i]**2; # add the square of each value
print("total is ",total)
print("the missing part is",1-total)
# the missing part is 1/b, square of 1/sqrt(b)
# thus, b is 1/missing_part
print("so, the value of 'b' should be",1/(1-total)) 

#
# you may define your first function in a separate cell 
#

# randomly creating a 2-dimensional quantum state
from random import randrange
def random_quantum_state():
    first_entry = randrange(-100,101)
    second_entry = randrange(-100,101)
    length_square = first_entry**2+second_entry**2
    while length_square == 0:
        first_entry = randrange(-100,101)
        second_entry = randrange(-100,101)
        length_square = first_entry**2+second_entry**2
    first_entry = first_entry / length_square**0.5
    second_entry = second_entry / length_square**0.5
    return [first_entry,second_entry]

#
# your code is here
#
# testing whether a given quantum state is valid
def is_quantum_state(quantum_state):
    length_square = 0
    for i in range(len(quantum_state)):
        length_square += quantum_state[i]**2
    print("summation of entry squares is",length_square)
    # there might be precision problem
    # the length may be very close to 1 but not exactly 1
    # so we use the following trick
    if (length_square - 1)**2 < 0.00000001: return True 
    return False # else

# defining a function for Hadamard multiplication
def hadamard(quantum_state):
    result_quantum_state = [0,0] # define with zero entries
    result_quantum_state[0] = (1/(2**0.5)) * quantum_state[0] + (1/(2**0.5)) * quantum_state[1]
    result_quantum_state[1] = (1/(2**0.5)) * quantum_state[0] - (1/(2**0.5)) * quantum_state[1]
    return result_quantum_state

# we are ready
for i in range(10):
    picked_quantum_state=random_quantum_state()
    print(picked_quantum_state,"this is randomly picked quantum state")
    print("Is it valid?",is_quantum_state(picked_quantum_state))
    new_quantum_state = hadamard(picked_quantum_state)
    print(new_quantum_state,"this is new quantum state")
    print("Is it valid?",is_quantum_state(new_quantum_state))
    print() # print an empty line