File size: 8,272 Bytes
f367219
f254492
d1de8bc
f367219
d1de8bc
 
 
f367219
d1de8bc
f367219
 
 
 
 
 
d1de8bc
 
 
 
 
 
 
 
2af61c2
 
 
d1de8bc
 
2af61c2
 
 
d1de8bc
 
2af61c2
 
 
d1de8bc
 
2af61c2
 
 
f367219
f254492
f367219
2af61c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f254492
2af61c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f254492
d1de8bc
 
2af61c2
 
 
f254492
2af61c2
 
 
 
 
 
 
f254492
d1de8bc
2af61c2
f367219
d1de8bc
 
f367219
d1de8bc
 
f254492
2af61c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d1de8bc
 
2af61c2
f367219
 
d1de8bc
2af61c2
f367219
 
 
d1de8bc
 
f254492
 
 
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
135
136
137
138
139
140
141
142
143
144
import gradio as gr
import requests
import os

# ------------------ GROQ SETTINGS ------------------
GROQ_API_KEY = os.getenv("GROQ_API_KEY") or "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"
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."

# ------------------ GRADIO UI ------------------
with gr.Blocks(title="AI Textbook Tutor") as app:
    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):
        return gr.update(choices=class_subject_chapters[selected_class][selected_subject], value=None)

    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
    )

app.launch()