Spaces:
Sleeping
Sleeping
better adapted for interview questions
Browse files- README.md +42 -4
- app_hf.py +1 -1
- queryrun.py +139 -11
- requirements_downloader.txt +1 -0
- test_interview_questions.py +89 -0
README.md
CHANGED
|
@@ -8,9 +8,16 @@ app_file: app_hf.py
|
|
| 8 |
pinned: false
|
| 9 |
---
|
| 10 |
|
| 11 |
-
# RAG API with
|
| 12 |
|
| 13 |
-
This is
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
## API Endpoints
|
| 16 |
|
|
@@ -24,8 +31,39 @@ This is a RAG (Retrieval-Augmented Generation) API deployed on Hugging Face Spac
|
|
| 24 |
}
|
| 25 |
```
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
## Local Development
|
|
|
|
| 28 |
1. Clone this repository
|
| 29 |
2. Install dependencies: `pip install -r requirements_hf.txt`
|
| 30 |
-
3. Set up environment variables in `.env`
|
| 31 |
-
4. Run: `python app_hf.py`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
pinned: false
|
| 9 |
---
|
| 10 |
|
| 11 |
+
# Enhanced RAG API with Interview-Style Question Support
|
| 12 |
|
| 13 |
+
This is an enhanced RAG (Retrieval-Augmented Generation) API deployed on Hugging Face Spaces with hybrid AI support for interview-style questions.
|
| 14 |
+
|
| 15 |
+
## Features
|
| 16 |
+
|
| 17 |
+
- **DeepSeek-Powered**: Uses DeepSeek as the primary response generator for all questions
|
| 18 |
+
- **Enhanced Responses**: DeepSeek provides more engaging, first-person responses
|
| 19 |
+
- **Fallback Support**: Gracefully falls back to Cohere if DeepSeek is unavailable
|
| 20 |
+
- **Context-Aware**: Uses retrieved documents to provide specific examples and details
|
| 21 |
|
| 22 |
## API Endpoints
|
| 23 |
|
|
|
|
| 31 |
}
|
| 32 |
```
|
| 33 |
|
| 34 |
+
## Environment Variables
|
| 35 |
+
|
| 36 |
+
Create a `.env` file with the following variables:
|
| 37 |
+
|
| 38 |
+
```env
|
| 39 |
+
# Cohere API key (required for basic RAG functionality)
|
| 40 |
+
COHEREAPIKEY=your_cohere_api_key_here
|
| 41 |
+
|
| 42 |
+
# DeepSeek API key (required for enhanced interview-style question handling)
|
| 43 |
+
DEEPKEY=your_deepseek_api_key_here
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
## Local Development
|
| 47 |
+
|
| 48 |
1. Clone this repository
|
| 49 |
2. Install dependencies: `pip install -r requirements_hf.txt`
|
| 50 |
+
3. Set up environment variables in `.env` (see above)
|
| 51 |
+
4. Run the main application: `python app_hf.py`
|
| 52 |
+
5. Or test the system: `python test_interview_questions.py`
|
| 53 |
+
|
| 54 |
+
## Response Generation
|
| 55 |
+
|
| 56 |
+
The system uses DeepSeek as the primary response generator for all questions, providing:
|
| 57 |
+
|
| 58 |
+
- **Engaging First-Person Responses**: Answers as if Julien is speaking directly
|
| 59 |
+
- **Context-Aware Answers**: Uses retrieved documents for specific examples
|
| 60 |
+
- **Professional Tone**: Maintains appropriate level of formality
|
| 61 |
+
- **Comprehensive Coverage**: Handles technical, personal, and general questions
|
| 62 |
+
|
| 63 |
+
### Question Examples:
|
| 64 |
+
- "What is your educational background?"
|
| 65 |
+
- "Tell me about a challenging project you worked on..."
|
| 66 |
+
- "What programming languages do you know?"
|
| 67 |
+
- "Describe your experience with machine learning..."
|
| 68 |
+
- "What are your research interests?"
|
| 69 |
+
- "Walk me through your journey in computer science..."
|
app_hf.py
CHANGED
|
@@ -43,7 +43,7 @@ def handle_query():
|
|
| 43 |
print(f"Received query: {query}")
|
| 44 |
|
| 45 |
search_results = query_system.search(query, k=5)
|
| 46 |
-
response_text = query_system.
|
| 47 |
|
| 48 |
sources_for_response = [
|
| 49 |
{
|
|
|
|
| 43 |
print(f"Received query: {query}")
|
| 44 |
|
| 45 |
search_results = query_system.search(query, k=5)
|
| 46 |
+
response_text = query_system.generate_hybrid_response(query, search_results)
|
| 47 |
|
| 48 |
sources_for_response = [
|
| 49 |
{
|
queryrun.py
CHANGED
|
@@ -8,18 +8,22 @@ from dotenv import load_dotenv
|
|
| 8 |
from langchain_community.docstore.document import Document
|
| 9 |
# Corrected import based on the deprecation warning
|
| 10 |
from langchain_community.docstore.in_memory import InMemoryDocstore
|
| 11 |
-
|
| 12 |
|
| 13 |
# Load environment variables
|
| 14 |
load_dotenv()
|
| 15 |
cohere_api_key = os.getenv("COHEREAPIKEY")
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
# DeepSeek client initialization
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
# Initialize Cohere client
|
| 25 |
if not cohere_api_key:
|
|
@@ -238,6 +242,44 @@ class FAISSQuerySystem:
|
|
| 238 |
traceback.print_exc()
|
| 239 |
raise
|
| 240 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
def preprocess_query(self, query):
|
| 242 |
"""Preprocess query to improve retrieval and context understanding"""
|
| 243 |
if not isinstance(query, str):
|
|
@@ -329,6 +371,92 @@ class FAISSQuerySystem:
|
|
| 329 |
results.sort(key=lambda x: x['score'], reverse=True)
|
| 330 |
return results
|
| 331 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
def generate_response(self, query, context_docs):
|
| 333 |
"""Generate RAG response using Cohere's chat API"""
|
| 334 |
if not context_docs:
|
|
@@ -412,7 +540,7 @@ def main():
|
|
| 412 |
|
| 413 |
if not docs:
|
| 414 |
print("Could not find relevant documents in the knowledge base.")
|
| 415 |
-
response = query_system.
|
| 416 |
print("\nResponse:")
|
| 417 |
print("-" * 50)
|
| 418 |
print(response)
|
|
@@ -421,9 +549,9 @@ def main():
|
|
| 421 |
|
| 422 |
print(f"Found {len(docs)} relevant document chunks.")
|
| 423 |
|
| 424 |
-
# 2. Generate and display response using RAG
|
| 425 |
print("Generating response based on documents...")
|
| 426 |
-
response = query_system.
|
| 427 |
print("\nResponse:")
|
| 428 |
print("-" * 50)
|
| 429 |
print(response)
|
|
|
|
| 8 |
from langchain_community.docstore.document import Document
|
| 9 |
# Corrected import based on the deprecation warning
|
| 10 |
from langchain_community.docstore.in_memory import InMemoryDocstore
|
| 11 |
+
from openai import OpenAI # DeepSeek API for interview-style questions
|
| 12 |
|
| 13 |
# Load environment variables
|
| 14 |
load_dotenv()
|
| 15 |
cohere_api_key = os.getenv("COHEREAPIKEY")
|
| 16 |
+
deepseek_api_key = os.getenv("DEEPKEY") # DeepSeek API key for enhanced responses
|
| 17 |
+
|
| 18 |
+
# DeepSeek client initialization
|
| 19 |
+
if deepseek_api_key:
|
| 20 |
+
deepseek_client = OpenAI(
|
| 21 |
+
api_key=deepseek_api_key,
|
| 22 |
+
base_url="https://api.deepseek.com/v1"
|
| 23 |
+
)
|
| 24 |
+
else:
|
| 25 |
+
deepseek_client = None
|
| 26 |
+
print("Warning: DEEPKEY not found. DeepSeek features will be disabled.")
|
| 27 |
|
| 28 |
# Initialize Cohere client
|
| 29 |
if not cohere_api_key:
|
|
|
|
| 242 |
traceback.print_exc()
|
| 243 |
raise
|
| 244 |
|
| 245 |
+
def is_interview_style_question(self, query):
|
| 246 |
+
"""Detect if the query is an interview-style question that would benefit from DeepSeek"""
|
| 247 |
+
query_lower = query.lower()
|
| 248 |
+
|
| 249 |
+
# Interview-style question patterns
|
| 250 |
+
interview_patterns = [
|
| 251 |
+
"tell me about", "can you tell me", "describe", "explain",
|
| 252 |
+
"what makes you", "why did you", "how did you", "what inspired",
|
| 253 |
+
"walk me through", "give me an example", "share a story",
|
| 254 |
+
"what was your role", "what challenges", "what was it like",
|
| 255 |
+
"how do you approach", "what's your experience with",
|
| 256 |
+
"what skills", "what technologies", "what projects",
|
| 257 |
+
"what's your background", "what's your journey",
|
| 258 |
+
"what are your strengths", "what are you passionate about",
|
| 259 |
+
"what motivates you", "what's your philosophy",
|
| 260 |
+
"how would you", "what would you do if",
|
| 261 |
+
"describe a time when", "tell me about a project where"
|
| 262 |
+
]
|
| 263 |
+
|
| 264 |
+
# Check for interview patterns
|
| 265 |
+
for pattern in interview_patterns:
|
| 266 |
+
if pattern in query_lower:
|
| 267 |
+
return True
|
| 268 |
+
|
| 269 |
+
# Check for question words that suggest interview context
|
| 270 |
+
question_words = ["why", "how", "what", "when", "where", "which", "who"]
|
| 271 |
+
if any(query_lower.startswith(word) for word in question_words):
|
| 272 |
+
# Additional context clues for interview questions
|
| 273 |
+
interview_context = [
|
| 274 |
+
"experience", "project", "work", "study", "research", "develop",
|
| 275 |
+
"create", "build", "learn", "achieve", "accomplish", "solve",
|
| 276 |
+
"challenge", "problem", "team", "collaborate", "lead", "manage"
|
| 277 |
+
]
|
| 278 |
+
if any(context in query_lower for context in interview_context):
|
| 279 |
+
return True
|
| 280 |
+
|
| 281 |
+
return False
|
| 282 |
+
|
| 283 |
def preprocess_query(self, query):
|
| 284 |
"""Preprocess query to improve retrieval and context understanding"""
|
| 285 |
if not isinstance(query, str):
|
|
|
|
| 371 |
results.sort(key=lambda x: x['score'], reverse=True)
|
| 372 |
return results
|
| 373 |
|
| 374 |
+
def generate_deepseek_response(self, query, context_docs):
|
| 375 |
+
"""Generate response using DeepSeek as the primary response generator"""
|
| 376 |
+
if not deepseek_client:
|
| 377 |
+
print("DeepSeek client not available, falling back to Cohere")
|
| 378 |
+
return self.generate_response(query, context_docs)
|
| 379 |
+
|
| 380 |
+
if not context_docs:
|
| 381 |
+
try:
|
| 382 |
+
response = deepseek_client.chat.completions.create(
|
| 383 |
+
model="deepseek-chat",
|
| 384 |
+
messages=[
|
| 385 |
+
{
|
| 386 |
+
"role": "system",
|
| 387 |
+
"content": "You are Julien Serbanescu, a computer science student and AI researcher. Answer questions about your background, projects, and experience in a professional, engaging manner. Be specific and provide concrete examples when possible. If you don't have specific information, acknowledge this and suggest how the user might rephrase their question."
|
| 388 |
+
},
|
| 389 |
+
{
|
| 390 |
+
"role": "user",
|
| 391 |
+
"content": f"I could not find relevant documents in my knowledge base to answer your question: '{query}'. Please provide a general response about your background and suggest how the user might rephrase their question."
|
| 392 |
+
}
|
| 393 |
+
],
|
| 394 |
+
temperature=0.7,
|
| 395 |
+
max_tokens=1000
|
| 396 |
+
)
|
| 397 |
+
return response.choices[0].message.content
|
| 398 |
+
except Exception as e:
|
| 399 |
+
print(f"Error calling DeepSeek without documents: {e}")
|
| 400 |
+
return "I could not find relevant documents and encountered an error trying to respond."
|
| 401 |
+
|
| 402 |
+
# Format context documents for DeepSeek
|
| 403 |
+
context_text = ""
|
| 404 |
+
for i, doc in enumerate(context_docs[:5]): # Limit to top 5 docs for DeepSeek
|
| 405 |
+
content = doc['content']
|
| 406 |
+
if not isinstance(content, str):
|
| 407 |
+
try:
|
| 408 |
+
content = str(content)
|
| 409 |
+
except UnicodeEncodeError:
|
| 410 |
+
import unicodedata
|
| 411 |
+
content = unicodedata.normalize('NFKD', str(content))
|
| 412 |
+
|
| 413 |
+
source = doc['metadata'].get('source', 'Unknown')
|
| 414 |
+
context_text += f"\n--- Source {i+1} ({source}) ---\n{content[:2000]}\n"
|
| 415 |
+
|
| 416 |
+
try:
|
| 417 |
+
response = deepseek_client.chat.completions.create(
|
| 418 |
+
model="deepseek-chat",
|
| 419 |
+
messages=[
|
| 420 |
+
{
|
| 421 |
+
"role": "system",
|
| 422 |
+
"content": f"""You are Julien Serbanescu, a computer engineering student and AI researcher. Answer the user's question based on the provided context documents about your background, projects, and experience.
|
| 423 |
+
|
| 424 |
+
Context about Julien Serbanescu:
|
| 425 |
+
{context_text}
|
| 426 |
+
|
| 427 |
+
Guidelines:
|
| 428 |
+
- Answer as if you are Julien speaking in first person
|
| 429 |
+
- Be specific and provide concrete examples from the context
|
| 430 |
+
- Use a professional but engaging tone
|
| 431 |
+
- If the context doesn't contain enough information, acknowledge this and provide what you can
|
| 432 |
+
- Structure your response clearly with specific examples
|
| 433 |
+
- Show enthusiasm and passion for your work
|
| 434 |
+
- For technical questions, provide detailed explanations
|
| 435 |
+
- For general questions, give comprehensive but concise answers"""
|
| 436 |
+
},
|
| 437 |
+
{
|
| 438 |
+
"role": "user",
|
| 439 |
+
"content": query
|
| 440 |
+
}
|
| 441 |
+
],
|
| 442 |
+
temperature=0.7,
|
| 443 |
+
max_tokens=1500
|
| 444 |
+
)
|
| 445 |
+
return response.choices[0].message.content
|
| 446 |
+
except Exception as e:
|
| 447 |
+
print(f"Error calling DeepSeek: {e}")
|
| 448 |
+
# Fallback to Cohere
|
| 449 |
+
return self.generate_response(query, context_docs)
|
| 450 |
+
|
| 451 |
+
def generate_hybrid_response(self, query, context_docs):
|
| 452 |
+
"""Generate response using DeepSeek as primary, with Cohere fallback"""
|
| 453 |
+
if deepseek_client:
|
| 454 |
+
print("Using DeepSeek for enhanced response...")
|
| 455 |
+
return self.generate_deepseek_response(query, context_docs)
|
| 456 |
+
else:
|
| 457 |
+
print("DeepSeek not available, using Cohere fallback...")
|
| 458 |
+
return self.generate_response(query, context_docs)
|
| 459 |
+
|
| 460 |
def generate_response(self, query, context_docs):
|
| 461 |
"""Generate RAG response using Cohere's chat API"""
|
| 462 |
if not context_docs:
|
|
|
|
| 540 |
|
| 541 |
if not docs:
|
| 542 |
print("Could not find relevant documents in the knowledge base.")
|
| 543 |
+
response = query_system.generate_hybrid_response(query, [])
|
| 544 |
print("\nResponse:")
|
| 545 |
print("-" * 50)
|
| 546 |
print(response)
|
|
|
|
| 549 |
|
| 550 |
print(f"Found {len(docs)} relevant document chunks.")
|
| 551 |
|
| 552 |
+
# 2. Generate and display response using hybrid RAG
|
| 553 |
print("Generating response based on documents...")
|
| 554 |
+
response = query_system.generate_hybrid_response(query, docs)
|
| 555 |
print("\nResponse:")
|
| 556 |
print("-" * 50)
|
| 557 |
print(response)
|
requirements_downloader.txt
CHANGED
|
@@ -5,3 +5,4 @@ requests>=2.31.0
|
|
| 5 |
pathlib2>=2.3.7; python_version < "3.4"
|
| 6 |
|
| 7 |
|
|
|
|
|
|
| 5 |
pathlib2>=2.3.7; python_version < "3.4"
|
| 6 |
|
| 7 |
|
| 8 |
+
|
test_interview_questions.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Test script to demonstrate the enhanced QA system with interview-style question handling.
|
| 4 |
+
This script tests both regular questions and interview-style questions to show the difference.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import sys
|
| 9 |
+
from dotenv import load_dotenv
|
| 10 |
+
|
| 11 |
+
# Add the current directory to Python path
|
| 12 |
+
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
| 13 |
+
|
| 14 |
+
from queryrun import FAISSQuerySystem
|
| 15 |
+
|
| 16 |
+
def test_questions():
|
| 17 |
+
"""Test various types of questions to demonstrate the DeepSeek-enhanced system"""
|
| 18 |
+
|
| 19 |
+
# Load environment variables
|
| 20 |
+
load_dotenv()
|
| 21 |
+
|
| 22 |
+
# Test questions
|
| 23 |
+
test_cases = [
|
| 24 |
+
{
|
| 25 |
+
"type": "General Question",
|
| 26 |
+
"question": "What is Julien's educational background?"
|
| 27 |
+
},
|
| 28 |
+
{
|
| 29 |
+
"type": "Interview Question",
|
| 30 |
+
"question": "Tell me about a challenging project you worked on and how you overcame the difficulties."
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"type": "Technical Question",
|
| 34 |
+
"question": "What programming languages does Julien know?"
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"type": "Experience Question",
|
| 38 |
+
"question": "Describe your experience with machine learning and what excites you most about AI research."
|
| 39 |
+
},
|
| 40 |
+
{
|
| 41 |
+
"type": "Research Question",
|
| 42 |
+
"question": "What are Julien's research interests?"
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"type": "Personal Question",
|
| 46 |
+
"question": "Walk me through your journey in computer science and what motivated you to pursue this field."
|
| 47 |
+
}
|
| 48 |
+
]
|
| 49 |
+
|
| 50 |
+
try:
|
| 51 |
+
print("Initializing RAG system...")
|
| 52 |
+
query_system = FAISSQuerySystem()
|
| 53 |
+
print("RAG system ready!\n")
|
| 54 |
+
|
| 55 |
+
for i, test_case in enumerate(test_cases, 1):
|
| 56 |
+
print(f"{'='*80}")
|
| 57 |
+
print(f"TEST CASE {i}: {test_case['type']}")
|
| 58 |
+
print(f"Question: {test_case['question']}")
|
| 59 |
+
print(f"{'='*80}")
|
| 60 |
+
|
| 61 |
+
# Search for relevant documents
|
| 62 |
+
print("\nSearching for relevant documents...")
|
| 63 |
+
docs = query_system.search(test_case['question'], k=5)
|
| 64 |
+
print(f"Found {len(docs)} relevant documents")
|
| 65 |
+
|
| 66 |
+
# Generate response using DeepSeek (with Cohere fallback)
|
| 67 |
+
print("\nGenerating response with DeepSeek...")
|
| 68 |
+
response = query_system.generate_hybrid_response(test_case['question'], docs)
|
| 69 |
+
|
| 70 |
+
print(f"\nResponse:")
|
| 71 |
+
print("-" * 60)
|
| 72 |
+
print(response)
|
| 73 |
+
print("-" * 60)
|
| 74 |
+
|
| 75 |
+
# Show sources
|
| 76 |
+
if docs:
|
| 77 |
+
print(f"\nSources used:")
|
| 78 |
+
for j, doc in enumerate(docs[:3], 1): # Show top 3 sources
|
| 79 |
+
print(f" {j}. {doc['metadata'].get('source', 'Unknown')} (score: {doc['score']:.4f})")
|
| 80 |
+
|
| 81 |
+
print(f"\n{'-'*80}\n")
|
| 82 |
+
|
| 83 |
+
except Exception as e:
|
| 84 |
+
print(f"Error during testing: {e}")
|
| 85 |
+
import traceback
|
| 86 |
+
traceback.print_exc()
|
| 87 |
+
|
| 88 |
+
if __name__ == "__main__":
|
| 89 |
+
test_questions()
|