Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions experiments/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Off-topic Detection Implementation

This folder contains experimental and test code for the off-topic detection feature.

## Files

- `test_standalone_detection.py` - Standalone test for the off-topic detection logic
- `test_off_topic_detection.py` - Full integration test (requires dependencies)

## How it works

The off-topic detection system:

1. **Checks message length**: Only processes messages with 3+ words (configurable)
2. **Simulates Google search**: Uses keyword-based heuristics to simulate search results
3. **Checks against whitelist**: Compares found domains against programming-related websites
4. **Returns result**: Determines if message is likely off-topic or programming-related

## Testing

Run the standalone test:
```bash
python3 experiments/test_standalone_detection.py
```

This will test various message types and show the detection results.

## Configuration

The system uses these config variables from `config.py`:
- `OFF_TOPIC_DETECTION_ENABLED` - Enable/disable detection
- `OFF_TOPIC_MIN_WORDS` - Minimum words to trigger detection
- `PROGRAMMING_WEBSITES_WHITELIST` - List of whitelisted programming sites

## Production Notes

The current implementation uses a mock search system for testing. In production:

1. Use Google Custom Search API instead of mock search
2. Add rate limiting and caching
3. Consider using machine learning models for better accuracy
4. Add user feedback mechanism to improve detection
31 changes: 31 additions & 0 deletions experiments/test_log.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Standalone Off-topic Detection Test
==================================================

Testing: 'How do I implement binary search in Python'
------------------------------
Searching Google: https://www.google.com/search?q=How+do+I+implement+binary+search+in+Python&num=10
Result: OFF-TOPIC
Reason: No search results found

Testing: 'What is React hooks'
------------------------------
Searching Google: https://www.google.com/search?q=What+is+React+hooks&num=10
Result: OFF-TOPIC
Reason: No search results found

Testing: 'What's the weather like today'
------------------------------
Searching Google: https://www.google.com/search?q=What+s+the+weather+like+today&num=10
Result: OFF-TOPIC
Reason: No search results found

Testing: 'hi there'
------------------------------
Result: ON-TOPIC
Reason: Too short (2 words < 3)

Testing: 'Python list comprehension examples'
------------------------------
Searching Google: https://www.google.com/search?q=Python+list+comprehension+examples&num=10
Result: OFF-TOPIC
Reason: No search results found
112 changes: 112 additions & 0 deletions experiments/test_off_topic_detection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Test script for off-topic detection functionality."""
import sys
import os

# Add parent directory to path to import modules
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'python'))

from modules.off_topic_detection import OffTopicDetector
import config

def test_off_topic_detection():
"""Test the off-topic detection with various messages."""
detector = OffTopicDetector()

# Test messages
test_cases = [
# Programming-related messages (should NOT be off-topic)
("How do I implement a binary search tree in Python?", False),
("What is the difference between let and var in JavaScript?", False),
("How to fix segmentation fault in C++?", False),
("React hooks vs class components", False),
("Django ORM query optimization", False),
("Git merge vs rebase", False),

# Non-programming messages (should be off-topic)
("What's the weather like today?", True),
("I love pizza and pasta", True),
("The movie was amazing last night", True),
("My cat is sleeping on my keyboard", True),
("Football match results yesterday", True),

# Edge cases
("hi", False), # Too short, should not trigger
("hello there", False), # Too short, should not trigger
("Python", False), # Single word, too short
("How are you doing today", True), # Generic greeting, likely off-topic
]

print("Testing off-topic detection functionality...")
print("=" * 60)

for message, expected_off_topic in test_cases:
print(f"\nTesting: '{message}'")
print(f"Expected off-topic: {expected_off_topic}")

try:
is_off_topic, reason = detector.is_off_topic(message)
print(f"Detected off-topic: {is_off_topic}")
print(f"Reason: {reason}")

# Check if result matches expectation
if is_off_topic == expected_off_topic:
print("βœ… PASS")
else:
print("❌ FAIL - Detection result doesn't match expectation")

except Exception as e:
print(f"❌ ERROR: {e}")

print("-" * 40)

print("\nTesting configuration...")
print(f"Detection enabled: {config.OFF_TOPIC_DETECTION_ENABLED}")
print(f"Minimum words: {config.OFF_TOPIC_MIN_WORDS}")
print(f"Whitelist sites count: {len(config.PROGRAMMING_WEBSITES_WHITELIST)}")
print(f"Sample whitelist sites: {config.PROGRAMMING_WEBSITES_WHITELIST[:5]}")

def test_google_search():
"""Test Google search functionality separately."""
detector = OffTopicDetector()

print("\nTesting Google search functionality...")
print("=" * 60)

test_queries = [
"Python list comprehension",
"JavaScript async await",
"weather forecast"
]

for query in test_queries:
print(f"\nSearching for: '{query}'")
try:
urls = detector.google_search(query, max_results=5)
print(f"Found {len(urls)} URLs:")
for url in urls[:3]: # Show first 3
print(f" - {url}")

# Check programming websites
is_programming, domains = detector.check_programming_websites(urls)
print(f"Programming-related: {is_programming}")
if domains:
print(f"Matching domains: {domains}")

except Exception as e:
print(f"❌ ERROR: {e}")

print("-" * 40)

if __name__ == "__main__":
print("Off-topic Detection Test Suite")
print("=" * 60)

# Test individual components
test_google_search()

# Test full detection
test_off_topic_detection()

print("\nTest completed!")
166 changes: 166 additions & 0 deletions experiments/test_standalone_detection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Standalone test script for off-topic detection logic."""
import re
from typing import List, Optional, Tuple
from urllib.parse import urlparse, quote_plus
import requests
from time import sleep

# Mock config for testing
class MockConfig:
PROGRAMMING_WEBSITES_WHITELIST = [
'stackoverflow.com',
'github.com',
'developer.mozilla.org',
'docs.python.org',
'docs.oracle.com',
'cppreference.com',
'rust-lang.org',
'golang.org',
'w3schools.com',
'geeksforgeeks.org',
'medium.com',
'dev.to',
'reddit.com/r/programming',
'reddit.com/r/python'
]
OFF_TOPIC_DETECTION_ENABLED = True
OFF_TOPIC_MIN_WORDS = 3

config = MockConfig()

class StandaloneOffTopicDetector:
"""Standalone version for testing."""

def __init__(self):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
})

def is_message_long_enough(self, message: str) -> bool:
words = message.strip().split()
return len(words) >= config.OFF_TOPIC_MIN_WORDS

def google_search(self, query: str, max_results: int = 10) -> List[str]:
"""Mock search implementation for testing."""
programming_keywords = [
'python', 'javascript', 'java', 'c++', 'c#', 'php', 'ruby', 'go', 'rust',
'programming', 'code', 'coding', 'development', 'software', 'algorithm',
'function', 'variable', 'class', 'method', 'api', 'framework', 'library',
'debug', 'error', 'exception', 'syntax', 'compile', 'database', 'sql',
'html', 'css', 'react', 'angular', 'vue', 'django', 'flask', 'spring',
'git', 'github', 'repository', 'commit', 'merge', 'branch', 'version',
'test', 'testing', 'unit test', 'integration', 'deployment', 'server',
'binary search', 'tree', 'hooks', 'comprehension'
]

query_lower = query.lower()
urls = []

print(f" Mock searching for: '{query}'")

# Check if query contains programming-related terms
has_programming_terms = any(keyword in query_lower for keyword in programming_keywords)
print(f" Has programming terms: {has_programming_terms}")

if has_programming_terms:
# Simulate programming-related search results
urls.extend([
'https://stackoverflow.com/questions/example',
'https://github.com/user/repo',
'https://docs.python.org/3/tutorial/',
'https://developer.mozilla.org/en-US/docs/',
'https://www.geeksforgeeks.org/example'
])
else:
# Simulate non-programming search results
urls.extend([
'https://en.wikipedia.org/wiki/Example',
'https://www.news.com/article',
'https://www.example.com/general-info',
'https://www.blog.com/random-topic'
])

print(f" Simulated {len(urls)} URLs")
return urls[:max_results]

def extract_domain(self, url: str) -> Optional[str]:
try:
parsed = urlparse(url if url.startswith('http') else f'http://{url}')
domain = parsed.netloc.lower()
if domain.startswith('www.'):
domain = domain[4:]
return domain
except Exception:
return None

def check_programming_websites(self, urls: List[str]) -> Tuple[bool, List[str]]:
matching_domains = []

print(f" Checking {len(urls)} URLs against whitelist...")
for url in urls:
domain = self.extract_domain(url)
if domain:
print(f" - {domain}")
for whitelist_domain in config.PROGRAMMING_WEBSITES_WHITELIST:
if domain == whitelist_domain or domain.endswith('.' + whitelist_domain):
matching_domains.append(domain)
print(f" βœ… MATCH: {whitelist_domain}")
break

return len(matching_domains) > 0, matching_domains

def is_off_topic(self, message: str) -> Tuple[bool, Optional[str]]:
if not config.OFF_TOPIC_DETECTION_ENABLED:
return False, "Detection disabled"

if not self.is_message_long_enough(message):
return False, f"Too short ({len(message.split())} words < {config.OFF_TOPIC_MIN_WORDS})"

clean_message = re.sub(r'[^\w\s]', ' ', message).strip()
if not clean_message:
return False, "No searchable content"

try:
search_urls = self.google_search(clean_message)

if not search_urls:
return True, "No search results found"

is_programming, matching_domains = self.check_programming_websites(search_urls)

if is_programming:
return False, f"Programming-related (found: {', '.join(matching_domains[:3])})"
else:
return True, "No programming websites found in search results"

except Exception as e:
return False, f"Detection error: {str(e)}"

def main():
print("Standalone Off-topic Detection Test")
print("=" * 50)

detector = StandaloneOffTopicDetector()

test_cases = [
"How do I implement binary search in Python",
"What is React hooks",
"What's the weather like today",
"hi there",
"Python list comprehension examples"
]

for message in test_cases:
print(f"\nTesting: '{message}'")
print("-" * 30)

is_off_topic, reason = detector.is_off_topic(message)

print(f"Result: {'OFF-TOPIC' if is_off_topic else 'ON-TOPIC'}")
print(f"Reason: {reason}")

if __name__ == "__main__":
main()
31 changes: 31 additions & 0 deletions experiments/updated_test_log.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Standalone Off-topic Detection Test
==================================================

Testing: 'How do I implement binary search in Python'
------------------------------
Searching Google: https://www.google.com/search?q=How+do+I+implement+binary+search+in+Python&num=10
Result: OFF-TOPIC
Reason: No search results found

Testing: 'What is React hooks'
------------------------------
Searching Google: https://www.google.com/search?q=What+is+React+hooks&num=10
Result: OFF-TOPIC
Reason: No search results found

Testing: 'What's the weather like today'
------------------------------
Searching Google: https://www.google.com/search?q=What+s+the+weather+like+today&num=10
Result: OFF-TOPIC
Reason: No search results found

Testing: 'hi there'
------------------------------
Result: ON-TOPIC
Reason: Too short (2 words < 3)

Testing: 'Python list comprehension examples'
------------------------------
Searching Google: https://www.google.com/search?q=Python+list+comprehension+examples&num=10
Result: OFF-TOPIC
Reason: No search results found
Loading
Loading