""" SEA Prep Pro - AI-Powered Tutor 🇹🇹 FULLY FREE VERSION - No API Keys Required! """ import gradio as gr import sqlite3 import json import os import re import random import math import threading from datetime import datetime # ==================== FREE AI TUTOR ==================== class FreeAITutor: """Free AI tutor using rule-based generation""" def __init__(self): self.math_templates = { "Fractions": [ "Simplify the fraction {num}/{den}.", "Add {a}/{b} + {c}/{d}.", "Subtract {a}/{b} - {c}/{d}.", "What is {num}/{den} of {whole}?", "Convert {decimal} to a fraction." ], "Geometry": [ "Find the area of a rectangle with length {l}cm and width {w}cm.", "Calculate the perimeter of a square with side {s}cm.", "Find the area of a triangle with base {b}cm and height {h}cm.", "Calculate the circumference of a circle with radius {r}cm (use π=3.14).", "Find the volume of a cube with side {s}cm." ] } self.english_templates = { "Grammar": [ "Correct the sentence: '{sentence}'", "Choose the correct word: '{sentence}'" ], "Vocabulary": [ "What is a synonym for '{word}'?", "What is the antonym of '{word}'?" ] } def generate_math_question(self, topic, difficulty): """Generate math question""" templates = self.math_templates.get(topic, ["Practice {topic}."]) template = random.choice(templates) # Generate values based on difficulty max_val = {1: 10, 2: 20, 3: 50, 4: 100, 5: 200}[difficulty] values = { 'num': random.randint(1, max_val), 'den': random.randint(2, max_val), 'a': random.randint(1, max_val), 'b': random.randint(2, max_val), 'c': random.randint(1, max_val), 'd': random.randint(2, max_val), 'whole': random.randint(10, 100), 'decimal': round(random.uniform(0.1, 0.9), 2), 'l': random.randint(5, 20), 'w': random.randint(3, 15), 's': random.randint(4, 12), 'r': random.randint(2, 10), 'h': random.randint(3, 12), 'b': random.randint(4, 16), 'topic': topic } question = template.format(**values) answer = self._calculate_answer(question, values) return question, answer def _calculate_answer(self, question, values): """Calculate answer for math question""" try: if "Simplify the fraction" in question: num, den = values['num'], values['den'] gcd = math.gcd(num, den) return f"{num//gcd}/{den//gcd}" elif "area of a rectangle" in question: return f"{values['l'] * values['w']} cm²" elif "perimeter of a square" in question: return f"{4 * values['s']} cm" elif "area of a triangle" in question: return f"{0.5 * values['b'] * values['h']} cm²" elif "circumference of a circle" in question: return f"{2 * 3.14 * values['r']:.2f} cm" elif "volume of a cube" in question: return f"{values['s'] ** 3} cm³" elif "Add" in question and "/" in question: a, b, c, d = values['a'], values['b'], values['c'], values['d'] lcm = b * d // math.gcd(b, d) num = a * (lcm // b) + c * (lcm // d) gcd = math.gcd(num, lcm) return f"{num//gcd}/{lcm//gcd}" else: return "Calculate step by step" except Exception: return "Practice this concept" def evaluate_answer(self, student_answer, correct_answer): """Evaluate student's answer""" student = str(student_answer).strip().lower() correct = str(correct_answer).strip().lower() if student == correct: return {"correct": True, "score": 1.0, "feedback": "✅ Correct! Well done!"} # Partial credit for showing work if len(student) > 10: return {"correct": False, "score": 0.5, "feedback": "⚠️ Good attempt. Keep practicing!"} return {"correct": False, "score": 0.0, "feedback": "❌ Incorrect. Try again!"} # ==================== DATABASE ==================== class ThreadLocal(threading.local): def __init__(self): self.connections = {} thread_local = ThreadLocal() def get_db_connection(db_name="questions"): """Get database connection""" if not hasattr(thread_local, 'connections'): thread_local.connections = {} if db_name not in thread_local.connections: conn = sqlite3.connect(f"/tmp/{db_name}.db", check_same_thread=False) thread_local.connections[db_name] = conn return thread_local.connections[db_name] def init_databases(): """Initialize databases""" # Questions DB conn = get_db_connection("questions") cur = conn.cursor() cur.execute(''' CREATE TABLE IF NOT EXISTS questions ( id INTEGER PRIMARY KEY AUTOINCREMENT, subject TEXT, topic TEXT, question_text TEXT, difficulty INTEGER, correct_answer TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''') # Student DB conn = get_db_connection("students") cur = conn.cursor() cur.execute(''' CREATE TABLE IF NOT EXISTS student_progress ( id INTEGER PRIMARY KEY AUTOINCREMENT, student_id TEXT, question_id INTEGER, student_answer TEXT, correct BOOLEAN, score REAL, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''') cur.execute(''' CREATE TABLE IF NOT EXISTS student_stats ( student_id TEXT PRIMARY KEY, total_questions INTEGER DEFAULT 0, correct_answers INTEGER DEFAULT 0, total_score REAL DEFAULT 0, level INTEGER DEFAULT 1 ) ''') conn.commit() # ==================== MAIN APP ==================== class SEAITutor: def __init__(self): self.ai = FreeAITutor() init_databases() print("🚀 SEA Prep Pro - Free AI Tutor Started!") self.subjects = { "Mathematics": { "topics": ["Fractions", "Geometry", "Algebra", "Word Problems", "Percentages"], "icon": "📐" }, "English": { "topics": ["Grammar", "Vocabulary", "Comprehension", "Writing"], "icon": "📚" } } self.difficulty_levels = { 1: "Beginner", 2: "Easy", 3: "Medium", 4: "Hard", 5: "Expert" } self.student_id = "student_001" def generate_question(self, subject, topic, difficulty): """Generate a new question""" if subject == "Mathematics": question, answer = self.ai.generate_math_question(topic, difficulty) else: question = f"Practice {topic} in {subject}. Write your answer below." answer = "Sample answer for practice." # Store in DB conn = get_db_connection("questions") cur = conn.cursor() cur.execute(''' INSERT INTO questions (subject, topic, question_text, difficulty, correct_answer) VALUES (?, ?, ?, ?, ?) ''', (subject, topic, question, difficulty, answer)) question_id = cur.lastrowid conn.commit() return { "id": question_id, "text": question, "subject": subject, "topic": topic, "difficulty": self.difficulty_levels.get(difficulty, "Medium") } def submit_answer(self, question_id, student_answer): """Submit and evaluate answer""" # Get question conn = get_db_connection("questions") cur = conn.cursor() cur.execute('SELECT correct_answer FROM questions WHERE id = ?', (question_id,)) row = cur.fetchone() if not row: return {"feedback": "Question not found.", "score": 0} correct_answer = row[0] evaluation = self.ai.evaluate_answer(student_answer, correct_answer) # Record progress conn = get_db_connection("students") cur = conn.cursor() cur.execute(''' INSERT INTO student_progress (student_id, question_id, student_answer, correct, score) VALUES (?, ?, ?, ?, ?) ''', (self.student_id, question_id, student_answer, evaluation["correct"], evaluation["score"])) # Update stats cur.execute(''' INSERT OR REPLACE INTO student_stats (student_id, total_questions, correct_answers, total_score) VALUES (?, COALESCE((SELECT total_questions FROM student_stats WHERE student_id = ?), 0) + 1, COALESCE((SELECT correct_answers FROM student_stats WHERE student_id = ?), 0) + ?, COALESCE((SELECT total_score FROM student_stats WHERE student_id = ?), 0) + ? ) ''', (self.student_id, self.student_id, self.student_id, 1 if evaluation["correct"] else 0, self.student_id, evaluation["score"])) conn.commit() return evaluation def get_stats(self): """Get student statistics""" conn = get_db_connection("students") cur = conn.cursor() cur.execute(''' SELECT total_questions, correct_answers, total_score, level FROM student_stats WHERE student_id = ? ''', (self.student_id,)) row = cur.fetchone() if not row: return {"total_questions": 0, "correct_answers": 0, "accuracy": 0, "level": 1} total, correct, score, level = row accuracy = (correct / total * 100) if total > 0 else 0 return { "total_questions": total, "correct_answers": correct, "accuracy": round(accuracy, 1), "total_score": round(score, 1), "level": level } # Initialize tutor = SEAITutor() # ==================== GRADIO UI ==================== def create_ui(): with gr.Blocks( title="SEA Prep Pro - Free AI Tutor 🇹🇹", theme=gr.themes.Soft(primary_hue="blue", secondary_hue="purple") ) as demo: # Header gr.Markdown(""" # 🤖 SEA Prep Pro - Free AI Tutor 🇹🇹 ### 100% Free • No API Keys • Trinidad & Tobago SEA Exam Preparation """) with gr.Tabs(): with gr.TabItem("🎯 Practice"): with gr.Row(): with gr.Column(scale=1): subject = gr.Dropdown( choices=["Mathematics", "English"], value="Mathematics", label="Subject" ) topic = gr.Dropdown( choices=tutor.subjects["Mathematics"]["topics"], value="Fractions", label="Topic" ) difficulty = gr.Slider( 1, 5, value=3, step=1, label="Difficulty Level" ) generate_btn = gr.Button("✨ Generate Question", variant="primary") gr.Markdown("---") stats = gr.JSON(label="📊 Your Stats") refresh_btn = gr.Button("🔄 Refresh Stats") with gr.Column(scale=2): question_display = gr.Markdown("### Your question will appear here") answer_input = gr.Textbox(label="Your Answer", lines=3) with gr.Row(): submit_btn = gr.Button("✅ Submit Answer", variant="primary") clear_btn = gr.Button("🗑️ Clear") feedback = gr.Markdown("### 💬 Feedback") with gr.TabItem("📈 Progress"): gr.Markdown("### Your Learning Journey") progress_stats = gr.JSON() gr.Markdown("### 🎯 Tips for Success") gr.Markdown(""" - Practice regularly - Review your mistakes - Ask for help when needed - Stay consistent """) with gr.TabItem("ℹ️ About"): gr.Markdown(""" ## About SEA Prep Pro **SEA Prep Pro** is a completely free AI-powered tutoring system for Trinidad and Tobago students. ### Features: - ✅ 100% Free - No payments ever - 🔒 No API Keys Required - 🤖 Smart Question Generation - 📊 Progress Tracking - 🇹🇹 Trinidad & Tobago Focus ### Subjects: - **Mathematics**: Fractions, Geometry, Algebra - **English**: Grammar, Vocabulary, Comprehension ### How to Use: 1. Select a subject and topic 2. Choose difficulty level 3. Generate questions 4. Submit answers 5. Track your progress **Made with ❤️ for Trinidad and Tobago students** """) # State current_q = gr.State() # Functions def update_topics(subject): topics = tutor.subjects.get(subject, {}).get("topics", []) return gr.Dropdown.update(choices=topics, value=topics[0] if topics else "") def generate(subject, topic, difficulty): q = tutor.generate_question(subject, topic, difficulty) display = f""" **Subject:** {q['subject']} **Topic:** {q['topic']} **Difficulty:** {q['difficulty']} --- **Question:** {q['text']} """ return display, q, "" def submit(answer, question): if not question: return "Please generate a question first!", question result = tutor.submit_answer(question["id"], answer) return f"**{result['feedback']}** \n**Score:** {result['score']:.1%}", question def get_stats_func(): return tutor.get_stats() def clear(): return "", "" # Event handlers subject.change(update_topics, subject, topic) generate_btn.click(generate, [subject, topic, difficulty], [question_display, current_q, feedback]) submit_btn.click(submit, [answer_input, current_q], [feedback, current_q]) refresh_btn.click(get_stats_func, outputs=stats) clear_btn.click(clear, outputs=[answer_input, feedback]) # Initialize demo.load(get_stats_func, outputs=stats) return demo # Launch if __name__ == "__main__": app = create_ui() app.launch(debug=True)