import numpy as np
from PIL import Image





def 	__lowerCamelCase							(UpperCAmelCase__     :							np.ndarray      , UpperCAmelCase__     :							int      , UpperCAmelCase__     :							int  ):
					SCREAMING_SNAKE_CASE    			=       np.array(UpperCAmelCase__  )
					if arr.shape[0] != arr.shape[1]:
										raise ValueError("The input array is not a square matrix"  )
					SCREAMING_SNAKE_CASE    			=       0
					SCREAMING_SNAKE_CASE    			=       0
					SCREAMING_SNAKE_CASE    			=       0
					SCREAMING_SNAKE_CASE    			=       0

					# compute the shape of the output matrix
					SCREAMING_SNAKE_CASE    			=       (arr.shape[0] - size) // stride + 1
					# initialize the output matrix with zeros of shape maxpool_shape
					SCREAMING_SNAKE_CASE    			=       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
															SCREAMING_SNAKE_CASE    			=       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
										SCREAMING_SNAKE_CASE    			=       0
										SCREAMING_SNAKE_CASE    			=       0

					return updated_arr





def 	__lowerCamelCase							(UpperCAmelCase__     :							np.ndarray      , UpperCAmelCase__     :							int      , UpperCAmelCase__     :							int  ):
					SCREAMING_SNAKE_CASE    			=       np.array(UpperCAmelCase__  )
					if arr.shape[0] != arr.shape[1]:
										raise ValueError("The input array is not a square matrix"  )
					SCREAMING_SNAKE_CASE    			=       0
					SCREAMING_SNAKE_CASE    			=       0
					SCREAMING_SNAKE_CASE    			=       0
					SCREAMING_SNAKE_CASE    			=       0

					# compute the shape of the output matrix
					SCREAMING_SNAKE_CASE    			=       (arr.shape[0] - size) // stride + 1
					# initialize the output matrix with zeros of shape avgpool_shape
					SCREAMING_SNAKE_CASE    			=       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
															SCREAMING_SNAKE_CASE    			=       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
										SCREAMING_SNAKE_CASE    			=       0
										SCREAMING_SNAKE_CASE    			=       0

					return updated_arr


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

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

							# Loading the image
							_lowerCamelCase					:   Tuple							=		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							(UpperCAmelCase__     :							list[int]  ):
					if not numbers:
										return 0

					if not isinstance(UpperCAmelCase__      , (list, tuple)  ) or not all(
					    isinstance(UpperCAmelCase__      , UpperCAmelCase__  ) for number in numbers  ):
										raise ValueError("numbers must be an iterable of integers"  )

					SCREAMING_SNAKE_CASE    			=       SCREAMING_SNAKE_CASE    			=       SCREAMING_SNAKE_CASE    			=       numbers[0]

					for i in range(1      , len(UpperCAmelCase__  )  ):
										# update the maximum and minimum subarray products
										SCREAMING_SNAKE_CASE    			=       numbers[i]
										if number < 0:
															SCREAMING_SNAKE_CASE			,   SCREAMING_SNAKE_CASE    			=       min_till_now, max_till_now
										SCREAMING_SNAKE_CASE    			=       max(UpperCAmelCase__      , max_till_now * number  )
										SCREAMING_SNAKE_CASE    			=       min(UpperCAmelCase__      , min_till_now * number  )

										# update the maximum product found till now
										SCREAMING_SNAKE_CASE    			=       max(UpperCAmelCase__      , UpperCAmelCase__  )

					return max_prod




