Advertisement
CosmicFox33

directoryindex

Dec 29th, 2022
817
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.90 KB | None | 0 0
  1. from os import walk
  2. from os.path import join as osjoin
  3. from string import punctuation
  4. import pickle
  5.  
  6. class DirectoryIndex:
  7.     def __init__(self, dirpath: str, encoding: str='utf-8'):
  8.         self.dirpath = dirpath
  9.         self.encoding = encoding
  10.         self.__index = dict()
  11.         self.__filekeys = dict()
  12.         self.__filenames = []
  13.        
  14.     def find_documents(self, word: str) -> list:
  15.         documents = self.__index.get(word, 'Слово не найдено')
  16.         if type(documents) is set: #если по ключу word найдено множество документов, то сортируем его и возвращаем
  17.             return sorted(documents)
  18.         return documents
  19.  
  20.     def get_filekeys(self):
  21.         #приводим путь до файла в читаемый вид
  22.         return {key: osjoin(value[0], value[1]) for key, value in self.__filekeys.items()}
  23.  
  24.     def update(self, filepath: str, encoding: str='utf-8'):
  25.         *path, file = filepath[3:].split('\\') #убираем из пути 3 символа с именем диска
  26.         next_idx = list(self.__filekeys.keys())[-1] + 1 #создаем новый индекс, который на 1 больше последнего (максимального)
  27.         self.__filenames.append((filepath[:3]+'\\'.join(path), file))
  28.         self.__filekeys[next_idx] = (filepath[:3]+'\\'.join(path), file)
  29.         words = self.__get_filtered_words(filepath)
  30.  
  31.         for word in words:
  32.             if not self.__index.get(word): #если слово не встречается в индексе, создаём для него пустое множество
  33.                 self.__index[word] = set()
  34.             self.__index.get(word).add(next_idx)
  35.    
  36.     def save(self):
  37.         #выгрузка индекса и ключей файлов с помощью pickle
  38.         with open(osjoin(self.dirpath, 'index.pickle'), 'wb') as f:
  39.             pickle.dump(self.__index, f)
  40.         with open(osjoin(self.dirpath, 'filekeys.pickle'), 'wb') as f:
  41.             pickle.dump(self.get_filekeys(), f)
  42.  
  43.     def __get_files(self, path):
  44.         for root, dirs, files in walk(path):
  45.             self.__filenames.extend((path, file) for file in files)
  46.             if dirs:
  47.                 for _dir in dirs:
  48.                     self.__get_files(osjoin(path, _dir))
  49.    
  50.     def __get_filtered_words(self, filepath):
  51.         with open(filepath, 'r') as f:
  52.             text = f.read()
  53.         text = text.lower().replace('\n', ' ').replace('\t', ' ') #делаем буквы строчными, заменяем переводы строки и табуляции на пробелы, чтобы убрать их
  54.         return filter(lambda x: len(x) > 0, (map(str.strip, text.translate(str.maketrans('', '', punctuation)).split())))
  55.  
  56.     @property
  57.     def inverted_index(self):
  58.         if not self.__index:
  59.             self.__get_files(self.dirpath)
  60.             #нумеруем все имена файлов уникальными ключами
  61.             self.__filekeys = dict(enumerate(self.__filenames))
  62.            
  63.             for idx, (path, file) in self.__filekeys.items():
  64.                 words = self.__get_filtered_words(osjoin(path, file))
  65.                 for word in words:
  66.                     if not self.__index.get(word):
  67.                         self.__index[word] = set()
  68.                     self.__index.get(word).add(idx)
  69.         return self.__index
  70.  
  71. index = DirectoryIndex('C:\\dataset')
  72. index.inverted_index
  73. print(index.find_documents(input('Введите слово для поиска по индексу: ')))
  74. print(f'Соответствие ключей и файлов: {index.get_filekeys()}')
  75. index.update('C:\\new\\newfile')
  76. print(index.find_documents('updating'))
  77. print(f'Соответствие ключей и файлов: {index.get_filekeys()}')
  78. index.save()
  79.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement