nex2 / app.py
byteforcegokul's picture
Update app.py
1ac46f2 verified
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()