import sys
print(sys.version)

"""
Explanation: 4.0 Numpy Advanced
4.1 Verifying the python version you are using
End of explanation
"""


import numpy as np
np.__version__

import matplotlib as mpl
from matplotlib import pyplot as plt
mpl.__version__

"""
Explanation: At this point anything above python 3.5 should be ok.
4.2 Import numpy
End of explanation
"""


values = np.zeros((2,50))
size  = values.shape
print(size)

for i in range(size[1]):
    values[0,i] = i * 2
    values[1,i] = np.sin(i / 2)
    
print(values)

"""
Explanation: Notes:
4.3 Set a dummy numpy array elements
Create a 2D numpy array and set the elements in it as you iterate.
End of explanation
"""


np.save('np_file.npy', values)
np.savetxt('txt_file.txt', np.transpose(values))

"""
Explanation: Notes:
4.4 Save the numpy array to file
It is practical to save the processed arrays and numpy has built in functions for this
End of explanation
"""


values_from_text = np.loadtxt("txt_file.txt")
values_from_np   = np.load("np_file.npy")

print(values_from_text[0,0] == values_from_np[0,0])
print(values_from_text)

"""
Explanation: Notes:
4.5 Load numpy array from file
End of explanation
"""


values = values_from_text
print(values.shape)

x_0 = values[0]
print(x_0)

x_1 = values[:,0]
print(x_1)

y_1 = values[:,1]
print(y_1)

fig = plt.figure()
plt.plot(x_1, y_1)
plt.show()

"""
Explanation: Notes:
4.6 Exercice:
Create a numpy array from -pi to pi and save the sin of it to file. The read this file again and print the result in the notebook.
Notes:
5. Numpy array slicing
5.1 General slicing
End of explanation
"""


indices = [5,10, 15 ,20]

x = values[indices,0]
print(x)

y = values[indices,1]
print(y)

fig = plt.figure()
plt.plot(x, y)
plt.show()

"""
Explanation: Notes:
5.2 Precise slicing
End of explanation
"""


indices = np.where(values[:,1] > -0.5)[0]
print("indices: ",indices)

x = values[indices,0]
print("x: ",x)

y = values[indices,1]
print("y: ",y)

fig = plt.figure()
plt.plot(x, y)
plt.show()

"""
Explanation: Notes:
5.3 Conditional slicing
End of explanation
"""


to_sort = np.random.rand(10)
print(to_sort)

to_sort.sort()
print(to_sort)

"""
Explanation: Notes:
6. Numpy array Sorting
6.1 One dimension
End of explanation
"""


to_sort = np.random.rand(2,10)
print(to_sort)

to_sort.sort(axis=1)
print(to_sort)

"""
Explanation: Notes:
6.2 Two dimension
End of explanation
"""


to_sort = np.random.rand(3,10)
print(to_sort)

#investigate the axis we want to sort after
print("The axis to sort: \n",to_sort[1])

sort_indices = to_sort[1].argsort()
print("The indexes after the sort: \n",sort_indices)

#proceed the sort using the slicing method we just introduced
to_sort = to_sort[:,sort_indices]
print("The sorted full array:\n ",to_sort)

"""
Explanation: Notes:
6.3 Sort whole array by one column
End of explanation
"""


