Last active
February 27, 2019 08:04
-
-
Save nejdetckenobi/e8493d40f7d3d12977bdb87881258c56 to your computer and use it in GitHub Desktop.
A search tool with O(n) complexity for finding something with its neighbours. Useful for a file like object.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from argparse import ArgumentParser, FileType | |
parser = ArgumentParser() | |
parser.add_argument('string', type=str, help='String to find') | |
parser.add_argument('file', type=FileType(), | |
help='File to look in') | |
parser.add_argument('--neighbourhoodsize', '-ns', type=int, default=0, | |
help='Neighbourhood size') | |
parser.add_argument('--nolinenumbers', action='store_true', | |
help='Line numbers') | |
parser.add_argument('--mark', action='store_true', | |
help='Marks the important line.') | |
args = parser.parse_args() | |
def find_with_neighbours(iterator, detector, neighbourhood_size=2): | |
detected_indexes = [] | |
current_queue = [] | |
for index, item in enumerate(iterator): | |
current_queue.append(item) | |
if len(current_queue) > 2 * neighbourhood_size + 1: | |
current_queue.pop(0) | |
if detector(item): | |
detected_indexes.append(index + neighbourhood_size) | |
if index in detected_indexes: | |
yield current_queue[:], index + neighbourhood_size | |
last_index = index | |
for index in range(last_index, last_index + neighbourhood_size + 1): | |
if index in detected_indexes: | |
yield current_queue[:], index + len(current_queue) - neighbourhood_size - 1 | |
current_queue.pop(0) | |
def print_with_neighbours(neigbourhood, last_index=None, detector=None): | |
if last_index is not None: | |
first_index = last_index - len(neigbourhood) | |
index_size = len(str(last_index)) | |
for index, line in enumerate(neigbourhood, start=first_index): | |
if args.nolinenumbers: | |
print(line.strip(), end='') | |
else: | |
print('{:{}} {}'.format(index, index_size, line.strip()), end='') | |
if detector is not None and detector(line): | |
print(' <--') | |
else: | |
print('') | |
print('\n') | |
if __name__ == '__main__': | |
detector = lambda x: args.string in x | |
g = find_with_neighbours(args.file, detector, getattr(args, 'neighbourhoodsize', 2)) | |
for r, i in g: | |
print_with_neighbours(r, i, detector=detector if args.mark else None) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment