Spaces:
Sleeping
Sleeping
import os | |
import streamlit as st | |
from dotenv import load_dotenv | |
from langchain.prompts import ChatPromptTemplate | |
from langchain_openai import ChatOpenAI | |
from langchain.schema import StrOutputParser | |
from docx import Document | |
import fitz # PyMuPDF | |
def extract_text_from_pdf_or_docx(file): | |
"""Extract text from PDF or Word document.""" | |
filename = file.name | |
text = "" | |
if filename.endswith('.pdf'): | |
# Extract text from PDF | |
with fitz.open(file) as doc: | |
for page in doc: | |
text += page.get_text() | |
elif filename.endswith('.docx'): | |
# Extract text from Word document | |
doc = Document(file) | |
for paragraph in doc.paragraphs: | |
text += paragraph.text + "\n" | |
else: | |
text = "Unsupported file format. Please upload a PDF or Word document." | |
return text | |
def create_multiple_choice_prompt(num_questions, quiz_context, expertise): | |
"""Create the prompt template for multiple-choice quiz.""" | |
template = f""" | |
You are an expert in {expertise}. Generate a quiz with {num_questions} multiple-choice questions that are relevant to {expertise} based on the following content: {quiz_context}. | |
The questions should be at the level of {expertise} and should challenge the knowledge of someone proficient in this field. | |
The format of the quiz is as follows: | |
- Multiple-choice: | |
- Questions: | |
1. <Question1>: | |
a. Answer 1 | |
b. Answer 2 | |
c. Answer 3 | |
d. Answer 4 | |
2. <Question2>: | |
a. Answer 1 | |
b. Answer 2 | |
c. Answer 3 | |
d. Answer 4 | |
.... | |
- Answers: | |
1. <a|b|c|d> | |
2. <a|b|c|d> | |
.... | |
Example: | |
- Questions: | |
1. What is the time complexity of a binary search tree? | |
a. O(n) | |
b. O(log n) | |
c. O(n^2) | |
d. O(1) | |
- Answers: | |
1. b | |
""" | |
return template | |
def create_true_false_prompt(num_questions, quiz_context, expertise): | |
"""Create the prompt template for true-false quiz.""" | |
template = f""" | |
You are an expert in {expertise}. Generate a quiz with {num_questions} true-false questions that are relevant to {expertise} based on the following content: {quiz_context}. | |
The questions should be at the level of {expertise} and should challenge the knowledge of someone proficient in this field. | |
The format of the quiz is as follows: | |
- True-false: | |
- Questions: | |
1. <Question1>: <True|False> | |
2. <Question2>: <True|False> | |
..... | |
- Answers: | |
1. <True|False> | |
2. <True|False> | |
..... | |
Example: | |
- Questions: | |
1. A binary search tree is a type of data structure. | |
2. Binary search trees are typically used for sorting and searching operations. | |
- Answers: | |
1. True | |
2. True | |
""" | |
return template | |
def create_open_ended_prompt(num_questions, quiz_context, expertise): | |
"""Create the prompt template for open-ended quiz.""" | |
template = f""" | |
You are an expert in {expertise}. Generate a quiz with {num_questions} open-ended questions that are relevant to {expertise} based on the following content: {quiz_context}. | |
The questions should be at the level of {expertise} and should challenge the knowledge of someone proficient in this field. | |
The format of the quiz is as follows: | |
- Open-ended: | |
- Questions: | |
1. <Question1> | |
2. <Question2> | |
.... | |
Example: | |
- Questions: | |
1. What is a binary search tree? | |
2. How are binary search trees implemented? | |
""" | |
return template | |
def create_fill_in_the_blank_prompt(num_questions, quiz_context, expertise): | |
"""Create the prompt template for fill-in-the-blank quiz.""" | |
template = f""" | |
You are an expert in {expertise}. Generate a quiz with {num_questions} fill-in-the-blank questions that are relevant to {expertise} based on the following content: {quiz_context}. | |
The questions should be at the level of {expertise} and should challenge the knowledge of someone proficient in this field. | |
The format of the quiz is as follows: | |
- Fill-in-the-blank: | |
- Questions: | |
1. <Question1>: <Fill-in-the-blank> | |
2. <Question2>: <Fill-in-the-blank> | |
.... | |
Example: | |
- Questions: | |
1. A binary search tree is a ________ data structure. | |
2. Binary search trees are implemented using ________. | |
- Answers: | |
1. hierarchical | |
2. linked lists | |
""" | |
return template | |
def create_mixed_questions_prompt(num_questions, quiz_context, expertise): | |
"""Create the prompt template for a mix of all question types.""" | |
template = f""" | |
You are an expert in {expertise}. Generate a quiz with {num_questions} questions that include a mix of multiple-choice, true-false, open-ended, and fill-in-the-blank questions relevant to {expertise} based on the following content: {quiz_context}. | |
The questions should be at the level of {expertise} and should challenge the knowledge of someone proficient in this field. | |
The format of the quiz is as follows: | |
- Mixed Questions: | |
- Questions: | |
1. <Question1> (Multiple-choice): | |
a. Answer 1 | |
b. Answer 2 | |
c. Answer 3 | |
d. Answer 4 | |
2. <Question2> (True/False): | |
<Question2>: <True|False> | |
3. <Question3> (Open-ended): | |
<Question3> | |
4. <Question4> (Fill-in-the-blank): | |
<Question4>: <Fill-in-the-blank> | |
.... | |
- Answers: | |
1. <a|b|c|d> | |
2. <True|False> | |
3. <Open-ended Answer> | |
4. <Fill-in-the-blank Answer> | |
.... | |
Example: | |
- Questions: | |
1. What is the time complexity of a binary search tree? (Multiple-choice) | |
a. O(n) | |
b. O(log n) | |
c. O(n^2) | |
d. O(1) | |
2. A binary search tree is a type of data structure. (True/False) | |
True | |
3. What is a binary search tree? (Open-ended) | |
4. A binary search tree is a ________ data structure. (Fill-in-the-blank) | |
- Answers: | |
1. b | |
2. True | |
3. A binary search tree is a data structure used to store data in a sorted manner. | |
4. hierarchical | |
""" | |
return template | |
def create_quiz_chain(openai_api_key): | |
"""Creates the chain for the quiz app.""" | |
llm = ChatOpenAI(temperature=0.0, openai_api_key=openai_api_key) | |
return llm | StrOutputParser() | |
def split_questions_answers(quiz_response): | |
"""Function that splits the questions and answers from the quiz response.""" | |
if "Answers:" in quiz_response: | |
questions = quiz_response.split("Answers:")[0] | |
answers = quiz_response.split("Answers:")[1] | |
else: | |
questions = quiz_response | |
answers = "Answers section not found in the response." | |
return questions, answers | |
def main(): | |
st.title("QuesPro") | |
st.write("This app generates questions based on the uploaded document.") | |
load_dotenv() | |
openai_api_key = os.getenv("OPENAI_API_KEY") | |
uploaded_file = st.file_uploader("Upload a PDF or Word document") | |
if uploaded_file is not None: | |
text = extract_text_from_pdf_or_docx(uploaded_file) | |
num_questions = st.number_input("Enter the number of questions", min_value=1, max_value=10, value=3) | |
quiz_type = st.selectbox("Select the quiz type", ["multiple-choice", "true-false", "open-ended", "fill-in-the-blank", "mixed"]) | |
expertise = st.text_input("Enter the field of expertise for the quiz") | |
if st.button("Generate Questions"): | |
if quiz_type == "multiple-choice": | |
prompt_template = create_multiple_choice_prompt(num_questions, text, expertise) | |
elif quiz_type == "true-false": | |
prompt_template = create_true_false_prompt(num_questions, text, expertise) | |
elif quiz_type == "open-ended": | |
prompt_template = create_open_ended_prompt(num_questions, text, expertise) | |
elif quiz_type == "fill-in-the-blank": | |
prompt_template = create_fill_in_the_blank_prompt(num_questions, text, expertise) | |
else: # mixed | |
prompt_template = create_mixed_questions_prompt(num_questions, text, expertise) | |
chain = create_quiz_chain(openai_api_key) | |
quiz_response = chain.invoke(prompt_template) | |
st.write("Quiz Generated!") | |
questions, answers = split_questions_answers(quiz_response) | |
st.session_state.answers = answers | |
st.session_state.questions = questions | |
st.write(questions) | |
if st.button("Show Answers"): | |
st.markdown(st.session_state.questions) | |
st.write("----") | |
st.markdown(st.session_state.answers) | |
if __name__ == "__main__": | |
main() | |