Trivia5 / src /modules /fact_game.py
Bharath370's picture
Upload 102 files
582bf6b verified
# modules/fact_game.py
"""Enhanced Fact Game Module"""
import random
from typing import Dict, List, Optional
from modules.api_utils import (
fetch_wikipedia_summary,
search_wikipedia,
fetch_wikidata_entity,
fetch_related_topics,
)
# Curated list of interesting topics for facts
FACT_CATEGORIES = {
"Science": [
"Quantum Entanglement",
"Black Hole",
"DNA",
"Photosynthesis",
"Theory of Relativity",
"Higgs Boson",
"Dark Matter",
"CRISPR",
"Stem Cell",
"Nanotechnology",
"Artificial Neural Network",
],
"History": [
"Ancient Egypt",
"Roman Empire",
"Renaissance",
"Industrial Revolution",
"World War II",
"Cold War",
"French Revolution",
"Ming Dynasty",
"Viking Age",
"Byzantine Empire",
"Aztec Empire",
],
"Nature": [
"Amazon Rainforest",
"Great Barrier Reef",
"Mount Everest",
"Grand Canyon",
"Antarctica",
"Sahara Desert",
"Northern Lights",
"Yellowstone",
"Galapagos Islands",
"Mariana Trench",
],
"Technology": [
"Internet",
"Blockchain",
"Quantum Computing",
"5G Technology",
"Virtual Reality",
"3D Printing",
"Robotics",
"Solar Power",
"Electric Vehicle",
"Space Exploration",
"Biotechnology",
],
"Culture": [
"Olympics",
"UNESCO",
"Nobel Prize",
"Louvre Museum",
"Great Wall of China",
"Machu Picchu",
"Taj Mahal",
"Easter Island",
"Stonehenge",
"Angkor Wat",
],
}
def extract_interesting_fact(text: str) -> str:
"""Extract the most interesting sentence from text"""
sentences = text.split(".")
# Keywords that often indicate interesting facts
interesting_keywords = [
"first",
"largest",
"smallest",
"discovered",
"invented",
"record",
"unique",
"only",
"famous",
"remarkable",
"surprising",
"estimated",
"approximately",
"billion",
"million",
"ancient",
"modern",
"revolutionary",
]
# Score sentences based on interesting keywords
scored_sentences = []
for sentence in sentences:
if len(sentence.strip()) > 20: # Minimum length
score = sum(
1
for keyword in interesting_keywords
if keyword.lower() in sentence.lower()
)
scored_sentences.append((sentence.strip(), score))
# Sort by score and return the most interesting
if scored_sentences:
scored_sentences.sort(key=lambda x: x[1], reverse=True)
return scored_sentences[0][0] + "."
# Fallback to first substantial sentence
for sentence in sentences:
if len(sentence.strip()) > 50:
return sentence.strip() + "."
return text[:200] + "..."
def generate_random_fact() -> Dict:
"""Generate a random fact from curated topics"""
# Select random category and topic
category = random.choice(list(FACT_CATEGORIES.keys()))
topic = random.choice(FACT_CATEGORIES[category])
# Fetch summary
summary_data = fetch_wikipedia_summary(topic)
if not summary_data:
return {"error": "Could not fetch fact", "status": False}
extract = summary_data.get("extract", "")
# Extract interesting fact
fact = extract_interesting_fact(extract)
return {
"fact": fact,
"topic": summary_data.get("title", topic),
"category": category,
"status": True,
}
def generate_fact_quiz(num_facts: int = 5) -> List[Dict]:
"""Generate multiple facts for a timed game"""
facts = []
used_topics = set()
attempts = 0
max_attempts = num_facts * 3
while len(facts) < num_facts and attempts < max_attempts:
fact = generate_random_fact()
attempts += 1
if fact.get("status") and fact.get("topic") not in used_topics:
facts.append(fact)
used_topics.add(fact.get("topic"))
return facts
def generate_themed_facts(theme: str, num_facts: int = 5) -> List[Dict]:
"""Generate facts based on a specific theme"""
facts = []
# Find the category that best matches the theme
matching_category = None
for category, topics in FACT_CATEGORIES.items():
if theme.lower() in category.lower():
matching_category = category
break
if not matching_category:
# Search for theme in all topics
for category, topics in FACT_CATEGORIES.items():
for topic in topics:
if theme.lower() in topic.lower():
matching_category = category
break
if matching_category:
break
if matching_category:
topics = FACT_CATEGORIES[matching_category]
random.shuffle(topics)
for topic in topics[:num_facts]:
summary_data = fetch_wikipedia_summary(topic)
if summary_data:
extract = summary_data.get("extract", "")
fact = extract_interesting_fact(extract)
facts.append(
{
"fact": fact,
"topic": summary_data.get("title", topic),
"category": matching_category,
"status": True,
}
)
return facts
def generate_daily_fact() -> Dict:
"""Generate a special 'fact of the day'"""
# Use current date as seed for consistency
from datetime import datetime
today = datetime.now().strftime("%Y-%m-%d")
random.seed(today)
fact = generate_random_fact()
fact["is_daily"] = True
# Reset random seed
random.seed()
return fact
def generate_fact_challenge(difficulty: str = "Medium") -> Dict:
"""Generate a fact challenge with true/false question"""
fact_data = generate_random_fact()
if not fact_data.get("status"):
return fact_data
# Create a true/false challenge
if difficulty == "Easy":
# Simple true fact
challenge = {
"fact": fact_data["fact"],
"topic": fact_data["topic"],
"is_true": True,
"question": "Is this fact true?",
"status": True,
}
elif difficulty == "Medium":
# 50/50 chance of modified fact
if random.random() > 0.5:
# True fact
challenge = {
"fact": fact_data["fact"],
"topic": fact_data["topic"],
"is_true": True,
"question": "Is this fact true?",
"status": True,
}
else:
# Modified fact (make it false)
modified_fact = fact_data["fact"]
# Simple modifications to make it false
replacements = [
("largest", "smallest"),
("first", "last"),
("most", "least"),
("highest", "lowest"),
("discovered", "invented"),
("ancient", "modern"),
]
for old, new in replacements:
if old in modified_fact.lower():
modified_fact = modified_fact.replace(old, new)
break
challenge = {
"fact": modified_fact,
"topic": fact_data["topic"],
"is_true": False,
"question": "Is this fact true?",
"original_fact": fact_data["fact"],
"status": True,
}
else: # Hard
# More complex modifications or completely different topic
if random.random() > 0.3:
# True fact but more complex
challenge = {
"fact": fact_data["fact"],
"topic": fact_data["topic"],
"is_true": True,
"question": "Is this fact accurate?",
"status": True,
}
else:
# Mix facts from different topics
other_fact = generate_random_fact()
if other_fact.get("status"):
# Combine elements from two different facts
mixed_fact = (
fact_data["fact"].split(".")[0]
+ " and "
+ other_fact["fact"].split(".")[-1]
)
challenge = {
"fact": mixed_fact,
"topic": fact_data["topic"],
"is_true": False,
"question": "Is this statement factually correct?",
"original_fact": fact_data["fact"],
"status": True,
}
else:
# Fallback to medium difficulty
return generate_fact_challenge("Medium")
return challenge