import numpy as np
from PIL import Image





def  _lowerCamelCase					(   a_				: np.ndarray						,			a_				: int						,			a_				: int):
			lowerCamelCase						:Optional[int]						  =     np.array(a_)
			if arr.shape[0] != arr.shape[1]:
						raise ValueError('''The input array is not a square matrix''')
			lowerCamelCase						:Dict						  =     0
			lowerCamelCase						:int						  =     0
			lowerCamelCase						:List[Any]						  =     0
			lowerCamelCase						:Dict						  =     0

			# compute the shape of the output matrix
			lowerCamelCase						:Optional[Any]						  =     (arr.shape[0] - size) // stride + 1
			# initialize the output matrix with zeros of shape maxpool_shape
			lowerCamelCase						:Union[str, Any]						  =     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
									lowerCamelCase						:Union[str, Any]						  =     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
						lowerCamelCase						:Dict						  =     0
						lowerCamelCase						:int						  =     0

			return updated_arr





def  _lowerCamelCase					(   a_				: np.ndarray						,			a_				: int						,			a_				: int):
			lowerCamelCase						:Optional[int]						  =     np.array(a_)
			if arr.shape[0] != arr.shape[1]:
						raise ValueError('''The input array is not a square matrix''')
			lowerCamelCase						:Any						  =     0
			lowerCamelCase						:Any						  =     0
			lowerCamelCase						:Any						  =     0
			lowerCamelCase						:List[Any]						  =     0

			# compute the shape of the output matrix
			lowerCamelCase						:List[Any]						  =     (arr.shape[0] - size) // stride + 1
			# initialize the output matrix with zeros of shape avgpool_shape
			lowerCamelCase						:Union[str, Any]						  =     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
									lowerCamelCase						:Optional[int]						  =     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
						lowerCamelCase						:str						  =     0
						lowerCamelCase						:List[str]						  =     0

			return updated_arr


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

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

			# Loading the image
			A__           =							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()




def  _lowerCamelCase					(   a_				: list):

			if not grid or not grid[0]:
						raise TypeError('''The grid does not contain the appropriate information''')

			for cell_n in range(1						,			len(grid[0])):
						grid[0][cell_n] += grid[0][cell_n - 1]
			lowerCamelCase						:Any						  =     grid[0]

			for row_n in range(1						,			len(a_)):
						lowerCamelCase						:List[str]						  =     grid[row_n]
						lowerCamelCase						:Union[str, Any]						  =     fill_row(a_						,			a_)
						lowerCamelCase						:List[Any]						  =     grid[row_n]

			return grid[-1][-1]





def  _lowerCamelCase					(   a_				: list						,			a_				: list):
			current_row[0] += row_above[0]
			for cell_n in range(1						,			len(a_)):
						current_row[cell_n] += min(current_row[cell_n - 1]						,			row_above[cell_n])

			return current_row


if __name__ == "__main__":
			import doctest

			doctest.testmod()



