from matplotlib.pyplot import bar

labels = []
elements = []
for i in range(8):
    labels = labels + [i+1]
    elements  = elements + [1]

# visualize the values of elements in the list 
bar(labels,elements)

# 
# 1st step - query
#

# change the sign of the marked element, i.e., multiply it by -1

# visualize the values of elements in the list 
bar(labels,elements)

#
# 1st step - inversion
#

# calculate the mean of all values 

# then reflect each element over the mean, e.g.:
#   if the mean is 0, then the reflection of 3 is -3
#   if the mean is 1, then the reflection of 3 is -1
#   if the mean is -1, then the reflection of 3 is -5


# visualize the values of elements in the list 
bar(labels,elements)

# 
# 2nd step - query
#


# visualize the values of elements in the list 
bar(labels,elements)

#
# 2nd step - inversion
#


# visualize the values of elements in the list 
bar(labels,elements)

#
# your code is here
#

from matplotlib.pyplot import bar

labels = []
elements = []
for i in range(8):
    labels = labels + [i+1]
    elements  = elements + [1]

# visualize the values of elements in the list 
bar(labels,elements)
# visualize the values of elements in the list 
bar(labels,elements)

# 
# 1st step - query
#

# flip the sign of the marked element
elements[3] = -1 * elements[3]

# visualize the values of elements in the list 
bar(labels,elements)

#
# 1st step - inversion
#

# summation of all values
sum = 0
for i in range(len(elements)):
    sum += elements[i]

# mean of all values
mean = sum / len(elements)

# reflection over the mean
for i in range(len(elements)):
    value = elements[i]
    new_value = mean - (elements[i]-mean)
    elements[i] = new_value

# visualize the values of elements in the list 
bar(labels,elements)

# 
# 2nd step - query
#

# flip the sign of the marked element
elements[3] = -1 * elements[3]

# visualize the values of elements in the list 
bar(labels,elements)

#
# 2nd step - inversion
#

# summation of all values
sum = 0
for i in range(len(elements)):
    sum += elements[i]

# mean of all values
mean = sum / len(elements)

# reflection over mean
for i in range(len(elements)):
    value = elements[i]
    new_value = mean - (elements[i]-mean)
    elements[i] = new_value

# visualize the values of elements in the list 
bar(labels,elements)

for i in range(3):
    # flip the sign of the marked element
    elements[3] = -1 * elements[3]
    
    # summation of all values
    sum = 0
    for i in range(len(elements)):
        sum += elements[i]

    # mean of all values
    mean = sum / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value
        
# visualize the values of elements in the list 
bar(labels,elements)        

def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements

def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

from matplotlib.pyplot import bar

# define the list of size 8 on which each element has value of 1
elements = []
for i in range(8):
    elements  = elements + [1]

# index of the marked element
marked_elements = [3]
    
# define the list of iterations
iterations = []
# the list storing the values of the 4th element after each step
L = []

# the first values
iterations.append(0)
L.append(elements[marked_elements[0]])

for step in range(20):
    # store the iteration
    iterations.append(step+1)
    
    # flip the sign of the marked element
    elements = query(elements,marked_elements)
    elements = inversion(elements)    
    
    # store the new value of the 4th element
    L.append(elements[marked_elements[0]])
    
# visualize the values of the 4th elements after each iteration
bar(iterations,L)
print(iterations)
print(L)

def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements

def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

from matplotlib.pyplot import bar

# define the list of size 8 on which each element has value of 1
elements = []
for i in range(16):
    elements  = elements + [1]

# index of the marked element
marked_elements = [10]
    
# define the list of iterations
iterations = []
# the list storing the values of the marked element after each step
L = []

# the first values
iterations.append(0)
L.append(elements[marked_elements[0]])

for step in range(20):
    # store the iteration
    iterations.append(step+1)
    
    # flip the sign of the marked element
    elements = query(elements,marked_elements)
    elements = inversion(elements)    
    
    # store the new value of the 4th element
    L.append(elements[marked_elements[0]])
    
# visualize the values of the marked elements after each iteration
bar(iterations,L)
print(iterations)
print(L)

def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements

def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

from matplotlib.pyplot import bar

# define the list of size 8 on which each element has value of 1
elements = []
for i in range(16):
    elements  = elements + [1]

# index of the marked element
marked_elements = [4,7,9]
    
# define the list of iterations
iterations = []
# the list storing the values of the first element after each step
L = []

# the first values
iterations.append(0)
L.append(elements[marked_elements[0]])

for step in range(20):
    # store the iteration
    iterations.append(step+1)
    
    # flip the sign of the marked element
    elements = query(elements,marked_elements)
    elements = inversion(elements)
    
    # store the new value of the first marked element
    L.append(elements[marked_elements[0]])
    
# visualizing the values of the first marked elements after each iteration
bar(iterations,L)
print(iterations)
print(L)

def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements

def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

def length_of_list (elements=[1]):
    summation = 0
    for el in elements:
        summation = summation + el**2
    return round(summation**0.5,3)

# define the list of size 8 on which each element has value of 1
elements = []
for i in range(16):
    elements  = elements + [1]

# index of the marked element
marked_elements = [0,1,2,3]

print("the initial length",length_of_list(elements))

for step in range(20):
    # store the iteration
    iterations.append(step+1)
    
    # flip the sign of the marked element
    elements = query(elements,marked_elements)
    print("step",step,"the length after query is ",length_of_list(elements))
    elements = inversion(elements)
    print("step",step,"the length after inversion is ",length_of_list(elements))

def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements

def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

def length_of_list (elements=[1]):
    summation = 0
    for el in elements:
        summation = summation + el**2
    return round(summation**0.5,3)

# define the list of size 10 on which each element has value of 1
elements = []
for i in range(10):
    elements  = elements + [1]

# index of the marked element
marked_elements = [9]

print("the initial length",length_of_list(elements))

for step in range(20):
    # store the iteration
    iterations.append(step+1)
    
    # flip the sign of the marked element
    elements = query(elements,marked_elements)
    print("step",step,"the length after query is ",length_of_list(elements))
    elements = inversion(elements)
    print("step",step,"the length after inversion is ",length_of_list(elements))

def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements

def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

def length_of_list (elements=[1]):
    summation = 0
    for el in elements:
        summation = summation + el**2
    return round(summation**0.5,3)

# print the elements of a given list with a given precision
def print_list(L,precision):
    output = ""
    for i in range(len(L)):
        output = output + str(round(L[i],precision))+"  "
    print(output)

# define the list of size 8 on which each element has value of 1
elements = []
for i in range(8):
    elements  = elements + [1/(8**0.5)]

# index of the marked element
marked_elements = [1]

print("step 0")
print("the list of elements is")
print_list(elements,3)
print("the initial length",length_of_list(elements))

for step in range(20):
    # store the iteration
    iterations.append(step+1)
    
    # flip the sign of the marked element
    elements = query(elements,marked_elements)
    elements = inversion(elements)
    print()
    print("after step",step+1)
    print("the list of elements is")
    print_list(elements,3)
    print("the length after iteration is ",length_of_list(elements))

def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements

def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

def length_of_list (elements=[1]):
    summation = 0
    for el in elements:
        summation = summation + el**2
    return round(summation**0.5,3)

# print the elements of a given list with a given precision
def print_list(L,precision):
    output = ""
    for i in range(len(L)):
        output = output + str(round(L[i],precision))+"  "
    print(output)

# define the list of size 8 on which each element has value of 1
elements = []
for i in range(16):
    elements  = elements + [1/(16**0.5)]

# index of the marked element
marked_elements = range(12)

print("step 0")
print("the list of elements is")
print_list(elements,3)
print("the initial length",length_of_list(elements))

for step in range(20):
    # store the iteration
    iterations.append(step+1)
    
    # flip the sign of the marked element
    elements = query(elements,marked_elements)
    elements = inversion(elements)
    print()
    print("after step",step+1)
    print("the list of elements is")
    print_list(elements,3)
    print("the length after iteration is ",length_of_list(elements))