Spaces:
Running
Running
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('"', """) | |
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() | |