Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import requests | |
| import os | |
| # ------------------ GROQ SETTINGS ------------------ | |
| GROQ_API_KEY = os.getenv("GROQ_API_KEY") | |
| GROQ_MODEL = "llama3-70b-8192" | |
| def query_gpt(prompt): | |
| headers = { | |
| "Authorization": f"Bearer {GROQ_API_KEY}", | |
| "Content-Type": "application/json" | |
| } | |
| data = { | |
| "model": GROQ_MODEL, | |
| "messages": [{"role": "user", "content": prompt}] | |
| } | |
| response = requests.post("https://api.groq.com/openai/v1/chat/completions", json=data, headers=headers) | |
| return response.json()['choices'][0]['message']['content'] | |
| # ------------------ SYLLABUS DATA ------------------ | |
| class_subject_chapters = { | |
| "9": { | |
| "Physics": ["Introduction to Physics", "Kinematics", "Dynamics", "Turning Effect of Forces", "Gravitation", "Work and Energy", "Properties of Matter", "Thermal Properties of Matter", "Transfer of Heat"], | |
| "Biology": ["Introduction to Biology", "Solving a Biological Problem", "Biodiversity", "Cells and Tissues", "Cell Cycle", "Enzymes", "Bioenergetics", "Nutrition", "Transport"], | |
| "Chemistry": ["Fundamentals of Chemistry", "Structure of Atoms", "Periodic Table", "Structure of Molecules", "Physical States of Matter", "Solutions", "Electrochemistry", "Chemical Reactivity"] | |
| }, | |
| "10": { | |
| "Physics": ["Simple Harmonic Motion and Waves", "Sound", "Geometrical Optics", "Electrostatics", "Current Electricity", "Electromagnetism", "Basic Electronics", "Information and Communication Technology", "Atomic and Nuclear Physics"], | |
| "Biology": ["Gaseous Exchange", "Homeostasis", "Coordination and Control", "Support and Movement", "Reproduction", "Inheritance", "Man and His Environment", "Biotechnology", "Pharmacology"], | |
| "Chemistry": ["Chemical Equilibrium", "Acids, Bases and Salts", "Organic Chemistry", "Hydrocarbons", "Biochemistry", "Environmental Chemistry", "Chemical Industries"] | |
| }, | |
| "11": { | |
| "Physics": ["Measurements", "Vectors and Equilibrium", "Motion and Force", "Work and Energy", "Circular Motion", "Fluid Dynamics", "Oscillations", "Waves", "Physical Optics", "Thermodynamics"], | |
| "Biology": ["Introduction to Biology", "Biological Molecules", "Enzymes", "The Cell", "Cell Cycle", "Variety of Life", "Kingdom Prokaryotae", "Kingdom Protista", "Kingdom Fungi", "Kingdom Plantae", "Kingdom Animalia"], | |
| "Chemistry": ["Basic Concepts", "Experimental Techniques", "Gases", "Liquids and Solids", "Atomic Structure", "Chemical Bonding", "Thermochemistry", "Chemical Equilibrium", "Ionic Equilibrium", "Redox Reactions"] | |
| }, | |
| "12": { | |
| "Physics": ["Electrostatics", "Current Electricity", "Electromagnetism", "Electromagnetic Induction", "Alternating Current", "Physics of Solids", "Electronics", "Dawn of Modern Physics", "Atomic Spectra", "Nuclear Physics"], | |
| "Biology": ["Homeostasis", "Support and Movement", "Coordination and Control", "Reproduction", "Growth and Development", "Chromosomes and DNA", "Biotechnology", "Evolution", "Ecosystem", "Some Major Ecosystems"], | |
| "Chemistry": ["Periodic Classification", "Transition Elements", "Chemical Reactivity", "Alcohols and Phenols", "Aldehydes and Ketones", "Carboxylic Acids", "Amines", "Polymers", "Biochemistry", "Environmental Chemistry"] | |
| } | |
| } | |
| # ------------------ FILE READER ------------------ | |
| def read_uploaded_file(file): | |
| if file is None: | |
| return "" | |
| if file.name.endswith(".txt"): | |
| return file.read().decode("utf-8") | |
| elif file.name.endswith(".pdf"): | |
| from PyPDF2 import PdfReader | |
| reader = PdfReader(file) | |
| return "\n".join(page.extract_text() for page in reader.pages if page.extract_text()) | |
| elif file.name.endswith(".docx"): | |
| import docx | |
| doc = docx.Document(file) | |
| return "\n".join(p.text for p in doc.paragraphs) | |
| else: | |
| return "Unsupported file format. Please upload a PDF, DOCX, or TXT file." | |
| # ------------------ MAIN BOT FUNCTION ------------------ | |
| def tutor_bot(mode, selected_class, selected_subject, selected_chapter, action_type, uploaded_file): | |
| if mode == "File Upload Mode" and uploaded_file is not None: | |
| file_text = read_uploaded_file(uploaded_file) | |
| if not file_text.strip(): | |
| return "Could not read text from the uploaded file." | |
| prompt = f"Based on the following content, {action_type.lower()}: \n\n{file_text[:4000]}" # keep it under token limits | |
| gpt_response = query_gpt(prompt) | |
| return gpt_response | |
| elif mode == "Syllabus Mode": | |
| if not selected_class or not selected_subject or not selected_chapter: | |
| return "Please select class, subject, and chapter." | |
| prompt = f"The user is studying in Class {selected_class}. Give a detailed response for the chapter '{selected_chapter}' in the subject '{selected_subject}'." | |
| if action_type == "Summarize Important Points": | |
| prompt = f"Summarize the key points of the chapter '{selected_chapter}' from Class {selected_class} {selected_subject}." | |
| elif action_type == "Generate MCQs": | |
| prompt = f"Create 5 multiple choice questions (MCQs) with 4 options each for the chapter '{selected_chapter}' from Class {selected_class} {selected_subject}." | |
| elif action_type == "Simplify Concepts": | |
| prompt = f"Explain in very simple terms the important concepts from the chapter '{selected_chapter}' from Class {selected_class} {selected_subject} for a 14-year-old student." | |
| gpt_response = query_gpt(prompt) | |
| search_query = f"{selected_class} {selected_subject} {selected_chapter} in Urdu" | |
| youtube_link = f"https://www.youtube.com/results?search_query={search_query.replace(' ', '+')}" | |
| gpt_response += f"\n\nπ₯ **Watch this topic on YouTube:** [Click here]({youtube_link})" | |
| return gpt_response | |
| return "Invalid mode or missing input." | |
| # ------------------ HANGMAN GAME ------------------ | |
| def generate_question_answer(class_level, subject, chapter): | |
| prompt = f"Give one short quiz question and a one-word answer from the chapter '{chapter}' in Class {class_level} {subject}. Format:\nQuestion: ...\nAnswer: ..." | |
| result = query_gpt(prompt) | |
| lines = result.strip().split("\n") | |
| question = "" | |
| answer = "" | |
| for line in lines: | |
| if line.lower().startswith("question:"): | |
| question = line.split(":", 1)[1].strip() | |
| elif line.lower().startswith("answer:"): | |
| answer = line.split(":", 1)[1].strip().lower() | |
| answer = ''.join(filter(str.isalpha, answer)) | |
| return question, answer | |
| def start_hangman_game(class_level, subject, chapter): | |
| question, answer = generate_question_answer(class_level, subject, chapter) | |
| return question, "_" * len(answer), "", 6, answer, [] | |
| def guess_letter(letter, answer, current_display, wrong_guesses_left, guessed_letters): | |
| letter = letter.lower() | |
| if letter in guessed_letters or len(letter) != 1: | |
| return current_display, f"You already guessed '{letter}' or invalid guess.", wrong_guesses_left, guessed_letters | |
| guessed_letters.append(letter) | |
| if letter in answer: | |
| new_display = "".join([letter if answer[i] == letter else current_display[i] for i in range(len(answer))]) | |
| if "_" not in new_display: | |
| return new_display, "π You won!", wrong_guesses_left, guessed_letters | |
| return new_display, f"β Correct guess!", wrong_guesses_left, guessed_letters | |
| else: | |
| wrong_guesses_left -= 1 | |
| if wrong_guesses_left == 0: | |
| return current_display, f"β Game over! The correct word was '{answer}'.", wrong_guesses_left, guessed_letters | |
| return current_display, f"β Wrong guess! {wrong_guesses_left} attempts left.", wrong_guesses_left, guessed_letters | |
| # ------------------ GRADIO UI ------------------ | |
| with gr.Blocks(title="AI Textbook Tutor") as app: | |
| with gr.Tab("π Tutor"): | |
| gr.Markdown("## π AI Textbook Tutor\nChoose a mode to either upload your file or select chapter-wise content to get summaries, MCQs, or simplified explanations.") | |
| mode = gr.Radio(["Syllabus Mode", "File Upload Mode"], label="Select Mode", value="Syllabus Mode") | |
| with gr.Row(): | |
| class_dropdown = gr.Dropdown(label="Class", choices=list(class_subject_chapters.keys())) | |
| subject_dropdown = gr.Dropdown(label="Subject") | |
| chapter_dropdown = gr.Dropdown(label="Chapter") | |
| file_input = gr.File(label="Upload File (PDF, DOCX, TXT)", file_types=[".pdf", ".docx", ".txt"]) | |
| action_dropdown = gr.Radio(["Summarize Important Points", "Generate MCQs", "Simplify Concepts"], label="Task", value="Summarize Important Points") | |
| run_button = gr.Button("Run Tutor π§ ") | |
| output_box = gr.Markdown() | |
| def update_subjects(selected_class): | |
| return gr.update(choices=list(class_subject_chapters[selected_class].keys()), value=None) | |
| def update_chapters(selected_class, selected_subject): | |
| try: | |
| chapters = class_subject_chapters[selected_class][selected_subject] | |
| return gr.update(choices=chapters, value=None) | |
| except Exception as e: | |
| return gr.update(choices=[], value="Error") | |
| def toggle_ui(selected_mode): | |
| if selected_mode == "File Upload Mode": | |
| return ( | |
| gr.update(visible=False), # Class | |
| gr.update(visible=False), # Subject | |
| gr.update(visible=False), # Chapter | |
| gr.update(visible=True) # File input | |
| ) | |
| else: | |
| return ( | |
| gr.update(visible=True), | |
| gr.update(visible=True), | |
| gr.update(visible=True), | |
| gr.update(visible=False) | |
| ) | |
| class_dropdown.change(update_subjects, inputs=class_dropdown, outputs=subject_dropdown) | |
| subject_dropdown.change(update_chapters, inputs=[class_dropdown, subject_dropdown], outputs=chapter_dropdown) | |
| mode.change(toggle_ui, inputs=mode, outputs=[class_dropdown, subject_dropdown, chapter_dropdown, file_input]) | |
| run_button.click( | |
| tutor_bot, | |
| inputs=[mode, class_dropdown, subject_dropdown, chapter_dropdown, action_dropdown, file_input], | |
| outputs=output_box | |
| ) | |
| with gr.Tab("π― Hangman Game"): | |
| with gr.Row(): | |
| class_level_hg = gr.Dropdown(label="Class", choices=list(class_subject_chapters.keys())) | |
| subject_hg = gr.Textbox(label="Subject") | |
| chapter_hg = gr.Textbox(label="Chapter") | |
| start_btn = gr.Button("Start Hangman Game") | |
| question_display = gr.Textbox(label="Question", interactive=False) | |
| word_display = gr.Textbox(label="Word", interactive=False) | |
| feedback_display = gr.Textbox(label="Feedback", interactive=False) | |
| guess_input = gr.Textbox(label="Guess a letter") | |
| guess_btn = gr.Button("Guess") | |
| wrong_guesses_left = gr.State(6) | |
| correct_answer = gr.State("") | |
| guessed_letters = gr.State([]) | |
| start_btn.click(fn=start_hangman_game, inputs=[class_level_hg, subject_hg, chapter_hg], outputs=[question_display, word_display, feedback_display, wrong_guesses_left, correct_answer, guessed_letters]) | |
| guess_btn.click(fn=guess_letter, inputs=[guess_input, correct_answer, word_display, wrong_guesses_left, guessed_letters], outputs=[word_display, feedback_display, wrong_guesses_left, guessed_letters]) | |
| app.launch() | |