import pandas as pd import gradio as gr from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity # Load CSV df = pd.read_csv("mcq_dataset.csv") domains = sorted(df["domain"].dropna().unique().tolist()) # Get subdomains def get_subdomains(domain): return sorted(df[df["domain"] == domain]["subdomain"].dropna().unique().tolist()) # Get top MCQs def get_top_mcqs(user_input, domain, subdomain, top_n=10): filtered_df = df[(df["domain"] == domain) & (df["subdomain"] == subdomain)] if filtered_df.empty: return pd.DataFrame() if not user_input.strip(): return filtered_df.head(top_n).reset_index(drop=True) documents = filtered_df["keywords"].fillna("").tolist() documents.insert(0, user_input) vectorizer = TfidfVectorizer() tfidf_matrix = vectorizer.fit_transform(documents) cosine_sim = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:]).flatten() top_indices = cosine_sim.argsort()[-top_n:][::-1] return filtered_df.iloc[top_indices].reset_index(drop=True) # Start quiz def start_quiz(user_input, domain, subdomain): quiz_df = get_top_mcqs(user_input, domain, subdomain) if quiz_df.empty: return "No questions found.", gr.update(visible=False), None, 0, 0 first_question = quiz_df.iloc[0] question_text = f"Q1: {first_question['question']}\nA. {first_question['option1']}\nB. {first_question['option2']}\nC. {first_question['option3']}\nD. {first_question['option4']}" return question_text, gr.update(visible=True), quiz_df, 0, 0 # Handle answer and move to next def next_question(user_answer, quiz_df, current_index, score): if quiz_df is None or current_index >= len(quiz_df): return "No quiz in progress.", quiz_df, current_index, score, gr.update(visible=False) row = quiz_df.iloc[current_index] correct = row["correct_answer"] options = [row["option1"], row["option2"], row["option3"], row["option4"]] answer_map = {'A': 0, 'B': 1, 'C': 2, 'D': 3} if user_answer.upper() in answer_map and options[answer_map[user_answer.upper()]] == correct: score += 1 current_index += 1 if current_index >= len(quiz_df): return f"🎯 Quiz Complete! Final Score: {score}/{len(quiz_df)}", quiz_df, current_index, score, gr.update(visible=False) next_row = quiz_df.iloc[current_index] question_text = f"Q{current_index+1}: {next_row['question']}\nA. {next_row['option1']}\nB. {next_row['option2']}\nC. {next_row['option3']}\nD. {next_row['option4']}" return question_text, quiz_df, current_index, score, gr.update(visible=True) with gr.Blocks() as demo: gr.Markdown("## 🧠 Interactive MCQ Quiz (1-at-a-time)") with gr.Row(): domain_dropdown = gr.Dropdown(label="Select Domain", choices=domains) subdomain_dropdown = gr.Dropdown(label="Select Subdomain") def update_subdomain_ui(domain): return gr.update(choices=get_subdomains(domain), value=None) domain_dropdown.change(fn=update_subdomain_ui, inputs=domain_dropdown, outputs=subdomain_dropdown) user_input = gr.Textbox(label="Keywords (optional)") start_btn = gr.Button("Start Quiz") question_display = gr.Markdown("") answer_input = gr.Textbox(label="Your Answer (A/B/C/D)") next_btn = gr.Button("Next Question", visible=False) # State variables quiz_data = gr.State() current_index = gr.State() current_score = gr.State() # Start quiz start_btn.click( fn=start_quiz, inputs=[user_input, domain_dropdown, subdomain_dropdown], outputs=[question_display, next_btn, quiz_data, current_index, current_score] ) # Next question next_btn.click( fn=next_question, inputs=[answer_input, quiz_data, current_index, current_score], outputs=[question_display, quiz_data, current_index, current_score, next_btn] ) demo.launch()