# If necessary, for more concepts and/or details see comprehensive
# overviews/documentations/tutorials etc.:
# https://numpy.org/doc/stable/user/index.html
# https://www.tutorialspoint.com/numpy/numpy_introduction.htm
# and more
# For a particular topics, try also
# https://stackoverflow.com/questions/tagged/numpy
# (Do not ask, typically, most of your questions have been answered
# long ago, just search for the topics)

import numpy as np


list1 = [0,4,2,1,3]
arr = np.array(list1)
print( "arr:    ",  arr )

# ----------------------------------------------------------------
# 1D array

# arithmetic
arr = arr + 2
print("arr+2   ", arr )
arr = 3*arr - 1
print("3*arr-1 ", arr )
arr = arr**3
print( "arr**3  ", arr )
arr = arr//100
print( "arr//100",  arr )
arr = arr/100
print( "arr/100", arr )
# etc. just use array as an operand
print()


# ----------------------------------------------------------------
# 2D array

a2 = np.zeros([4,5])
print(a2)
print()

a2 = np.ones([4,5]) * 23
print(a2)
a2 = a2.astype(int)
print(a2)
print()

# rint, floor, trunc, ceil
# round to nearest integer,
# nearest smallest or equal integer,
# truncated decimal part,
# nearest bigger or equal integer
a21 = [2.6, 7.11, 3.001 ]
print( "trunc(a21)", np.trunc(a21) )
# etc
print()

# Arithmetic with 2D arrays is done item by item
a3 = np.ones([4,5])*2
print(a3)
# the sizes of the arrays must be identical!
a3 = a3 + a2
print(a3)
print()

a4 = np.ones([2,3])*5
a5 = np.ones([2,3])*7
a6 = (a4**2) * a5
print("a6:\n", a6)
print()

# Also 2D numpy arrays can be based on "usual" Python arrays/lists
list2 = [[3,5,1,6,3], [8,7,2,4,5], [1,3,6,5,4]]
a2 = np.array(list2)
print(a2)
# array items are accessed in standard way by indexing
print(a2[1][1])
print(a2[1,1])
# and the rows are accessed analogously
print(">", a2[2])
print()

# slicing works in 2D as well, a single square bracket is used
a3 = a2[1:3,1:4]
print(a3)

print()

# arrays can be "glued" together horizontally or vertically
# by concatenate with axis specified
# or by horizontal or vertical "stacking"
a4 = np.ones([2,2])
a5 = np.ones([2,2])*2
print(a4); print(); print(a5); print()
a6 = np.concatenate([a4,a5], axis = 0)
a7 = np.concatenate([a4,a5], axis = 1)
print(a6)
print()
print(a7)

print()
a6 = np.hstack([a4,a5])
a7 = np.vstack([a4,a5])
print(a6)
print()
print(a7)

#

