Turbiling commited on
Commit
f3dc0b2
·
verified ·
1 Parent(s): 7482ae6

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +231 -0
app.py ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import PyPDF2
3
+ import pytesseract
4
+ from PIL import Image
5
+ import io
6
+ import faiss
7
+ import numpy as np
8
+ from transformers import AutoTokenizer, AutoModel
9
+ from docx import Document
10
+ from docx.shared import Inches
11
+ import torch
12
+ import os
13
+ from datetime import datetime
14
+
15
+ # Initialize models
16
+ MODEL_NAME = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
17
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
18
+ model = AutoModel.from_pretrained(MODEL_NAME)
19
+
20
+ # Helper functions
21
+ def extract_text_from_pdf(pdf_file):
22
+ try:
23
+ pdf_reader = PyPDF2.PdfReader(pdf_file)
24
+ text = ""
25
+ for page in pdf_reader.pages:
26
+ text += page.extract_text() or ""
27
+ if not text.strip():
28
+ text = extract_text_with_ocr(pdf_file)
29
+ return text
30
+ except Exception as e:
31
+ return f"Error extracting text: {str(e)} / متن نکالنے میں خرابی: {str(e)}"
32
+
33
+ def extract_text_with_ocr(pdf_file):
34
+ try:
35
+ pdf_reader = PyPDF2.PdfReader(pdf_file)
36
+ text = ""
37
+ for page in pdf_reader.pages:
38
+ img = page.images[0].image if page.images else None
39
+ if img:
40
+ text += pytesseract.image_to_string(Image.open(io.BytesIO(img.data)), lang="eng+urd")
41
+ return text
42
+ except Exception as e:
43
+ return f"OCR failed: {str(e)} / OCR ناکام: {str(e)}"
44
+
45
+ def chunk_text(text, chunk_size=400, overlap=80):
46
+ words = text.split()
47
+ chunks = []
48
+ for i in range(0, len(words), chunk_size - overlap):
49
+ chunk = " ".join(words[i:i + chunk_size])
50
+ chunks.append(chunk)
51
+ return chunks
52
+
53
+ def create_embeddings(chunks):
54
+ embeddings = []
55
+ for chunk in chunks:
56
+ inputs = tokenizer(chunk, return_tensors="pt", truncation=True, padding=True)
57
+ with torch.no_grad():
58
+ embedding = model(**inputs).last_hidden_state.mean(dim=1).numpy()
59
+ embeddings.append(embedding)
60
+ return np.vstack(embeddings)
61
+
62
+ def setup_faiss_index(embeddings):
63
+ dimension = embeddings.shape[1]
64
+ index = faiss.IndexFlatL2(dimension)
65
+ index.add(embeddings)
66
+ return index
67
+
68
+ def retrieve_relevant_chunks(query, index, chunks, k=3):
69
+ query_inputs = tokenizer(query, return_tensors="pt", truncation=True, padding=True)
70
+ with torch.no_grad():
71
+ query_embedding = model(**query_inputs).last_hidden_state.mean(dim=1).numpy()
72
+ distances, indices = index.search(query_embedding, k)
73
+ return [chunks[i] for i in indices[0]]
74
+
75
+ def generate_lesson_plan_boppps(grade, subject, topic, slo, duration, context):
76
+ doc = Document()
77
+ doc.add_heading(f"Grade {grade} {subject} Lesson Plan: {topic}", 0)
78
+ doc.add_paragraph(f"SLO: {slo}")
79
+ doc.add_paragraph(f"Duration: {duration} minutes")
80
+ doc.add_heading("BOPPPS Model", level=1)
81
+ doc.add_heading("Bridge-in", level=2)
82
+ doc.add_paragraph(f"Engaging activity for {topic}: [Generated activity based on {context}]")
83
+ doc.add_heading("Outcome", level=2)
84
+ doc.add_paragraph(f"Objective: {slo}")
85
+ doc.add_heading("Pre-assessment", level=2)
86
+ doc.add_paragraph("Quick quiz or question to gauge prior knowledge.")
87
+ doc.add_heading("Participatory Learning", level=2)
88
+ doc.add_paragraph(f"Interactive activity: [Generated from {context}]")
89
+ doc.add_heading("Post-assessment", level=2)
90
+ doc.add_paragraph("Evaluate SLO achievement with a short task.")
91
+ doc.add_heading("Summary", level=2)
92
+ doc.add_paragraph("Recap key points of the lesson.")
93
+ buffer = io.BytesIO()
94
+ doc.save(buffer)
95
+ buffer.seek(0)
96
+ return buffer, "\n".join([p.text for p in doc.paragraphs])
97
+
98
+ def generate_lesson_plan_backward(grade, subject, topic, slo, duration, context):
99
+ doc = Document()
100
+ doc.add_heading(f"Grade {grade} {subject} Lesson Plan: {topic}", 0)
101
+ doc.add_paragraph(f"SLO: {slo}")
102
+ doc.add_paragraph(f"Duration: {duration} minutes")
103
+ doc.add_heading("Backward Design", level=1)
104
+ doc.add_heading("Desired Results", level=2)
105
+ doc.add_paragraph(f"Goals: {slo}")
106
+ doc.add_heading("Acceptable Evidence", level=2)
107
+ doc.add_paragraph("Assessment criteria based on SLO.")
108
+ doc.add_heading("Learning Experiences", level=2)
109
+ doc.add_paragraph(f"Instructional strategies: [Generated from {context}]")
110
+ buffer = io.BytesIO()
111
+ doc.save(buffer)
112
+ buffer.seek(0)
113
+ return buffer, "\n".join([p.text for p in doc.paragraphs])
114
+
115
+ def generate_flashcards(grade, subject, topic, slo, context):
116
+ doc = Document()
117
+ doc.add_heading(f"Grade {grade} {subject} Flashcards: {topic}", 0)
118
+ doc.add_paragraph(f"SLO: {slo}")
119
+ table = doc.add_table(rows=6, cols=2)
120
+ table.style = "Table Grid"
121
+ table.cell(0, 0).text = "Front (Question)"
122
+ table.cell(0, 1).text = "Back (Answer)"
123
+ for i in range(1, 6):
124
+ table.cell(i, 0).text = f"Question {i} about {topic}?"
125
+ table.cell(i, 1).text = f"Answer {i} based on {context}."
126
+ buffer = io.BytesIO()
127
+ doc.save(buffer)
128
+ buffer.seek(0)
129
+ table_text = "\n".join([f"{row.cells[0].text} | {row.cells[1].text}" for row in table.rows])
130
+ return buffer, table_text
131
+
132
+ def generate_worksheet(grade, subject, topic, slo, context):
133
+ doc = Document()
134
+ doc.add_heading(f"Grade {grade} {subject} Worksheet: {topic}", 0)
135
+ doc.add_paragraph(f"SLO: {slo}")
136
+ doc.add_heading("Instructions", level=1)
137
+ doc.add_paragraph("Complete the following questions.")
138
+ doc.add_heading("Multiple Choice", level=2)
139
+ for i in range(1, 4):
140
+ doc.add_paragraph(f"{i}. Sample MCQ about {topic}? a) Option1 b) Option2 c) Option3 d) Option4")
141
+ doc.add_heading("Short Answer", level=2)
142
+ for i in range(1, 3):
143
+ doc.add_paragraph(f"{i}. Short answer question about {topic}?")
144
+ doc.add_heading("Activity", level=2)
145
+ doc.add_paragraph(f"Activity based on {context}.")
146
+ buffer = io.BytesIO()
147
+ doc.save(buffer)
148
+ buffer.seek(0)
149
+ return buffer, "\n".join([p.text for p in doc.paragraphs])
150
+
151
+ # Global variables for FAISS index
152
+ faiss_index = None
153
+ chunks = []
154
+ embeddings = None
155
+
156
+ def process_and_generate(pdf_file, grade, subject, topic, slo, duration, output_type, feedback=""):
157
+ global faiss_index, chunks, embeddings
158
+ if not pdf_file:
159
+ return None, "Please upload a PDF file / براہ کرم پی ڈی ایف فائل اپ لوڈ کریں", None
160
+ try:
161
+ # Extract and process PDF
162
+ text = extract_text_from_pdf(pdf_file)
163
+ if "Error" in text or "failed" in text:
164
+ return None, text, None
165
+ if not text.strip():
166
+ return None, "No text extracted. Please upload a valid PDF / کوئی متن نہیں نکالا گیا۔ براہ کرم ایک درست پی ڈی ایف اپ لوڈ کریں", None
167
+
168
+ # Chunk and embed text
169
+ chunks = chunk_text(text)
170
+ embeddings = create_embeddings(chunks)
171
+ faiss_index = setup_faiss_index(embeddings)
172
+
173
+ # Retrieve relevant context
174
+ query = f"Grade {grade} {subject} {topic} {slo}"
175
+ relevant_chunks = retrieve_relevant_chunks(query, faiss_index, chunks)
176
+ context = " ".join(relevant_chunks)
177
+
178
+ # Generate output
179
+ if output_type == "Lesson Plan (BOPPPS)":
180
+ buffer, preview = generate_lesson_plan_boppps(grade, subject, topic, slo or "General SLO", duration, context)
181
+ filename = f"Grade_{grade}_{subject}_BOPPPS_Lesson_Plan.docx"
182
+ elif output_type == "Lesson Plan (Backward Design)":
183
+ buffer, preview = generate_lesson_plan_backward(grade, subject, topic, slo or "General SLO", duration, context)
184
+ filename = f"Grade_{grade}_{subject}_Backward_Design_Lesson_Plan.docx"
185
+ elif output_type == "Flashcards":
186
+ buffer, preview = generate_flashcards(grade, subject, topic, slo or "General SLO", context)
187
+ filename = f"Grade_{grade}_{subject}_Flashcards.docx"
188
+ else:
189
+ buffer, preview = generate_worksheet(grade, subject, topic, slo or "General SLO", context)
190
+ filename = f"Grade_{grade}_{subject}_Worksheet.docx"
191
+
192
+ # Handle feedback
193
+ if feedback:
194
+ with open("feedback.txt", "a") as f:
195
+ f.write(f"{datetime.now()}: {feedback}\n")
196
+
197
+ return buffer, preview, filename
198
+ except Exception as e:
199
+ return None, f"Error: {str(e)} / خرابی: {str(e)}", None
200
+
201
+ # Gradio interface
202
+ with gr.Blocks(title="Curriculum Assistant / نصابی اسسٹنٹ") as demo:
203
+ gr.Markdown("""
204
+ # Curriculum Assistant / نصابی اسسٹنٹ
205
+ Upload a curriculum PDF and generate lesson plans, flashcards, or worksheets / نصابی پی ڈی ایف اپ لوڈ کریں اور سبق کے منصوبے، فلیش کارڈز، یا ورک شیٹس بنائیں.
206
+ *Tip*: BOPPPS is great for structured lessons; Backward Design focuses on learning goals / BOPPPS منظم اسباق کے لیے بہترین ہے؛ Backward Design سیکھنے کے اہداف پر مرکوز ہے.
207
+ """)
208
+
209
+ with gr.Row():
210
+ with gr.Column():
211
+ pdf_file = gr.File(label="Upload Curriculum PDF / پی ڈی ایف اپ لوڈ کریں", file_types=[".pdf"])
212
+ grade = gr.Dropdown(choices=list(range(1, 13)), label="Grade / گریڈ")
213
+ subject = gr.Dropdown(choices=["Math", "Science", "Social Studies", "English"], label="Subject / مضمون")
214
+ topic = gr.Textbox(label="Topic / موضوع", placeholder="e.g., Photosynthesis / مثلاً، فوٹوسنتھیسز")
215
+ slo = gr.Textbox(label="Specific SLO (optional) / مخصوص SLO (اختیاری)", placeholder="e.g., Understand cell structure / مثلاً، خلیے کی ساخت کو سمجھیں")
216
+ duration = gr.Dropdown(choices=[30, 45, 60], label="Lesson Duration (minutes) / سبق کا دورانیہ (منٹ)")
217
+ output_type = gr.Radio(choices=["Lesson Plan (BOPPPS)", "Lesson Plan (Backward Design)", "Flashcards", "Worksheet"], label="Output Type / آؤٹ پٹ کی قسم")
218
+ feedback = gr.Textbox(label="Feedback (optional) / رائے (اختیاری)", placeholder="Report issues or suggestions / مسائل یا تجاویز کی اطلاع دیں")
219
+ submit_button = gr.Button("Generate / بنائیں")
220
+
221
+ with gr.Column():
222
+ preview = gr.Textbox(label="Preview / پیش منظر", lines=10, interactive=False)
223
+ download_button = gr.File(label="Download as Word / ورڈ کے طور پر ڈاؤن لوڈ کریں")
224
+
225
+ submit_button.click(
226
+ fn=process_and_generate,
227
+ inputs=[pdf_file, grade, subject, topic, slo, duration, output_type, feedback],
228
+ outputs=[download_button, preview]
229
+ )
230
+
231
+ demo.launch()