ahm14 commited on
Commit
c27c636
·
verified ·
1 Parent(s): 5858ef1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -52
app.py CHANGED
@@ -13,8 +13,9 @@ import os
13
  from concurrent.futures import ThreadPoolExecutor
14
  import requests
15
  from bs4 import BeautifulSoup
16
- from docx import Document
17
- from fpdf import FPDF
 
18
 
19
  # Load environment variables
20
  load_dotenv()
@@ -30,10 +31,14 @@ pytesseract.pytesseract.tesseract_cmd = r"/usr/bin/tesseract" # Adjust based on
30
 
31
  # Function to enhance image for OCR processing
32
  def enhance_image_for_ocr(image):
33
- gray_image = image.convert("L")
34
- enhancer = ImageEnhance.Contrast(gray_image)
35
- enhanced_image = enhancer.enhance(2.0)
36
- return enhanced_image
 
 
 
 
37
 
38
  # Function to extract text from images using OCR
39
  def extract_text_from_images(images, lang="eng"):
@@ -112,20 +117,26 @@ def process_files(uploaded_files, lang="eng"):
112
  ocr_text = extract_text_from_images(images, lang)
113
  return combined_text + "\n" + ocr_text
114
 
115
- # Function to generate questions (without the question number or difficulty)
116
- def generate_questions(syllabus_text, num_questions):
117
- prompt = f"Generate {num_questions} relevant questions based on the following syllabus content. Ensure that the questions are diverse and realistic, as would be generated by a human educator. Syllabus Content: {syllabus_text}"
 
 
 
 
 
118
 
119
  chain = (ChatPromptTemplate.from_template(prompt) | llm | StrOutputParser())
120
  try:
121
  questions = chain.invoke({})
122
- questions = "\n".join([q.strip() for q in questions.split("\n") if q.strip()]) # Clean up the questions
123
- return questions
 
124
  except Exception as e:
125
  logging.error(f"Error generating questions: {e}")
126
  return ""
127
 
128
- # Function to generate answers based on the questions
129
  def generate_answers(questions, syllabus_text):
130
  answers = {}
131
 
@@ -134,6 +145,8 @@ def generate_answers(questions, syllabus_text):
134
  prompt = f"""
135
  Below is a syllabus excerpt. Please answer the following question based on the content provided.
136
  Ensure the answer is directly related to the question and specific to the syllabus.
 
 
137
  Syllabus Content: {syllabus_text}
138
 
139
  Question: {question}
@@ -145,44 +158,40 @@ def generate_answers(questions, syllabus_text):
145
  answer = chain.invoke({})
146
  answers[f"Answer {i+1}"] = answer.strip()
147
  except Exception as e:
148
- answers[f"Answer {i+1}"] = "No answer found."
149
 
150
  return "\n".join([f"{k}: {v}" for k, v in answers.items()])
151
 
152
- # Function to generate docx download
153
- def generate_docx(questions, answers):
154
- doc = Document()
155
- doc.add_heading("Questions and Answers", 0)
156
-
157
- questions_list = questions.split("\n")
158
- answers_list = answers.split("\n")
 
 
 
 
 
159
 
160
- for i in range(len(questions_list)):
161
- doc.add_heading(f"Q{i+1}: {questions_list[i]}", level=1)
162
- doc.add_paragraph(f"A{i+1}: {answers_list[i]}")
163
 
164
- doc_path = "/tmp/questions_and_answers.docx"
165
- doc.save(doc_path)
166
- return doc_path
167
 
168
- # Function to generate PDF download
169
- def generate_pdf(questions, answers):
170
  pdf = FPDF()
171
- pdf.set_auto_page_break(auto=True, margin=15)
172
  pdf.add_page()
173
-
174
- questions_list = questions.split("\n")
175
- answers_list = answers.split("\n")
176
-
177
  pdf.set_font("Arial", size=12)
178
-
179
- for i in range(len(questions_list)):
180
- pdf.cell(200, 10, f"Q{i+1}: {questions_list[i]}", ln=True)
181
- pdf.multi_cell(200, 10, f"A{i+1}: {answers_list[i]}")
182
-
183
- pdf_path = "/tmp/questions_and_answers.pdf"
184
- pdf.output(pdf_path)
185
- return pdf_path
186
 
187
  # Streamlit UI
188
  st.title("AI-Powered Exam Generator")
@@ -213,9 +222,30 @@ with tab2:
213
  # Generate questions and answers
214
  with tab3:
215
  st.header("Generate Questions and Answers")
216
- num_questions = st.number_input("Total Number of Questions", min_value=1, step=1)
217
- if num_questions and st.button("Generate Questions and Answers"):
218
- questions = generate_questions(st.session_state.get("syllabus_text", ""), num_questions)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  st.session_state["questions"] = questions
220
  st.text_area("Generated Questions", questions, height=300)
221
 
@@ -225,14 +255,12 @@ with tab3:
225
  st.text_area("Generated Answers", answers, height=300)
226
 
227
  # Download questions and answers
228
- st.download_button("Download Questions", questions, file_name="questions.txt")
229
- st.download_button("Download Answers", answers, file_name="answers.txt")
230
- st.download_button("Download as DOCX", generate_docx(questions, answers), file_name="questions_and_answers.docx")
231
- st.download_button("Download as PDF", generate_pdf(questions, answers), file_name="questions_and_answers.pdf")
232
 
233
  # Generate answers
234
  with tab4:
235
- st.header("Generate Answers for Uploaded Content")
236
  if "questions" in st.session_state:
237
  if st.button("Generate Answers"):
238
  answers = generate_answers(st.session_state["questions"], st.session_state.get("syllabus_text", ""))
@@ -240,6 +268,4 @@ with tab4:
240
  st.text_area("Generated Answers", answers, height=300)
241
 
242
  # Download answers
243
- st.download_button("Download Answers", answers, file_name="answers.txt")
244
- st.download_button("Download Answers as DOCX", generate_docx(st.session_state["questions"], answers), file_name="answers.docx")
245
- st.download_button("Download Answers as PDF", generate_pdf(st.session_state["questions"], answers), file_name="answers.pdf")
 
13
  from concurrent.futures import ThreadPoolExecutor
14
  import requests
15
  from bs4 import BeautifulSoup
16
+ import re
17
+ import json
18
+ import pandas as pd
19
 
20
  # Load environment variables
21
  load_dotenv()
 
31
 
32
  # Function to enhance image for OCR processing
33
  def enhance_image_for_ocr(image):
34
+ try:
35
+ gray_image = image.convert("L")
36
+ enhancer = ImageEnhance.Contrast(gray_image)
37
+ enhanced_image = enhancer.enhance(2.0) # Increase contrast
38
+ return enhanced_image
39
+ except Exception as e:
40
+ logging.error(f"Error enhancing image for OCR: {e}")
41
+ return image
42
 
43
  # Function to extract text from images using OCR
44
  def extract_text_from_images(images, lang="eng"):
 
117
  ocr_text = extract_text_from_images(images, lang)
118
  return combined_text + "\n" + ocr_text
119
 
120
+ # Function to generate questions with enhanced realism
121
+ def generate_questions(question_type, syllabus_text, num_questions, difficulty, prompt_template):
122
+ prompt = prompt_template.format(
123
+ num_questions=num_questions,
124
+ question_type=question_type,
125
+ syllabus_text=syllabus_text,
126
+ **difficulty
127
+ )
128
 
129
  chain = (ChatPromptTemplate.from_template(prompt) | llm | StrOutputParser())
130
  try:
131
  questions = chain.invoke({})
132
+ # Extract only the question text, remove numbering, difficulty, etc.
133
+ questions_clean = re.sub(r"(\d+\.)|(.*?)", "", questions) # Remove question numbers and extra parts
134
+ return questions_clean.strip()
135
  except Exception as e:
136
  logging.error(f"Error generating questions: {e}")
137
  return ""
138
 
139
+ # Refined function to generate answers (excluding question numbers and difficulty)
140
  def generate_answers(questions, syllabus_text):
141
  answers = {}
142
 
 
145
  prompt = f"""
146
  Below is a syllabus excerpt. Please answer the following question based on the content provided.
147
  Ensure the answer is directly related to the question and specific to the syllabus.
148
+ If necessary, explain key concepts clearly. Answer the question in a concise and detailed manner.
149
+
150
  Syllabus Content: {syllabus_text}
151
 
152
  Question: {question}
 
158
  answer = chain.invoke({})
159
  answers[f"Answer {i+1}"] = answer.strip()
160
  except Exception as e:
161
+ answers[f"Answer {i+1}"] = search_answers_online(question)
162
 
163
  return "\n".join([f"{k}: {v}" for k, v in answers.items()])
164
 
165
+ # Function to search answers online
166
+ def search_answers_online(question):
167
+ search_url = f"https://www.google.com/search?q={question}"
168
+ headers = {"User-Agent": "Mozilla/5.0"}
169
+ try:
170
+ response = requests.get(search_url, headers=headers)
171
+ soup = BeautifulSoup(response.text, "html.parser")
172
+ snippets = soup.find_all("div", class_="BNeawe")
173
+ return "\n".join([snippet.get_text() for snippet in snippets[:3]])
174
+ except Exception as e:
175
+ logging.error(f"Error fetching online answers: {e}")
176
+ return "No online answer found."
177
 
178
+ # Function to limit downloads to DOCX, PDF, and TXT formats
179
+ def save_as_txt(questions, answers):
180
+ return f"Questions:\n{questions}\n\nAnswers:\n{answers}"
181
 
182
+ def save_as_pdf(questions, answers):
183
+ # For simplicity, returning a text-based PDF. For more complex PDFs, libraries like ReportLab can be used.
184
+ from fpdf import FPDF
185
 
 
 
186
  pdf = FPDF()
 
187
  pdf.add_page()
188
+ pdf.set_auto_page_break(auto=True, margin=15)
 
 
 
189
  pdf.set_font("Arial", size=12)
190
+ pdf.multi_cell(0, 10, f"Questions:\n{questions}\n\nAnswers:\n{answers}")
191
+ pdf_output = BytesIO()
192
+ pdf.output(pdf_output)
193
+ pdf_output.seek(0)
194
+ return pdf_output
 
 
 
195
 
196
  # Streamlit UI
197
  st.title("AI-Powered Exam Generator")
 
222
  # Generate questions and answers
223
  with tab3:
224
  st.header("Generate Questions and Answers")
225
+ question_type = st.selectbox("Select Question Type", ["MCQs", "Short Questions", "Long Questions", "Fill-in-the-Blank", "Case Study"])
226
+ num_questions = st.text_input("Total Number of Questions")
227
+ difficulty_levels = ["Remember", "Understand", "Apply", "Analyze", "Evaluate", "Create"]
228
+ difficulty = {level: st.slider(level, 0, 5, 1) for level in difficulty_levels}
229
+ prompt_template = st.text_area(
230
+ "Edit Prompt Template",
231
+ """
232
+ Generate {num_questions} {question_type} questions from the syllabus content below.
233
+ Syllabus Content: {syllabus_text}
234
+ Difficulty Levels:
235
+ - Remember: {Remember}
236
+ - Understand: {Understand}
237
+ - Apply: {Apply}
238
+ - Analyze: {Analyze}
239
+ - Evaluate: {Evaluate}
240
+ - Create: {Create}
241
+ """,
242
+ height=200
243
+ )
244
+ if num_questions.isdigit() and st.button("Generate Questions and Answers"):
245
+ num_questions = int(num_questions)
246
+
247
+ # Generate questions
248
+ questions = generate_questions(question_type, st.session_state.get("syllabus_text", ""), num_questions, difficulty, prompt_template)
249
  st.session_state["questions"] = questions
250
  st.text_area("Generated Questions", questions, height=300)
251
 
 
255
  st.text_area("Generated Answers", answers, height=300)
256
 
257
  # Download questions and answers
258
+ st.download_button("Download Questions (TXT)", save_as_txt(questions, answers), file_name="qa.txt")
259
+ st.download_button("Download Q&A (PDF)", save_as_pdf(questions, answers), file_name="qa.pdf")
 
 
260
 
261
  # Generate answers
262
  with tab4:
263
+ st.header("Generate Answers (Optional)")
264
  if "questions" in st.session_state:
265
  if st.button("Generate Answers"):
266
  answers = generate_answers(st.session_state["questions"], st.session_state.get("syllabus_text", ""))
 
268
  st.text_area("Generated Answers", answers, height=300)
269
 
270
  # Download answers
271
+ st.download_button("Download Answers", answers, file_name="answers.txt")