File size: 4,243 Bytes
242da2d
 
 
 
bc20a41
a9d0ada
cde1a59
e33f38e
cde1a59
e33f38e
 
a9d0ada
af08924
a9d0ada
 
529a636
a9d0ada
242da2d
cde1a59
242da2d
 
529a636
242da2d
529a636
242da2d
529a636
 
242da2d
 
 
cde1a59
 
 
242da2d
529a636
242da2d
af08924
cde1a59
 
 
 
a9d0ada
cde1a59
a9d0ada
 
 
df4bf8e
a9d0ada
cde1a59
a9d0ada
 
 
 
cde1a59
242da2d
af08924
242da2d
 
529a636
 
 
242da2d
 
529a636
cde1a59
 
 
 
 
 
 
529a636
a9d0ada
 
cde1a59
a9d0ada
 
cde1a59
 
 
 
 
242da2d
 
529a636
cde1a59
242da2d
af08924
242da2d
cde1a59
 
 
 
 
a9d0ada
cde1a59
a9d0ada
cde1a59
a9d0ada
 
 
 
cde1a59
 
 
 
 
529a636
 
af08924
a9d0ada
242da2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cde1a59
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import os
from datetime import datetime
from PyPDF2 import PdfReader
from docx import Document
import streamlit as st
from groq import Groq
import textwrap

# βœ… Page Configuration
st.set_page_config(page_title="AI Study Plan Assistant", layout="wide")

# βœ… Load Groq Client
@st.cache_resource
def load_groq_client():
    return Groq(api_key=os.getenv("GROQ_API_KEY"))

groq_client = load_groq_client()

# βœ… File Text Extraction
def extract_text(file):
    ext = os.path.splitext(file.name)[1].lower()
    if ext == ".txt":
        return file.read().decode("utf-8")
    elif ext == ".docx":
        doc = Document(file)
        return "\n".join([para.text for para in doc.paragraphs])
    elif ext == ".pdf":
        pdf_reader = PdfReader(file)
        text = ""
        for page in pdf_reader.pages:
            page_text = page.extract_text()
            if page_text:
                text += page_text + "\n"
        return text
    else:
        raise ValueError("Only .txt, .docx, and .pdf files are supported.")

# βœ… Chunking helper
def chunk_text(text, chunk_size=1500):
    return textwrap.wrap(text, width=chunk_size, break_long_words=False, replace_whitespace=False)

# βœ… Query Groq LLM
def query_groq(prompt, temperature=0.4):
    try:
        chat = groq_client.chat.completions.create(
            messages=[{"role": "user", "content": prompt}],
            model="llama3-8b-8192",
            temperature=temperature
        )
        return chat.choices[0].message.content.strip()
    except Exception as e:
        return f"⚠️ Groq API Error: {str(e)}"

# βœ… Generate Study Plan with chunking
def generate_plan(file, hours_per_day, exam_date, language):
    try:
        content = extract_text(file)
        today = datetime.now().date()
        exam = datetime.strptime(exam_date.strip(), "%Y-%m-%d").date()
        days = (exam - today).days

        if days <= 0:
            return "❌ Exam date must be in the future."

        chunks = chunk_text(content, chunk_size=1500)
        plan_parts = []

        for idx, chunk in enumerate(chunks):
            prompt = f"""This is part {idx + 1} of {len(chunks)} of a syllabus.
Create a study plan segment for this syllabus. Total study duration is {days} days with {hours_per_day} hours/day.
Write the study plan in {language}.

Syllabus:
\"\"\"
{chunk}
\"\"\"
"""
            response = query_groq(prompt)
            plan_parts.append(response)

        return "\n\n".join(plan_parts)

    except Exception as e:
        return f"⚠️ Error: {str(e)}"

# βœ… Ask Question with context chunking
def ask_question(file, question):
    try:
        context = extract_text(file)
        chunks = chunk_text(context, chunk_size=1500)
        answers = []

        for idx, chunk in enumerate(chunks):
            prompt = f"""Use the following part of study material to answer the question:

Material:
\"\"\"
{chunk}
\"\"\"

Question: {question}
Answer:"""
            answer = query_groq(prompt)
            answers.append(f"Part {idx + 1}:\n{answer}")

        return "\n\n".join(answers)

    except Exception as e:
        return f"⚠️ Error: {str(e)}"

# βœ… Streamlit UI
st.sidebar.title("πŸ“š Study Assistant Options")
uploaded_file = st.sidebar.file_uploader("Upload syllabus (.txt, .docx, .pdf)", type=["txt", "docx", "pdf"])
study_hours = st.sidebar.number_input("Study hours per day", min_value=1, max_value=12, value=3)
exam_date = st.sidebar.text_input("Exam Date (YYYY-MM-DD)", value="2025-06-30")
language = st.sidebar.selectbox("Select Language", ["English", "Urdu"])

st.title("🧠 AI Study Plan & QA Assistant")

tab1, tab2 = st.tabs(["πŸ“… Generate Study Plan", "❓ Ask a Question"])

with tab1:
    st.subheader("Generate a Personalized Study Plan")
    if uploaded_file and st.button("Generate Study Plan"):
        result = generate_plan(uploaded_file, study_hours, exam_date, language)
        st.text_area("Study Plan", result, height=400)

with tab2:
    st.subheader("Ask Questions from Uploaded Material")
    question = st.text_input("Enter your question:")
    if uploaded_file and question and st.button("Get Answer"):
        answer = ask_question(uploaded_file, question)
        st.text_area("Answer", answer, height=300)