-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdoc_explorer.py
More file actions
executable file
Β·220 lines (186 loc) Β· 8.86 KB
/
Copy pathdoc_explorer.py
File metadata and controls
executable file
Β·220 lines (186 loc) Β· 8.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#!/usr/bin/env python3
"""
π Python Docs Explorer - An Interactive Documentation Tool
Surprise features included!
"""
import os
import re
import random
from pathlib import Path
from collections import defaultdict
class PythonDocsExplorer:
def __init__(self):
self.docs_dir = Path(__file__).parent
self.docs = self._load_all_docs()
self.code_snippets = self._extract_code_snippets()
def _load_all_docs(self):
"""Load all markdown documentation files"""
docs = {}
for md_file in self.docs_dir.glob("python-*.md"):
with open(md_file, 'r', encoding='utf-8') as f:
docs[md_file.stem] = f.read()
return docs
def _extract_code_snippets(self):
"""Extract all Python code snippets from documentation"""
snippets = defaultdict(list)
code_pattern = re.compile(r'```python\n(.*?)```', re.DOTALL)
for doc_name, content in self.docs.items():
matches = code_pattern.findall(content)
snippets[doc_name] = [m.strip() for m in matches if m.strip()]
return snippets
def search(self, query):
"""Search across all documentation"""
results = []
query_lower = query.lower()
for doc_name, content in self.docs.items():
lines = content.split('\n')
for i, line in enumerate(lines):
if query_lower in line.lower():
results.append({
'doc': doc_name,
'line': i + 1,
'content': line.strip()
})
return results
def random_snippet(self, topic=None):
"""Get a random code snippet, optionally filtered by topic"""
if topic and topic in self.code_snippets:
snippets = self.code_snippets[topic]
source = topic
else:
all_snippets = []
sources = []
for doc, snips in self.code_snippets.items():
all_snippets.extend(snips)
sources.extend([doc] * len(snips))
if not all_snippets:
return None, None
idx = random.randint(0, len(all_snippets) - 1)
return all_snippets[idx], sources[idx]
if snippets:
return random.choice(snippets), source
return None, None
def get_stats(self):
"""Get interesting statistics about the documentation"""
total_lines = sum(len(content.split('\n')) for content in self.docs.values())
total_code_snippets = sum(len(snippets) for snippets in self.code_snippets.values())
total_size = sum(len(content) for content in self.docs.values())
# Count common keywords
all_text = ' '.join(self.docs.values()).lower()
keywords = {
'function': len(re.findall(r'\bfunction\b', all_text)),
'class': len(re.findall(r'\bclass\b', all_text)),
'import': len(re.findall(r'\bimport\b', all_text)),
'def': len(re.findall(r'\bdef\b', all_text)),
'return': len(re.findall(r'\breturn\b', all_text)),
}
return {
'total_docs': len(self.docs),
'total_lines': total_lines,
'total_snippets': total_code_snippets,
'total_chars': total_size,
'keywords': keywords
}
def python_fact_of_the_day(self):
"""Generate a fun Python fact based on the documentation"""
facts = [
f"π This documentation contains {self.get_stats()['total_snippets']} code examples!",
f"π There are {self.get_stats()['total_lines']:,} lines of Python wisdom here!",
f"π The word 'function' appears {self.get_stats()['keywords']['function']} times in these docs!",
"π Python was named after Monty Python, not the snake!",
"β¨ Python uses indentation for code blocks, making it beautifully readable!",
f"π You have {len(self.docs)} different Python topics to explore!",
"π Python's philosophy: 'There should be one-- and preferably only one --obvious way to do it.'",
f"π» These docs contain {self.get_stats()['total_chars']:,} characters of Python knowledge!",
]
return random.choice(facts)
def interactive_menu(self):
"""Run an interactive documentation explorer"""
while True:
print("\n" + "="*60)
print("π PYTHON DOCS EXPLORER π".center(60))
print("="*60)
print("\n1. π Search documentation")
print("2. π² Random code snippet")
print("3. π Documentation statistics")
print("4. π‘ Python fact of the day")
print("5. π List all topics")
print("6. π― Quiz me! (Random snippet guess)")
print("7. πͺ Exit")
print("\n" + "-"*60)
choice = input("\nEnter your choice (1-7): ").strip()
if choice == '1':
query = input("\nπ Enter search term: ").strip()
results = self.search(query)
print(f"\n⨠Found {len(results)} results for '{query}':")
for r in results[:10]: # Show first 10
print(f" π {r['doc']}:{r['line']} - {r['content'][:80]}...")
if len(results) > 10:
print(f"\n ... and {len(results) - 10} more results")
elif choice == '2':
snippet, source = self.random_snippet()
if snippet:
print(f"\nπ² Random snippet from {source}:")
print("\n" + "β"*60)
print(snippet)
print("β"*60)
else:
print("\nβ No snippets found!")
elif choice == '3':
stats = self.get_stats()
print("\nπ Documentation Statistics:")
print(f" π Total documents: {stats['total_docs']}")
print(f" π Total lines: {stats['total_lines']:,}")
print(f" π» Code snippets: {stats['total_snippets']}")
print(f" π Total characters: {stats['total_chars']:,}")
print(f"\n π Keyword frequency:")
for kw, count in stats['keywords'].items():
print(f" {kw}: {count}")
elif choice == '4':
print(f"\nπ‘ {self.python_fact_of_the_day()}")
elif choice == '5':
print("\nπ Available topics:")
for i, doc_name in enumerate(sorted(self.docs.keys()), 1):
topic = doc_name.replace('python-', '').title()
snippets_count = len(self.code_snippets.get(doc_name, []))
print(f" {i}. {topic} ({snippets_count} code examples)")
elif choice == '6':
snippet, source = self.random_snippet()
if snippet:
print("\nπ― QUIZ TIME! What topic is this code from?")
print("\n" + "β"*60)
# Show just first few lines
lines = snippet.split('\n')[:5]
print('\n'.join(lines))
if len(snippet.split('\n')) > 5:
print("...")
print("β"*60)
input("\nπ€ Take a guess, then press Enter to reveal...")
topic = source.replace('python-', '').title()
print(f"\n⨠Answer: {topic}!")
else:
print("\nβ No snippets available for quiz!")
elif choice == '7':
print("\nπ Happy coding! May your bugs be few and your code be Pythonic! π")
break
else:
print("\nβ Invalid choice! Please enter 1-7.")
if __name__ == "__main__":
print("""
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β π SURPRISE! Python Docs Explorer π β
β β
β An interactive tool to explore your Python docs! β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
""")
explorer = PythonDocsExplorer()
# Show a welcome fact
print(f"\nπ‘ Welcome fact: {explorer.python_fact_of_the_day()}\n")
try:
explorer.interactive_menu()
except KeyboardInterrupt:
print("\n\nπ Interrupted! Goodbye!")
except Exception as e:
print(f"\nβ Error: {e}")