|
3 | 3 | from stack import Stack |
4 | 4 | from index import InvertedIndex |
5 | 5 |
|
| 6 | +# Path to the folder that has all text files |
| 7 | +PATH = "./documents" # First we go to base dir |
| 8 | + |
6 | 9 | class SearchSim: |
7 | | - """Search engine simulation using Inverted Index + Stack (for history).""" |
| 10 | + """A simple search engine simulation.""" |
8 | 11 |
|
9 | | - def __init__(self, path="./"): |
10 | | - self.index = InvertedIndex() |
11 | | - self.history = Stack() |
12 | | - self.path = path |
13 | | - self.results = [] |
14 | | - self._load() |
| 12 | + def __init__(self, path=PATH): |
| 13 | + self.index = InvertedIndex() # for word search |
| 14 | + self.history = Stack() # to store search history |
| 15 | + self.path = path # folder path |
| 16 | + self.results = [] # last search results |
| 17 | + self._load() # load documents into index |
15 | 18 |
|
16 | 19 | def _load(self): |
17 | | - print("Building index...") |
| 20 | + """Load all text files and build the index.""" |
| 21 | + print("Loading index...") |
18 | 22 | try: |
19 | 23 | files = [f for f in os.listdir(self.path) if f.endswith(".txt")] |
20 | 24 | if not files: |
21 | | - print("No .txt files in documents/") |
| 25 | + print("No .txt files found in documents folder.") |
22 | 26 | for f in files: |
23 | | - doc = os.path.splitext(f)[0] |
| 27 | + doc = os.path.splitext(f)[0] # filename without .txt |
24 | 28 | with open(os.path.join(self.path, f), "r", encoding="utf-8") as file: |
25 | 29 | self.index.add_doc(doc, file.read()) |
26 | | - print(f"Index built with {len(files)} docs.") |
| 30 | + print(f"Index built with {len(files)} documents.") |
27 | 31 | except FileNotFoundError: |
28 | | - print("documents/ folder not found.") |
| 32 | + print("Documents folder not found!") |
29 | 33 | exit() |
30 | 34 |
|
31 | 35 | def run(self): |
| 36 | + """Main loop for user interaction.""" |
32 | 37 | while True: |
33 | | - user_input = input("\nEnter search query, 'back', 'show', or 'quit': ").strip() |
34 | | - if user_input.lower() == "quit": |
| 38 | + user_input = input("\nEnter search query, 'back', 'show', or 'quit': ").strip().lower() |
| 39 | + |
| 40 | + if user_input == "quit": |
| 41 | + print("Goodbye!") |
35 | 42 | break |
36 | | - elif user_input.lower() == "back": |
| 43 | + elif user_input == "back": |
37 | 44 | self._back() |
38 | | - elif user_input.lower() == "show": |
| 45 | + elif user_input == "show": |
39 | 46 | self.history.show() |
40 | | - else: |
| 47 | + elif user_input: # if user typed something |
41 | 48 | self._search(user_input) |
42 | 49 |
|
43 | | - def _search(self, q): |
44 | | - self.history.push(q) |
45 | | - print(f"\nSearching: '{q}'") |
46 | | - self.results = self.index.search(q) |
| 50 | + def _search(self, query): |
| 51 | + """Handle search queries.""" |
| 52 | + self.history.push(query) |
| 53 | + print(f"\nSearching for: '{query}'") |
47 | 54 |
|
| 55 | + self.results = self.index.search(query) |
48 | 56 | if not self.results: |
49 | | - print("No matches.") |
| 57 | + print("No matches found.") |
50 | 58 | return |
51 | 59 |
|
52 | | - print(f"Found {len(self.results)} docs:") |
53 | | - for i, r in enumerate(self.results, 1): |
| 60 | + print(f"Found {len(self.results)} document(s):") |
| 61 | + for i, r in enumerate(self.results, start=1): |
54 | 62 | print(f"{i}. {r['doc']}.txt | Score: {r['score']}") |
55 | 63 |
|
56 | 64 | self._open_doc() |
57 | 65 |
|
58 | 66 | def _open_doc(self): |
| 67 | + """Open and show the contents of a selected document.""" |
59 | 68 | while True: |
60 | | - sel = input("\nEnter doc number to open, or 'next': ").strip().lower() |
61 | | - if sel == "next": |
| 69 | + choice = input("\nEnter document number to open, or 'next': ").strip().lower() |
| 70 | + if choice == "next": |
62 | 71 | break |
63 | 72 | try: |
64 | | - i = int(sel) |
65 | | - if 1 <= i <= len(self.results): |
66 | | - doc = self.results[i - 1]["doc"] |
| 73 | + num = int(choice) |
| 74 | + if 1 <= num <= len(self.results): |
| 75 | + doc = self.results[num - 1]["doc"] |
67 | 76 | with open(os.path.join(self.path, f"{doc}.txt"), "r", encoding="utf-8") as f: |
68 | 77 | print(f"\n--- {doc}.txt ---\n{f.read()}\n------------------") |
69 | 78 | else: |
70 | 79 | print("Invalid number.") |
71 | 80 | except ValueError: |
72 | | - print("Enter a number or 'next'.") |
| 81 | + print("Please enter a valid number or 'next'.") |
73 | 82 | except FileNotFoundError: |
74 | 83 | print("File not found.") |
75 | 84 |
|
76 | 85 | def _back(self): |
| 86 | + """Go back to the previous search query.""" |
77 | 87 | if len(self.history.items) <= 1: |
78 | | - print("No previous search.") |
| 88 | + print("No previous search available.") |
79 | 89 | return |
80 | | - self.history.pop() |
81 | | - prev = self.history.peek() |
82 | | - print(f"\nBack to: '{prev}'") |
83 | | - self.results = self.index.search(prev) |
| 90 | + |
| 91 | + self.history.pop() # remove current search |
| 92 | + prev_query = self.history.peek() # last one left |
| 93 | + print(f"\nBack to: '{prev_query}'") |
| 94 | + |
| 95 | + self.results = self.index.search(prev_query) |
84 | 96 | if not self.results: |
85 | | - print("No matches.") |
| 97 | + print("No matches found.") |
86 | 98 | else: |
87 | | - for i, r in enumerate(self.results, 1): |
| 99 | + for i, r in enumerate(self.results, start=1): |
88 | 100 | print(f"{i}. {r['doc']}.txt | Score: {r['score']}") |
89 | 101 | self._open_doc() |
0 commit comments