Quizy / app.py
Abhinav
Refactor AI integration and enhance quiz functionality with validation
484bee1
raw
history blame
5.48 kB
import json
import gradio as gr
import PyPDF2 as pypdf
from stylesheet import style
from dotenv import load_dotenv
from prompts import prompts
from ai import ask_ai
load_dotenv()
css, js = style()
# PDF To Text Conversion Function
def convertPdfIntoText(file):
if file is None:
return "No file uploaded."
pypdf_reader = pypdf.PdfReader(file.name)
text = ""
for page in pypdf_reader.pages:
text += page.extract_text() + "\n"
# print("---------PDF TEXT EXTRACTION DONE-----------")
return text.strip()
# Gradio Interface Setup
with gr.Blocks(title="Quizy", css=css, head=js) as app:
gr.Markdown("# Quizy: Quiz Generator")
gr.Markdown("Upload a PDF file to generate a quiz based on its content.")
file_input = gr.File(label="Upload PDF File", file_types=[".pdf"])
generate_btn = gr.Button("Generate Quiz", visible=True, elem_id="generate-btn")
with gr.Accordion("Quiz", open=False, visible=False) as quiz_accordion:
output_container = gr.HTML()
submit_btn = gr.Button("Submit", elem_id="submit-btn", visible=False)
def generate_quiz(file):
if file is None:
return "<p>No file uploaded.</p>", gr.Accordion(visible=False)
inputData = convertPdfIntoText(file)
systemPrompt, userPrompt = prompts(inputData)
response = ask_ai(systemPrompt, userPrompt)
clean_response = (
response.strip().removeprefix("```json").removesuffix("```")
)
clean_response = clean_response.strip()
quiz_data = json.loads(clean_response)
html = "<div class='quiz-container'>"
html += "<form id='quiz-form' method='post' onsubmit='return false;'>"
for i, question in enumerate(quiz_data["quiz"]):
question_type = question["type"]
answer_json = json.dumps(question["answer"]).replace('"', "&quot;")
html += f"<div class='question' data-id='{i}' data-type='{question_type}' data-answer='{answer_json}'>"
html += f"<h3>Question {i+1}: {question['question']}</h3>"
if question_type == "single_choice":
if "options" in question:
html += "<div class='options'>"
for option in question["options"]:
html += f"<div><input type='radio' name='q{i}' value='{option}'> {option}</div>"
html += "</div>"
elif question_type == "true_false":
html += "<div class='options'>"
html += (
f"<div><input type='radio' name='q{i}' value='True'> True</div>"
)
html += f"<div><input type='radio' name='q{i}' value='False'> False</div>"
html += "</div>"
elif question_type == "multiple_choice":
if "options" in question:
html += "<div class='options'>"
for option in question["options"]:
html += f"<div><input type='checkbox' name='q{i}[]' value='{option}'> {option}</div>"
html += "</div>"
elif question_type == "fill_in_the_blank":
html += (
"<input type='text' placeholder='Enter your answer here...'>"
)
html += "</div>"
# Updated button to use validateForm first and then call checkAnswers if validation passes
html += "<button type='button' class='submit-btn' onclick='if(validateForm()) checkAnswers(event);'>Submit Quiz</button>"
html += "</form>" # Close the form
html += "<div id='result'></div>"
html += "</div>"
html += "<details id='quiz-answers' style='display:none;'>"
html += "<summary><h2>Solutions:</h2></summary>"
html += "<div class='answers-container'>"
for i, question in enumerate(quiz_data["quiz"]):
question_type = question["type"]
html += "<div class='answer-item'>"
html += f"<h3>Question {i+1}: {question['question']}</h3>"
# Format the answer based on question type
if question_type == "multiple_choice":
if isinstance(question["answer"], list):
answer_text = ", ".join(question["answer"])
html += f"<p><strong>Correct Answer:</strong> {answer_text}</p>"
else:
html += f"<p><strong>Correct Answer:</strong> {question['answer']}</p>"
elif question_type == "fill_in_the_blank":
html += (
f"<p><strong>Correct Answer:</strong> {question['answer']}</p>"
)
else: # single_choice or true_false
html += (
f"<p><strong>Correct Answer:</strong> {question['answer']}</p>"
)
html += "</div>"
html += "</div>" # Close answers-container
html += "</details>" # Close quiz-answers
return html, gr.Accordion(visible=True)
generate_btn.click(
fn=generate_quiz,
inputs=file_input,
outputs=[output_container, quiz_accordion],
)
app.launch()