Quizy / app.py
Abhinav
Refactor AI integration and enhance quiz functionality with validation
484bee1
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()