File size: 5,482 Bytes
f2f372e
 
 
 
 
484bee1
 
f2f372e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484bee1
f2f372e
 
 
 
484bee1
f2f372e
 
 
484bee1
f2f372e
484bee1
 
 
f2f372e
484bee1
f2f372e
484bee1
 
f2f372e
484bee1
 
 
 
 
f2f372e
484bee1
 
f2f372e
484bee1
 
f2f372e
484bee1
 
 
f2f372e
484bee1
 
 
 
 
 
 
f2f372e
484bee1
 
 
 
f2f372e
484bee1
 
 
 
 
 
 
 
 
 
 
f2f372e
 
484bee1
 
 
 
f2f372e
484bee1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f2f372e
484bee1
 
f2f372e
484bee1
f2f372e
484bee1
f2f372e
 
 
 
 
484bee1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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()