Spaces:
Sleeping
Sleeping
Download app.py from YAMITEK/PDF-based-MCQ-Generator: direct link, hf CLI and curl.
- Browser
- Download file 4.26 kB
-
https://huggingface.co/spaces/YAMITEK/PDF-based-MCQ-Generator/resolve/main/app.py
- Command line
-
hf download hf://spaces/YAMITEK/PDF-based-MCQ-Generator/app.py
-
curl -L -o app.py https://huggingface.co/spaces/YAMITEK/PDF-based-MCQ-Generator/resolve/main/app.py
4.26 kB
| import streamlit as st | |
| from langchain.prompts import PromptTemplate | |
| from langchain.chains import LLMChain | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| import fitz | |
| import json | |
| import docx | |
| import os | |
| # Title | |
| st.title("๐ File-based MCQ Generator") | |
| # Sidebar | |
| st.sidebar.title("Upload & Settings") | |
| # Upload file | |
| uploaded_file = st.sidebar.file_uploader("Upload a file (PDF or Word)", type=["pdf", "docx"]) | |
| # Number of questions | |
| number_of_questions = st.sidebar.slider("Number of questions", min_value=1, max_value=20, value=5) | |
| # Session states | |
| if "mcqs" not in st.session_state: | |
| st.session_state.mcqs = [] | |
| if "current_q" not in st.session_state: | |
| st.session_state.current_q = 0 | |
| if "user_answers" not in st.session_state: | |
| st.session_state.user_answers = {} | |
| if "quiz_finished" not in st.session_state: | |
| st.session_state.quiz_finished = False | |
| # Gemini setup | |
| GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") | |
| llm = ChatGoogleGenerativeAI( | |
| model="gemini-2.0-flash", | |
| google_api_key=GOOGLE_API_KEY, | |
| temperature=0.7 | |
| ) | |
| template = """ | |
| You are an expert MCQ generator. Generate {number} unique multiple-choice questions from the given text. | |
| Each question must have exactly 1 correct answer and 3 incorrect options. | |
| Strictly return output in the following JSON format (no explanations, no markdown): | |
| [ | |
| {{ | |
| "question": "What is ...?", | |
| "options": ["Option A", "Option B", "Option C", "Option D"], | |
| "answer": "Option D" | |
| }}, | |
| ... | |
| ] | |
| TEXT: | |
| {text} | |
| """ | |
| prompt = PromptTemplate( | |
| input_variables=["text", "number"], | |
| template=template | |
| ) | |
| mcq_chain = LLMChain(llm=llm, prompt=prompt) | |
| # Extract text from PDF or Word | |
| def extract_text(file): | |
| if file.name.endswith(".pdf"): | |
| # Read the entire file content into memory | |
| file_bytes = file.read() | |
| # Open the PDF from the byte stream | |
| doc = fitz.open(stream=file_bytes, filetype="pdf") | |
| # Extract text from all pages | |
| text = "" | |
| for page in doc: | |
| text += page.get_text() | |
| return text | |
| elif file.name.endswith(".docx"): | |
| doc = docx.Document(file) | |
| return "\n".join([para.text for para in doc.paragraphs]) | |
| return "" | |
| # Generate MCQs | |
| if st.sidebar.button("Generate MCQs"): | |
| if uploaded_file is None: | |
| st.error("Please upload a file.") | |
| else: | |
| with st.spinner("Extracting text and generating MCQs..."): | |
| text = extract_text(uploaded_file) | |
| try: | |
| response = mcq_chain.run(text=text, number=str(number_of_questions)) | |
| mcqs_json = json.loads(response[8:-3]) | |
| st.session_state.mcqs = mcqs_json | |
| st.session_state.current_q = 0 | |
| st.session_state.user_answers = {} | |
| st.session_state.quiz_finished = False | |
| st.success("โ MCQs generated successfully!") | |
| except Exception as e: | |
| st.error(f"Error generating MCQs: {e}") | |
| # Display question | |
| if st.session_state.mcqs and not st.session_state.quiz_finished: | |
| idx = st.session_state.current_q | |
| q_data = st.session_state.mcqs[idx] | |
| st.subheader(f"Question {idx + 1}: {q_data['question']}") | |
| with st.form(key=f"form_{idx}"): | |
| selected_option = st.radio("Choose an answer:", q_data["options"], key=f"radio_{idx}") | |
| submitted = st.form_submit_button("Next") | |
| if submitted: | |
| st.session_state.user_answers[idx] = selected_option | |
| if idx < len(st.session_state.mcqs) - 1: | |
| st.session_state.current_q += 1 | |
| else: | |
| st.session_state.quiz_finished = True | |
| st.success("๐ Quiz completed!") | |
| # Show result | |
| if st.session_state.quiz_finished: | |
| st.header("๐ Quiz Results") | |
| score = 0 | |
| total = len(st.session_state.mcqs) | |
| for i, q in enumerate(st.session_state.mcqs): | |
| user_ans = st.session_state.user_answers.get(i) | |
| correct_ans = q["answer"] | |
| if user_ans == correct_ans: | |
| score += 1 | |
| st.markdown(f"**Q{i+1}: {q['question']}**") | |
| st.markdown(f"- Your answer: {user_ans}") | |
| st.markdown(f"- Correct answer: {correct_ans}") | |
| st.markdown("---") | |
| st.success(f"โ You scored {score} out of {total}") | |