Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import os | |
| from dotenv import load_dotenv | |
| from deep_translator import GoogleTranslator | |
| from gtts import gTTS | |
| import base64 | |
| import tempfile | |
| import google.generativeai as genai | |
| import uuid | |
| import speech_recognition as sr | |
| # Load environment variables | |
| load_dotenv() | |
| genai.configure(api_key=os.getenv("GEMINI_API_KEY")) | |
| model = genai.GenerativeModel("gemini-1.5-flash") | |
| st.set_page_config(page_title="LearnMate - AI Buddy", page_icon="π") | |
| st.title("π LearnMate - AI Learning Companion") | |
| # Sidebar: Enhanced Sidebar with Goals and Tasks | |
| st.sidebar.title("π LearnMate Dashboard") | |
| # Learning Goals Section | |
| st.sidebar.subheader("π― Your Learning Goals") | |
| learning_goal = st.sidebar.text_input("Add a Goal") | |
| if st.sidebar.button("β Add Goal") and learning_goal: | |
| if "goals" not in st.session_state: | |
| st.session_state.goals = [] | |
| st.session_state.goals.append(learning_goal) | |
| if "goals" in st.session_state: | |
| for goal in st.session_state.goals: | |
| st.sidebar.markdown(f"β {goal}") | |
| # Project Tracker | |
| st.sidebar.subheader("ππTask Tracker") | |
| if "todo" not in st.session_state: | |
| st.session_state.todo = [] | |
| if "done" not in st.session_state: | |
| st.session_state.done = [] | |
| new_task = st.sidebar.text_input("ππ New Task") | |
| if st.sidebar.button("ππ― Add Task") and new_task: | |
| st.session_state.todo.append(new_task) | |
| for i, task in enumerate(st.session_state.todo): | |
| if st.sidebar.checkbox(f"β¬ {task}", key=f"todo_{i}_{task}"): | |
| st.session_state.todo.remove(task) | |
| st.session_state.done.append(task) | |
| st.sidebar.subheader("β πTask Completed") | |
| for i, task in enumerate(st.session_state.done): | |
| st.sidebar.checkbox(f"βοΈ {task}", value=True, disabled=True, key=f"done_{i}_{task}") | |
| # Translation helper | |
| def safe_translate(text, lang): | |
| max_len = 500 | |
| chunks = [text[i:i+max_len] for i in range(0, len(text), max_len)] | |
| return " ".join([GoogleTranslator(source='auto', target=lang).translate(chunk) for chunk in chunks]) | |
| # Tabs | |
| TABS = st.tabs(["π Learning Path", "π¬ Study Twin", "π§ͺ Quiz Generator", "π§ Audio Summary", "π Regional Buddy"]) | |
| # ------------------------ π Learning Path ------------------------# | |
| with TABS[0]: | |
| st.header("π Build Your Learning Roadmap") | |
| lang = st.selectbox("π Language", ["english", "hindi", "tamil", "telugu"]) | |
| knowledge = st.text_area("π§ Your Current Knowledge") | |
| goal = st.text_area("π― Learning Goal") | |
| style = st.selectbox("π§© Learning Style", ["Visual", "Reading", "Hands-on", "Mixed"]) | |
| if st.button("π Generate Plan"): | |
| with st.spinner("π§ Crafting your custom roadmap..."): | |
| prompt = f""" | |
| You are LearnMate, an expert AI tutor. | |
| The user has the following: | |
| - Current knowledge: {knowledge} | |
| - Goal: {goal} | |
| - Preferred learning style: {style} | |
| Please generate a full markdown learning roadmap that includes: | |
| 1. π Stage-by-stage steps with estimated timelines. | |
| 2. π¨ Visual-style flow or layout described in text if user chose 'Visual'. | |
| 3. πΊ Three **specific YouTube videos** including titles and real video **hyperlinks**. | |
| 4. π Recommended resources, tools or tutorials related to the goal. | |
| 5. π§ Personalized study tips matching the selected learning style. | |
| Format all sections clearly with markdown headers (##) and bullet points. | |
| Example for video: [How Neural Networks Learn](https://www.youtube.com/watch?v=aircAruvnKk) | |
| Do NOT return video titles without links. | |
| """ | |
| response = model.generate_content(prompt) | |
| plan = response.text | |
| # Translate if needed | |
| if lang != "english": | |
| plan = safe_translate(plan, lang) | |
| st.markdown("### π Your Learning Plan") | |
| st.markdown(plan) | |
| # Enable download | |
| st.download_button( | |
| label="β¬οΈ Download Plan as .txt", | |
| data=plan, | |
| file_name="learning_plan.txt", | |
| mime="text/plain" | |
| ) | |
| st.markdown("---") | |
| st.success("β Video links are now clickable. Save this roadmap and start learning!") | |
| # ------------------------ π¬ Study Twin ------------------------ | |
| # ------------------------ π¬ Study Twin ------------------------ | |
| with TABS[1]: | |
| st.header("π¬ AI Study Twinπ―") | |
| if "study_step" not in st.session_state: | |
| st.session_state.study_step = 1 | |
| if "chat_history" not in st.session_state: | |
| st.session_state.chat_history = [] | |
| if st.session_state.study_step == 1: | |
| st.write("Let's get started β¨") | |
| st.session_state.study_topic = st.text_input("π What topic are you studying?") | |
| st.session_state.confidence_level = st.slider("Confidence (0-10)", 0, 10) | |
| if st.button("β‘οΈ Continue"): | |
| st.session_state.study_step = 2 | |
| elif st.session_state.study_step == 2: | |
| topic = st.session_state.study_topic | |
| score = st.session_state.confidence_level | |
| prompt = f"User is studying: {topic}, confidence: {score}/10. Suggest action plan, style-based activities & encouragement." | |
| reply = model.generate_content(prompt).text | |
| st.markdown("### π― Suggestion") | |
| st.markdown(reply) | |
| if st.button("π¬ Ask a Questionπ"): | |
| st.session_state.study_step = 3 | |
| elif st.session_state.study_step == 3: | |
| st.subheader("π€ Chat with Your Twin") | |
| user_msg = st.text_input("You:", key="twin_input") | |
| if st.button("π¨ Send"): | |
| chat = model.start_chat(history=st.session_state.chat_history) | |
| reply = chat.send_message(user_msg) | |
| st.session_state.chat_history.append({"role": "user", "parts": [user_msg]}) | |
| st.session_state.chat_history.append({"role": "model", "parts": [reply.text]}) | |
| for msg in st.session_state.chat_history: | |
| role = "π§ You" if msg["role"] == "user" else "π€ Twin" | |
| st.markdown(f"**{role}:** {msg['parts'][0]}") | |
| # ------------------------ π§ͺ Quiz Generator ------------------------ | |
| with TABS[2]: | |
| st.header("π§ͺ Test Yourself!") | |
| topic = st.text_input("π Enter a topic to quiz yourself:") | |
| if st.button("π― Generate Quiz"): | |
| prompt = f""" | |
| You are a quiz master. | |
| Generate 5 multiple choice questions (MCQs) for the topic: {topic}. | |
| Each question must include: | |
| - Question | |
| - Four options (a, b, c, d) | |
| - Correct answer line: Answer: x) | |
| Format: | |
| Q: [question] | |
| a) ... | |
| b) ... | |
| c) ... | |
| d) ... | |
| Answer: x) | |
| """ | |
| quiz_text = model.generate_content(prompt).text | |
| st.session_state.quiz_data = quiz_text.strip().split("\n\n") | |
| st.session_state.full_quiz_text = quiz_text | |
| if "quiz_data" in st.session_state: | |
| st.markdown("### π Your Quiz") | |
| for i, q_block in enumerate(st.session_state.quiz_data): | |
| lines = q_block.strip().split("\n") | |
| q_line = next((l for l in lines if l.strip().lower().startswith("q:")), None) | |
| opts = [line for line in lines if line.strip()[:2] in ["a)", "b)", "c)", "d)"]] | |
| ans_line = next((l for l in lines if "Answer:" in l), None) | |
| if not (q_line and opts and ans_line): | |
| st.warning(f"β Skipping malformed Q{i+1}") | |
| continue | |
| correct = ans_line.split(":")[-1].strip().lower() | |
| selected = st.radio(f"Q{i+1}: {q_line[2:].strip()}", opts, key=f"quiz_{i}") | |
| if st.button(f"βοΈ Check Q{i+1}", key=f"btn_{i}"): | |
| if selected.lower().startswith(correct): | |
| st.success("β Correct!") | |
| else: | |
| st.error(f"β Wrong. Correct answer is: {correct}") | |
| # Download full quiz | |
| st.markdown("---") | |
| st.download_button("β¬οΈ Download Full Quiz (.txt)", st.session_state.full_quiz_text, file_name="quiz.txt") | |
| # ------------------------ π§ Audio Summary ------------------------ | |
| with TABS[3]: | |
| st.header("π§ Audio Summary") | |
| text = st.text_area("Enter content:") | |
| if st.button("π Generate Audio"): | |
| tts = gTTS(text) | |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as fp: | |
| tts.save(fp.name) | |
| with open(fp.name, "rb") as f: | |
| audio_data = f.read() | |
| b64 = base64.b64encode(audio_data).decode() | |
| st.audio(f"data:audio/mp3;base64,{b64}", format='audio/mp3') | |
| st.download_button("β¬οΈ Download Audio", audio_data, file_name="audio_summary.mp3") | |
| # ------------------------ π Regional Buddy ------------------------ | |
| with TABS[4]: | |
| st.header("π Speak in Your Language") | |
| lang = st.selectbox("Choose Language", ["hindi", "tamil", "telugu"]) | |
| msg = st.text_area("Type your message:") | |
| if st.button("π Translate"): | |
| try: | |
| translated = GoogleTranslator(source="en", target=lang).translate(msg) | |
| st.success(f"Translated ({lang.upper()}): {translated}") | |
| except Exception as e: | |
| st.error(f"Error: {e}") |