


'''simple docstring'''







#
# Sort large text files in a minimum amount of memory
#
import argparse
import os
class    lowercase_	:
    __UpperCAmelCase       =      'block_{0}.dat'


    def __init__(	self    ,   a       ):
          UpperCamelCase__      =							filename
          UpperCamelCase__      =							[]


    def   __a				(	self    ,   a    ,   a       ):
          UpperCamelCase__      =							self.BLOCK_FILENAME_FORMAT.format(a       )
          with open(a    ,   "w"       ) as file:
                file.write(a       )
          self.block_filenames.append(a       )


    def   __a				(	self       ):
          return self.block_filenames


    def   __a				(	self    ,   a    ,   a=None       ):
          UpperCamelCase__      =							0
          with open(self.filename       ) as file:
                while True:
                      UpperCamelCase__      =							file.readlines(a       )

                      if lines == []:
                            break

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

                      self.write_block("".join(a       )    ,   a       )
                      i += 1


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

class    lowercase_	:


    def   __a				(	self    ,   a       ):
          UpperCamelCase__      =							-1
          UpperCamelCase__      =							None

          for i in range(len(a       )       ):
                if min_str is None or choices[i] < min_str:
                      UpperCamelCase__      =							i

          return min_index

class    lowercase_	:


    def __init__(	self    ,   a       ):
          UpperCamelCase__      =							files
          UpperCamelCase__      =							set()
          UpperCamelCase__      =							len(a       )
          UpperCamelCase__      =							{i: None for i in range(self.num_buffers       )}


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


    def   __a				(	self       ):
          for i in range(self.num_buffers       ):
                if self.buffers[i] is None and i not in self.empty:
                      UpperCamelCase__      =							self.files[i].readline()

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

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

          return True


    def   __a				(	self    ,   a       ):
          UpperCamelCase__      =							self.buffers[index]
          UpperCamelCase__      =							None

          return value

class    lowercase_	:


    def __init__(	self    ,   a       ):
          UpperCamelCase__      =							merge_strategy


    def   __a				(	self    ,   a    ,   a    ,   a       ):
          UpperCamelCase__      =							FilesArray(self.get_file_handles(a    ,   a       )       )
          with open(a    ,   "w"    ,   a       ) as outfile:
                while buffers.refresh():
                      UpperCamelCase__      =							self.merge_strategy.select(buffers.get_dict()       )
                      outfile.write(buffers.unshift(a       )       )


    def   __a				(	self    ,   a    ,   a       ):
          UpperCamelCase__      =							{}

          for i in range(len(a       )       ):
                UpperCamelCase__      =							open(filenames[i]    ,   "r"    ,   a       )  # noqa: UP015

          return files

class    lowercase_	:


    def __init__(	self    ,   a       ):
          UpperCamelCase__      =							block_size


    def   __a				(	self    ,   a    ,   a=None       ):
          UpperCamelCase__      =							self.get_number_blocks(a    ,   self.block_size       )
          UpperCamelCase__      =							FileSplitter(a       )
          splitter.split(self.block_size    ,   a       )

          UpperCamelCase__      =							FileMerger(NWayMerge()       )
          UpperCamelCase__      =							self.block_size / (num_blocks + 1)
          merger.merge(splitter.get_block_filenames()    ,   filename + ".out"    ,   a       )

          splitter.cleanup()


    def   __a				(	self    ,   a    ,   a       ):
          return (os.stat(a       ).st_size / block_size) + 1







def _UpperCamelCase			(	__A       )				->						List[Any]:


      '''simple docstring'''



      if string[-1].lower() == "k":
            return int(string[:-1]       ) * 1024
      elif string[-1].lower() == "m":
            return int(string[:-1]       ) * 1024 * 1024
      elif string[-1].lower() == "g":
            return int(string[:-1]       ) * 1024 * 1024 * 1024
      else:
            return int(__A       )







def _UpperCamelCase			(	)				->						Optional[Any]:


      '''simple docstring'''



      UpperCamelCase__      =							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__      =							parser.parse_args()

      UpperCamelCase__      =							ExternalSort(parse_memory(args.mem       )       )
      sorter.sort(args.filename[0]       )


if __name__ == "__main__":
  main()









'''simple docstring'''







import math
from timeit import timeit







def _UpperCamelCase			(	__A       )				->						int:


      '''simple docstring'''



      UpperCamelCase__      =							0
      UpperCamelCase__      =							abs(__A       )
      while True:
            UpperCamelCase__      =							n // 10
            digits += 1
            if n == 0:
                  break
      return digits







def _UpperCamelCase			(	__A       )				->						int:


      '''simple docstring'''



      return 1 if n == 0 else math.floor(math.log(abs(__A       ) ,     10       ) + 1       )







def _UpperCamelCase			(	__A       )				->						int:


      '''simple docstring'''



      return len(str(abs(__A       )       )       )







def _UpperCamelCase			(	)				->						None:


      '''simple docstring'''



      from collections.abc import Callable

      def benchmark_a_function(__A ,     __A       ) -> None:
            UpperCamelCase__      =							F'''{func.__name__}({value})'''
            UpperCamelCase__      =							timeit(F'''__main__.{call}''' ,     setup="import __main__"       )
            print(F'''{call}: {func(__A       )} -- {timing} seconds'''       )

      for value in (262144, 1125899906842624, 1267650600228229401496703205376):
            for func in (num_digits, num_digits_fast, num_digits_faster):
                  benchmark_a_function(__A ,     __A       )
            print()


if __name__ == "__main__":
  import doctest

  doctest.testmod()
  benchmark()





