






'''simple docstring'''







#
# Sort large text files in a minimum amount of memory
#
import argparse
import os




class 					__UpperCAmelCase :

      '''simple docstring'''





      SCREAMING_SNAKE_CASE				:    Any				       =					"block_{0}.dat"




      def __init__(					self  ,		_UpperCAmelCase						):
             UpperCAmelCase__	:   str												=	filename
             UpperCAmelCase__	:   str												=	[]




      def 							lowerCamelCase     (					self  ,		_UpperCAmelCase  ,		_UpperCAmelCase						):
             UpperCAmelCase__	:   Dict												=	self.BLOCK_FILENAME_FORMAT.format(_UpperCAmelCase						)
             with open(_UpperCAmelCase  ,		'''w'''						) as file:
                    file.write(_UpperCAmelCase						)
             self.block_filenames.append(_UpperCAmelCase						)




      def 							lowerCamelCase     (					self						):
             return self.block_filenames




      def 							lowerCamelCase     (					self  ,		_UpperCAmelCase  ,		_UpperCAmelCase=None						):
             UpperCAmelCase__	:   Optional[int]												=	0
             with open(self.filename						) as file:
                    while True:
                           UpperCAmelCase__	:   List[Any]												=	file.readlines(_UpperCAmelCase						)

                           if lines == []:
                                  break

                           if sort_key is None:
                                  lines.sort()
                           else:
                                  lines.sort(key=_UpperCAmelCase						)

                           self.write_block(''''''.join(_UpperCAmelCase						)  ,		_UpperCAmelCase						)
                           i += 1




      def 							lowerCamelCase     (					self						):
             map(os.remove  ,		self.block_filenames						)




class 					__UpperCAmelCase :

      '''simple docstring'''





      def 							lowerCamelCase     (					self  ,		_UpperCAmelCase						):
             UpperCAmelCase__	:   str												=	-1
             UpperCAmelCase__	:   Dict												=	None

             for i in range(len(_UpperCAmelCase						)						):
                    if min_str is None or choices[i] < min_str:
                           UpperCAmelCase__	:   Tuple												=	i

             return min_index




class 					__UpperCAmelCase :

      '''simple docstring'''





      def __init__(					self  ,		_UpperCAmelCase						):
             UpperCAmelCase__	:   Any												=	files
             UpperCAmelCase__	:   Dict												=	set()
             UpperCAmelCase__	:   int												=	len(_UpperCAmelCase						)
             UpperCAmelCase__	:   List[Any]												=	{i: None for i in range(self.num_buffers						)}




      def 							lowerCamelCase     (					self						):
             return {
                 i: self.buffers[i] for i in range(self.num_buffers						) if i not in self.empty
             }




      def 							lowerCamelCase     (					self						):
             for i in range(self.num_buffers						):
                    if self.buffers[i] is None and i not in self.empty:
                           UpperCAmelCase__	:   Optional[Any]												=	self.files[i].readline()

                           if self.buffers[i] == "":
                                  self.empty.add(_UpperCAmelCase						)
                                  self.files[i].close()

             if len(self.empty						) == self.num_buffers:
                    return False

             return True




      def 							lowerCamelCase     (					self  ,		_UpperCAmelCase						):
             UpperCAmelCase__	:   int												=	self.buffers[index]
             UpperCAmelCase__	:   Union[str, Any]												=	None

             return value




class 					__UpperCAmelCase :

      '''simple docstring'''





      def __init__(					self  ,		_UpperCAmelCase						):
             UpperCAmelCase__	:   Optional[int]												=	merge_strategy




      def 							lowerCamelCase     (					self  ,		_UpperCAmelCase  ,		_UpperCAmelCase  ,		_UpperCAmelCase						):
             UpperCAmelCase__	:   Union[str, Any]												=	FilesArray(self.get_file_handles(_UpperCAmelCase  ,		_UpperCAmelCase						)						)
             with open(_UpperCAmelCase  ,		'''w'''  ,		_UpperCAmelCase						) as outfile:
                    while buffers.refresh():
                           UpperCAmelCase__	:   Dict												=	self.merge_strategy.select(buffers.get_dict()						)
                           outfile.write(buffers.unshift(_UpperCAmelCase						)						)




      def 							lowerCamelCase     (					self  ,		_UpperCAmelCase  ,		_UpperCAmelCase						):
             UpperCAmelCase__	:   Optional[int]												=	{}

             for i in range(len(_UpperCAmelCase						)						):
                    UpperCAmelCase__	:   List[str]												=	open(filenames[i]  ,		'''r'''  ,		_UpperCAmelCase						)  # noqa: UP015

             return files




class 					__UpperCAmelCase :

      '''simple docstring'''





      def __init__(					self  ,		_UpperCAmelCase						):
             UpperCAmelCase__	:   Optional[Any]												=	block_size




      def 							lowerCamelCase     (					self  ,		_UpperCAmelCase  ,		_UpperCAmelCase=None						):
             UpperCAmelCase__	:   str												=	self.get_number_blocks(_UpperCAmelCase  ,		self.block_size						)
             UpperCAmelCase__	:   List[str]												=	FileSplitter(_UpperCAmelCase						)
             splitter.split(self.block_size  ,		_UpperCAmelCase						)

             UpperCAmelCase__	:   Optional[Any]												=	FileMerger(NWayMerge()						)
             UpperCAmelCase__	:   Optional[Any]												=	self.block_size / (num_blocks + 1)
             merger.merge(splitter.get_block_filenames()  ,		filename + '''.out'''  ,		_UpperCAmelCase						)

             splitter.cleanup()




      def 							lowerCamelCase     (					self  ,		_UpperCAmelCase  ,		_UpperCAmelCase						):
             return (os.stat(_UpperCAmelCase						).st_size / block_size) + 1






def  lowerCAmelCase__		(					a_  :     int			)   -> Optional[int]:
       if string[-1].lower() == "k":
              return int(string[:-1]			) * 1_0_2_4
       elif string[-1].lower() == "m":
              return int(string[:-1]			) * 1_0_2_4 * 1_0_2_4
       elif string[-1].lower() == "g":
              return int(string[:-1]			) * 1_0_2_4 * 1_0_2_4 * 1_0_2_4
       else:
              return int(a_			)






def  lowerCAmelCase__		(					)   -> Optional[Any]:
       UpperCAmelCase__	:   Tuple												=	argparse.ArgumentParser()
       parser.add_argument(
           '''-m'''			,						'''--mem'''			,						help='''amount of memory to use for sorting'''			,						default='''100M'''			)
       parser.add_argument(
           '''filename'''			,						metavar='''<filename>'''			,						nargs=1			,						help='''name of file to sort'''			)
       UpperCAmelCase__	:   List[str]												=	parser.parse_args()

       UpperCAmelCase__	:   Dict												=	ExternalSort(parse_memory(args.mem			)			)
       sorter.sort(args.filename[0]			)


if __name__ == "__main__":
  main()







'''simple docstring'''







import re






def  lowerCAmelCase__		(					a_  :     Optional[int]			)   -> Optional[Any]:
       def docstring_decorator(a_  :     Dict			):
              UpperCAmelCase__	:   Optional[int]												=	fn.__doc__
              UpperCAmelCase__	:   Dict												=	func_doc.split('''\n'''			)
              UpperCAmelCase__	:   Any												=	0
              while i < len(a_			) and re.search(r'''^\s*Examples?:\s*$'''			,						lines[i]			) is None:
                     i += 1
              if i < len(a_			):
                     UpperCAmelCase__	:   List[Any]												=	example_docstring
                     UpperCAmelCase__	:   int												=	'''\n'''.join(a_			)
              else:
                     raise ValueError(
                         f"""The function {fn} should have an empty 'Examples:' in its docstring as placeholder, """
                         f"""current docstring is:\n{func_doc}"""			)
              UpperCAmelCase__	:   Any												=	func_doc
              return fn

       return docstring_decorator