




import numpy as np
from PIL import Image



def 						lowerCAmelCase		(		_lowerCAmelCase							:   np.ndarray						,							_lowerCAmelCase							:   int						,							_lowerCAmelCase							:   int	):




 """simple docstring"""







 UpperCAmelCase__							 =						np.array(_lowerCAmelCase	)
 if arr.shape[0] != arr.shape[1]:
  raise ValueError("The input array is not a square matrix"	)
 UpperCAmelCase__							 =						0
 UpperCAmelCase__							 =						0
 UpperCAmelCase__							 =						0
 UpperCAmelCase__							 =						0

 # compute the shape of the output matrix
 UpperCAmelCase__							 =						(arr.shape[0] - size) // stride + 1
 # initialize the output matrix with zeros of shape maxpool_shape
 UpperCAmelCase__							 =						np.zeros((maxpool_shape, maxpool_shape)	)

 while i < arr.shape[0]:
  if i + size > arr.shape[0]:
   # if the end of the matrix is reached, break
   break
  while j < arr.shape[1]:
   # if the end of the matrix is reached, break
   if j + size > arr.shape[1]:
    break
   # compute the maximum of the pooling matrix
   UpperCAmelCase__							 =						np.max(arr[i : i + size, j : j + size]	)
   # shift the pooling matrix by stride of column pixels
   j += stride
   mat_j += 1

  # shift the pooling matrix by stride of row pixels
  i += stride
  mat_i += 1

  # reset the column index to 0
  UpperCAmelCase__							 =						0
  UpperCAmelCase__							 =						0

 return updated_arr



def 						lowerCAmelCase		(		_lowerCAmelCase							:   np.ndarray						,							_lowerCAmelCase							:   int						,							_lowerCAmelCase							:   int	):




 """simple docstring"""







 UpperCAmelCase__							 =						np.array(_lowerCAmelCase	)
 if arr.shape[0] != arr.shape[1]:
  raise ValueError("The input array is not a square matrix"	)
 UpperCAmelCase__							 =						0
 UpperCAmelCase__							 =						0
 UpperCAmelCase__							 =						0
 UpperCAmelCase__							 =						0

 # compute the shape of the output matrix
 UpperCAmelCase__							 =						(arr.shape[0] - size) // stride + 1
 # initialize the output matrix with zeros of shape avgpool_shape
 UpperCAmelCase__							 =						np.zeros((avgpool_shape, avgpool_shape)	)

 while i < arr.shape[0]:
  # if the end of the matrix is reached, break
  if i + size > arr.shape[0]:
   break
  while j < arr.shape[1]:
   # if the end of the matrix is reached, break
   if j + size > arr.shape[1]:
    break
   # compute the average of the pooling matrix
   UpperCAmelCase__							 =						int(np.average(arr[i : i + size, j : j + size]	)	)
   # shift the pooling matrix by stride of column pixels
   j += stride
   mat_j += 1

  # shift the pooling matrix by stride of row pixels
  i += stride
  mat_i += 1
  # reset the column index to 0
  UpperCAmelCase__							 =						0
  UpperCAmelCase__							 =						0

 return updated_arr


# Main Function
if __name__ == "__main__":
  from doctest import testmod

  testmod(name="avgpooling", verbose=True)

  # Loading the image
  _lowerCAmelCase						:   str		=   Image.open("path_to_image")

  # Converting the image to numpy array and maxpooling, displaying the result
  # Ensure that the image is a square matrix

  Image.fromarray(maxpooling(np.array(image), size=3, stride=2)).show()

  # Converting the image to numpy array and averagepooling, displaying the result
  # Ensure that the image is a square matrix

  Image.fromarray(avgpooling(np.array(image), size=3, stride=2)).show()











from __future__ import annotations



def 						lowerCAmelCase		(		_lowerCAmelCase							:   int = 4	):




 """simple docstring"""







 UpperCAmelCase__							 =						abs(_lowerCAmelCase	) or 4
 return [[1 + x + y * row_size for x in range(_lowerCAmelCase	)] for y in range(_lowerCAmelCase	)]



def 						lowerCAmelCase		(		_lowerCAmelCase							:   list[list[int]]	):




 """simple docstring"""







 return reverse_row(transpose(_lowerCAmelCase	)	)
 # OR.. transpose(reverse_column(matrix))



def 						lowerCAmelCase		(		_lowerCAmelCase							:   list[list[int]]	):




 """simple docstring"""







 return reverse_row(reverse_column(_lowerCAmelCase	)	)
 # OR.. reverse_column(reverse_row(matrix))



def 						lowerCAmelCase		(		_lowerCAmelCase							:   list[list[int]]	):




 """simple docstring"""







 return reverse_column(transpose(_lowerCAmelCase	)	)
 # OR.. transpose(reverse_row(matrix))



def 						lowerCAmelCase		(		_lowerCAmelCase							:   list[list[int]]	):




 """simple docstring"""







 UpperCAmelCase__							 =						[list(_lowerCAmelCase	) for x in zip(*_lowerCAmelCase	)]
 return matrix



def 						lowerCAmelCase		(		_lowerCAmelCase							:   list[list[int]]	):




 """simple docstring"""







 UpperCAmelCase__							 =						matrix[::-1]
 return matrix



def 						lowerCAmelCase		(		_lowerCAmelCase							:   list[list[int]]	):




 """simple docstring"""







 UpperCAmelCase__							 =						[x[::-1] for x in matrix]
 return matrix



def 						lowerCAmelCase		(		_lowerCAmelCase							:   list[list[int]]	):




 """simple docstring"""







 for i in matrix:
  print(*_lowerCAmelCase	)


if __name__ == "__main__":
  _lowerCAmelCase						:   Optional[int]		=   make_matrix()
  print("\norigin:\n")
  print_matrix(matrix)
  print("\nrotate 90 counterclockwise:\n")
  print_matrix(rotate_aa(matrix))

  _lowerCAmelCase						:   Union[str, Any]		=   make_matrix()
  print("\norigin:\n")
  print_matrix(matrix)
  print("\nrotate 180:\n")
  print_matrix(rotate_aaa(matrix))

  _lowerCAmelCase						:   Optional[int]		=   make_matrix()
  print("\norigin:\n")
  print_matrix(matrix)
  print("\nrotate 270 counterclockwise:\n")
  print_matrix(rotate_aaa(matrix))





