




import pickle

import numpy as np
from matplotlib import pyplot as plt






class  __magic_name__						:
				'''simple docstring'''







				def __init__(							self:   Tuple		,					_lowerCamelCase:   str		,					_lowerCamelCase:   List[Any]		,					_lowerCamelCase:   Optional[int]		,					_lowerCamelCase:   Dict		,					_lowerCamelCase:   Union[str, Any]		,					_lowerCamelCase:   str=0.2		,					_lowerCamelCase:   int=0.2		):
											SCREAMING_SNAKE_CASE_   	=    bp_numa
											SCREAMING_SNAKE_CASE_   	=    bp_numa
											SCREAMING_SNAKE_CASE_   	=    bp_numa
											SCREAMING_SNAKE_CASE_   	=    conva_get[:2]
											SCREAMING_SNAKE_CASE_   	=    conva_get[2]
											SCREAMING_SNAKE_CASE_   	=    size_pa
											SCREAMING_SNAKE_CASE_   	=    rate_w
											SCREAMING_SNAKE_CASE_   	=    rate_t
											SCREAMING_SNAKE_CASE_   	=    [
											    np.mat(-1 * np.random.rand(self.conva[0]		,					self.conva[0]		) + 0.5		)
											    for i in range(self.conva[1]		)
											]
											SCREAMING_SNAKE_CASE_   	=    np.mat(-1 * np.random.rand(self.num_bpa		,					self.num_bpa		) + 0.5		)
											SCREAMING_SNAKE_CASE_   	=    np.mat(-1 * np.random.rand(self.num_bpa		,					self.num_bpa		) + 0.5		)
											SCREAMING_SNAKE_CASE_   	=    -2 * np.random.rand(self.conva[1]		) + 1
											SCREAMING_SNAKE_CASE_   	=    -2 * np.random.rand(self.num_bpa		) + 1
											SCREAMING_SNAKE_CASE_   	=    -2 * np.random.rand(self.num_bpa		) + 1


				def     _A							(							self:   Optional[int]		,					_lowerCamelCase:   Optional[int]		):
											# save model dict with pickle
											SCREAMING_SNAKE_CASE_   	=    {
											    '''num_bp1''': self.num_bpa,
											    '''num_bp2''': self.num_bpa,
											    '''num_bp3''': self.num_bpa,
											    '''conv1''': self.conva,
											    '''step_conv1''': self.step_conva,
											    '''size_pooling1''': self.size_poolinga,
											    '''rate_weight''': self.rate_weight,
											    '''rate_thre''': self.rate_thre,
											    '''w_conv1''': self.w_conva,
											    '''wkj''': self.wkj,
											    '''vji''': self.vji,
											    '''thre_conv1''': self.thre_conva,
											    '''thre_bp2''': self.thre_bpa,
											    '''thre_bp3''': self.thre_bpa,
											}
											with open(_lowerCamelCase		,					'''wb'''		) as f:
																		pickle.dump(_lowerCamelCase		,					_lowerCamelCase		)

											print(f"Model saved： {save_path}"		)


				@classmethod
				def     _A							(							cls:   List[Any]		,					_lowerCamelCase:   Union[str, Any]		):
											# read saved model
											with open(_lowerCamelCase		,					'''rb'''		) as f:
																		SCREAMING_SNAKE_CASE_   	=    pickle.load(_lowerCamelCase		)  # noqa: S301

											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''conv1'''		)
											conv_get.append(model_dic.get('''step_conv1'''		)		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''size_pooling1'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''num_bp1'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''num_bp2'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''num_bp3'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''rate_weight'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''rate_thre'''		)
											# create model instance
											SCREAMING_SNAKE_CASE_   	=    CNN(_lowerCamelCase		,					_lowerCamelCase		,					_lowerCamelCase		,					_lowerCamelCase		,					_lowerCamelCase		,					_lowerCamelCase		,					_lowerCamelCase		)
											# modify model parameter
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''w_conv1'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''wkj'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''vji'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''thre_conv1'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''thre_bp2'''		)
											SCREAMING_SNAKE_CASE_   	=    model_dic.get('''thre_bp3'''		)
											return conv_ins


				def     _A							(							self:   List[Any]		,					_lowerCamelCase:   int		):
											return 1 / (1 + np.exp(-1 * x		))


				def     _A							(							self:   Dict		,					_lowerCamelCase:   List[Any]		):
											return round(_lowerCamelCase		,					3		)


				def     _A							(							self:   str		,					_lowerCamelCase:   Union[str, Any]		,					_lowerCamelCase:   Optional[int]		,					_lowerCamelCase:   Union[str, Any]		,					_lowerCamelCase:   Dict		,					_lowerCamelCase:   Dict		):
											# convolution process
											SCREAMING_SNAKE_CASE_   	=    convs[0]
											SCREAMING_SNAKE_CASE_   	=    convs[1]
											SCREAMING_SNAKE_CASE_   	=    np.shape(_lowerCamelCase		)[0]
											# get the data slice of original image data, data_focus
											SCREAMING_SNAKE_CASE_   	=    []
											for i_focus in range(0		,					size_data - size_conv + 1		,					_lowerCamelCase		):
																		for j_focus in range(0		,					size_data - size_conv + 1		,					_lowerCamelCase		):
																									SCREAMING_SNAKE_CASE_   	=    data[
																									    i_focus : i_focus + size_conv, j_focus : j_focus + size_conv
																									]
																									data_focus.append(_lowerCamelCase		)
        # calculate the feature map of every single kernel, and saved as list of matrix
											SCREAMING_SNAKE_CASE_   	=    []
											SCREAMING_SNAKE_CASE_   	=    int((size_data - size_conv) / conv_step + 1		)
											for i_map in range(_lowerCamelCase		):
																		SCREAMING_SNAKE_CASE_   	=    []
																		for i_focus in range(len(_lowerCamelCase		)		):
																									SCREAMING_SNAKE_CASE_   	=    (
																									    np.sum(np.multiply(data_focus[i_focus]		,					w_convs[i_map]		)		)
																									    - thre_convs[i_map]
																									)
																									featuremap.append(self.sig(_lowerCamelCase		)		)
																		SCREAMING_SNAKE_CASE_   	=    np.asmatrix(_lowerCamelCase		).reshape(
																		    _lowerCamelCase		,					_lowerCamelCase		)
																		data_featuremap.append(_lowerCamelCase		)

											# expanding the data slice to One dimenssion
											SCREAMING_SNAKE_CASE_   	=    []
											for each_focus in data_focus:
																		focusa_list.extend(self.Expand_Mat(_lowerCamelCase		)		)
											SCREAMING_SNAKE_CASE_   	=    np.asarray(_lowerCamelCase		)
											return focus_list, data_featuremap


				def     _A							(							self:   Tuple		,					_lowerCamelCase:   List[str]		,					_lowerCamelCase:   Union[str, Any]		,					_lowerCamelCase:   str="average_pool"		):
											# pooling process
											SCREAMING_SNAKE_CASE_   	=    len(featuremaps[0]		)
											SCREAMING_SNAKE_CASE_   	=    int(size_map / size_pooling		)
											SCREAMING_SNAKE_CASE_   	=    []
											for i_map in range(len(_lowerCamelCase		)		):
																		SCREAMING_SNAKE_CASE_   	=    featuremaps[i_map]
																		SCREAMING_SNAKE_CASE_   	=    []
																		for i_focus in range(0		,					_lowerCamelCase		,					_lowerCamelCase		):
																									for j_focus in range(0		,					_lowerCamelCase		,					_lowerCamelCase		):
																																SCREAMING_SNAKE_CASE_   	=    feature_map[
																																    i_focus : i_focus + size_pooling,
																																    j_focus : j_focus + size_pooling,
																																]
																																if pooling_type == "average_pool":
																																							# average pooling
																																							map_pooled.append(np.average(_lowerCamelCase		)		)
																																elif pooling_type == "max_pooling":
																																							# max pooling
																																							map_pooled.append(np.max(_lowerCamelCase		)		)
																		SCREAMING_SNAKE_CASE_   	=    np.asmatrix(_lowerCamelCase		).reshape(_lowerCamelCase		,					_lowerCamelCase		)
																		featuremap_pooled.append(_lowerCamelCase		)
											return featuremap_pooled


				def     _A							(							self:   Tuple		,					_lowerCamelCase:   Dict		):
											# expanding three dimension data to one dimension list
											SCREAMING_SNAKE_CASE_   	=    []
											for i in range(len(_lowerCamelCase		)		):
																		SCREAMING_SNAKE_CASE_   	=    np.shape(data[i]		)
																		SCREAMING_SNAKE_CASE_   	=    data[i].reshape(1		,					shapes[0] * shapes[1]		)
																		SCREAMING_SNAKE_CASE_   	=    data_listed.getA().tolist()[0]
																		data_expanded.extend(_lowerCamelCase		)
											SCREAMING_SNAKE_CASE_   	=    np.asarray(_lowerCamelCase		)
											return data_expanded


				def     _A							(							self:   str		,					_lowerCamelCase:   Union[str, Any]		):
											# expanding matrix to one dimension list
											SCREAMING_SNAKE_CASE_   	=    np.asarray(_lowerCamelCase		)
											SCREAMING_SNAKE_CASE_   	=    np.shape(_lowerCamelCase		)
											SCREAMING_SNAKE_CASE_   	=    data_mat.reshape(1		,					shapes[0] * shapes[1]		)
											return data_expanded


				def     _A							(							self:   str		,					_lowerCamelCase:   int		,					_lowerCamelCase:   Any		,					_lowerCamelCase:   Any		,					_lowerCamelCase:   str		,					_lowerCamelCase:   str		):
											SCREAMING_SNAKE_CASE_   	=    []
											SCREAMING_SNAKE_CASE_   	=    0
											for i_map in range(_lowerCamelCase		):
																		SCREAMING_SNAKE_CASE_   	=    np.ones((size_map, size_map)		)
																		for i in range(0		,					_lowerCamelCase		,					_lowerCamelCase		):
																									for j in range(0		,					_lowerCamelCase		,					_lowerCamelCase		):
																																SCREAMING_SNAKE_CASE_   	=    pd_pool[
																																    i_pool
																																]
																																SCREAMING_SNAKE_CASE_   	=    i_pool + 1
																		SCREAMING_SNAKE_CASE_   	=    np.multiply(
																		    _lowerCamelCase		,					np.multiply(out_map[i_map]		,					(1 - out_map[i_map])		)		)
																		pd_all.append(_lowerCamelCase		)
											return pd_all


				def     _A							(							self:   Tuple		,					_lowerCamelCase:   List[Any]		,					_lowerCamelCase:   Dict		,					_lowerCamelCase:   Tuple		,					_lowerCamelCase:   Optional[Any]		,					_lowerCamelCase:   Tuple		,					_lowerCamelCase:   Dict=bool		):
											# model traning
											print('''----------------------Start Training-------------------------'''		)
											print((''' - - Shape: Train_Data  ''', np.shape(_lowerCamelCase		))		)
											print((''' - - Shape: Teach_Data  ''', np.shape(_lowerCamelCase		))		)
											SCREAMING_SNAKE_CASE_   	=    0
											SCREAMING_SNAKE_CASE_   	=    []
											SCREAMING_SNAKE_CASE_   	=    1_00_00
											while rp < n_repeat and mse >= error_accuracy:
																		SCREAMING_SNAKE_CASE_   	=    0
																		print(f"-------------Learning Time {rp}--------------"		)
																		for p in range(len(_lowerCamelCase		)		):
																									# print('------------Learning Image: %d--------------'%p)
																									SCREAMING_SNAKE_CASE_   	=    np.asmatrix(datas_train[p]		)
																									SCREAMING_SNAKE_CASE_   	=    np.asarray(datas_teach[p]		)
																									SCREAMING_SNAKE_CASE_	,	SCREAMING_SNAKE_CASE_   	=    self.convolute(
																									    _lowerCamelCase		,					self.conva		,					self.w_conva		,					self.thre_conva		,					conv_step=self.step_conva		,					)
																									SCREAMING_SNAKE_CASE_   	=    self.pooling(_lowerCamelCase		,					self.size_poolinga		)
																									SCREAMING_SNAKE_CASE_   	=    np.shape(_lowerCamelCase		)
																									SCREAMING_SNAKE_CASE_   	=    self._expand(_lowerCamelCase		)
																									SCREAMING_SNAKE_CASE_   	=    data_bp_input

																									SCREAMING_SNAKE_CASE_   	=    np.dot(_lowerCamelCase		,					self.vji.T		) - self.thre_bpa
																									SCREAMING_SNAKE_CASE_   	=    self.sig(_lowerCamelCase		)
																									SCREAMING_SNAKE_CASE_   	=    np.dot(_lowerCamelCase		,					self.wkj.T		) - self.thre_bpa
																									SCREAMING_SNAKE_CASE_   	=    self.sig(_lowerCamelCase		)

																									# --------------Model Leaning ------------------------
																									# calculate error and gradient---------------
																									SCREAMING_SNAKE_CASE_   	=    np.multiply(
																									    (data_teach - bp_outa)		,					np.multiply(_lowerCamelCase		,					(1 - bp_outa)		)		)
																									SCREAMING_SNAKE_CASE_   	=    np.multiply(
																									    np.dot(_lowerCamelCase		,					self.wkj		)		,					np.multiply(_lowerCamelCase		,					(1 - bp_outa)		)		)
																									SCREAMING_SNAKE_CASE_   	=    np.dot(_lowerCamelCase		,					self.vji		)

																									SCREAMING_SNAKE_CASE_   	=    pd_i_all / (self.size_poolinga * self.size_poolinga)
																									SCREAMING_SNAKE_CASE_   	=    pd_conva_pooled.T.getA().tolist()
																									SCREAMING_SNAKE_CASE_   	=    self._calculate_gradient_from_pool(
																									    _lowerCamelCase		,					_lowerCamelCase		,					shape_featuremapa[0]		,					shape_featuremapa[1]		,					self.size_poolinga		,					)
																									# weight and threshold learning process---------
																									# convolution layer
																									for k_conv in range(self.conva[1]		):
																																SCREAMING_SNAKE_CASE_   	=    self._expand_mat(pd_conva_all[k_conv]		)
																																SCREAMING_SNAKE_CASE_   	=    self.rate_weight * np.dot(_lowerCamelCase		,					_lowerCamelCase		)

																																SCREAMING_SNAKE_CASE_   	=    self.w_conva[k_conv] + delta_w.reshape(
																																    (self.conva[0], self.conva[0])		)

																																SCREAMING_SNAKE_CASE_   	=    (
																																    self.thre_conva[k_conv]
																																    - np.sum(pd_conva_all[k_conv]		) * self.rate_thre
																																)
																									# all connected layer
																									SCREAMING_SNAKE_CASE_   	=    self.wkj + pd_k_all.T * bp_outa * self.rate_weight
																									SCREAMING_SNAKE_CASE_   	=    self.vji + pd_j_all.T * bp_outa * self.rate_weight
																									SCREAMING_SNAKE_CASE_   	=    self.thre_bpa - pd_k_all * self.rate_thre
																									SCREAMING_SNAKE_CASE_   	=    self.thre_bpa - pd_j_all * self.rate_thre
																									# calculate the sum error of all single image
																									SCREAMING_SNAKE_CASE_   	=    np.sum(abs(data_teach - bp_outa		)		)
																									error_count += errors
																									# print('   ----Teach      ',data_teach)
																									# print('   ----BP_output  ',bp_out3)
																		SCREAMING_SNAKE_CASE_   	=    rp + 1
																		SCREAMING_SNAKE_CASE_   	=    error_count / patterns
																		all_mse.append(_lowerCamelCase		)

											def draw_error():
																		SCREAMING_SNAKE_CASE_   	=    [error_accuracy for i in range(int(n_repeat * 1.2		)		)]
																		plt.plot(_lowerCamelCase		,					'''+-'''		)
																		plt.plot(_lowerCamelCase		,					'''r--'''		)
																		plt.xlabel('''Learning Times'''		)
																		plt.ylabel('''All_mse'''		)
																		plt.grid(_lowerCamelCase		,					alpha=0.5		)
																		plt.show()

											print('''------------------Training Complished---------------------'''		)
											print((''' - - Training epoch: ''', rp, f"     - - Mse: {mse:.6f}")		)
											if draw_e:
																		draw_error()
											return mse


				def     _A							(							self:   int		,					_lowerCamelCase:   Union[str, Any]		):
											# model predict
											SCREAMING_SNAKE_CASE_   	=    []
											print('''-------------------Start Testing-------------------------'''		)
											print((''' - - Shape: Test_Data  ''', np.shape(_lowerCamelCase		))		)
											for p in range(len(_lowerCamelCase		)		):
																		SCREAMING_SNAKE_CASE_   	=    np.asmatrix(datas_test[p]		)
																		SCREAMING_SNAKE_CASE_	,	SCREAMING_SNAKE_CASE_   	=    self.convolute(
																		    _lowerCamelCase		,					self.conva		,					self.w_conva		,					self.thre_conva		,					conv_step=self.step_conva		,					)
																		SCREAMING_SNAKE_CASE_   	=    self.pooling(_lowerCamelCase		,					self.size_poolinga		)
																		SCREAMING_SNAKE_CASE_   	=    self._expand(_lowerCamelCase		)

																		SCREAMING_SNAKE_CASE_   	=    data_bp_input
																		SCREAMING_SNAKE_CASE_   	=    bp_outa * self.vji.T - self.thre_bpa
																		SCREAMING_SNAKE_CASE_   	=    self.sig(_lowerCamelCase		)
																		SCREAMING_SNAKE_CASE_   	=    bp_outa * self.wkj.T - self.thre_bpa
																		SCREAMING_SNAKE_CASE_   	=    self.sig(_lowerCamelCase		)
																		produce_out.extend(bp_outa.getA().tolist()		)
											SCREAMING_SNAKE_CASE_   	=    [list(map(self.do_round		,					_lowerCamelCase		)		) for each in produce_out]
											return np.asarray(_lowerCamelCase		)





				def     _A							(							self:   Optional[Any]		,					_lowerCamelCase:   Tuple		):
											# return the data of image after convoluting process so we can check it out
											SCREAMING_SNAKE_CASE_   	=    np.asmatrix(_lowerCamelCase		)
											SCREAMING_SNAKE_CASE_	,	SCREAMING_SNAKE_CASE_   	=    self.convolute(
											    _lowerCamelCase		,					self.conva		,					self.w_conva		,					self.thre_conva		,					conv_step=self.step_conva		,					)
											SCREAMING_SNAKE_CASE_   	=    self.pooling(_lowerCamelCase		,					self.size_poolinga		)

											return data_conveda, data_pooleda


if __name__ == "__main__":
			pass








def 			a   (_lowerCAmelCase     ):
							SCREAMING_SNAKE_CASE_	,	SCREAMING_SNAKE_CASE_   	=    [], []
							while len(_lowerCAmelCase     ) > 1:
														SCREAMING_SNAKE_CASE_	,	SCREAMING_SNAKE_CASE_   	=    min(_lowerCAmelCase     ), max(_lowerCAmelCase     )
														start.append(_lowerCAmelCase     )
														end.append(_lowerCAmelCase     )
														collection.remove(_lowerCAmelCase     )
														collection.remove(_lowerCAmelCase     )
							end.reverse()
							return start + collection + end


if __name__ == "__main__":
			__SCREAMING_SNAKE_CASE 						=input("""Enter numbers separated by a comma:\n""").strip()
			__SCREAMING_SNAKE_CASE 						=[int(item) for item in user_input.split(""",""")]
			print(*merge_sort(unsorted), sep=""",""")


