import streamlit as st # Set page config FIRST before any other Streamlit commands st.set_page_config(page_title="Education with Fun", page_icon="🎓", layout="centered") import fitz # PyMuPDF from sentence_transformers import SentenceTransformer import faiss import numpy as np from gtts import gTTS import tempfile import os # --- Custom UI Styling with Background --- page_bg_img = """ """ st.markdown(page_bg_img, unsafe_allow_html=True) # --- Load Model --- @st.cache_resource def load_model(): return SentenceTransformer('all-MiniLM-L6-v2') # --- Extract Text from PDF --- def extract_text_from_pdf(pdf_file): doc = fitz.open(stream=pdf_file.read(), filetype="pdf") text = "" for page in doc: text += page.get_text() return text # --- Split Text into Chunks --- def split_text(text, max_length=300): sentences = text.split('.') chunks = [] current_chunk = "" for sentence in sentences: if len(current_chunk) + len(sentence) < max_length: current_chunk += sentence + "." else: chunks.append(current_chunk.strip()) current_chunk = sentence + "." if current_chunk: chunks.append(current_chunk.strip()) return chunks # --- Create FAISS Index --- def create_faiss_index(chunks, model): embeddings = model.encode(chunks) dimension = embeddings.shape[1] index = faiss.IndexFlatL2(dimension) index.add(np.array(embeddings)) return index, chunks # --- Search Top Matches --- def search_index(query, model, index, chunks, k=3): query_vector = model.encode([query]) distances, indices = index.search(np.array(query_vector), k) results = [chunks[i] for i in indices[0]] return results # --- Story Answer Generator --- def generate_story_answer(passages, question): intro = "📖 چلو بچوں، ایک زبردست کہانی سنتے ہیں!\n" content = " ".join(passages) closing = f"\n\n🧐 سوال تھا: {question}" return f"{intro}\n{content}\n{closing}" # --- Text to Speech --- def text_to_speech(text): tts = gTTS(text=text, lang='ur') with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as fp: tts.save(fp.name) return fp.name # --- App UI --- st.title("📚 Education with Fun") st.subheader("Learn Primary Science (Grades 5 & 6) Through Stories and Sound!") # Upload the syllabus PDF uploaded_pdf = st.file_uploader("📄 Upload Primary Science Syllabus PDF", type="pdf") # Select grade and subject grade = st.selectbox("📘 Select Grade", ["Grade 5", "Grade 6"]) subject = st.selectbox("📙 Select Subject", ["Primary Science 5", "Primary Science 6"]) # Input question question = st.text_input("🧠 Ask a Question (in English or Urdu):") # Process if uploaded_pdf and question: with st.spinner("🔍 Thinking and generating your story..."): model = load_model() full_text = extract_text_from_pdf(uploaded_pdf) chunks = split_text(full_text) index, chunk_list = create_faiss_index(chunks, model) relevant_chunks = search_index(question, model, index, chunk_list) final_answer = generate_story_answer(relevant_chunks, question) audio_file = text_to_speech(final_answer) st.subheader("📖 Storytelling Answer") st.write(final_answer) st.subheader("🔊 Listen to the Answer") st.audio(audio_file, format='audio/mp3') st.success("✅ Done! You can ask another question or upload a new syllabus.") # Tip st.markdown("---") st.info("ℹ️ Tip: Use real Primary Science syllabus PDFs from Punjab Board or Cambridge to get best results.")