import gradio as gr from groq import Groq import os from PIL import Image, ImageDraw, ImageFont from datetime import datetime import json import tempfile # Initialize Groq client client = Groq( api_key=os.getenv("GROQ_API_KEY") ) class QuizApp: def __init__(self): self.current_questions = [] def generate_questions(self, text, num_questions): prompt = f"""Create exactly {num_questions} multiple choice questions based on this text: {text} For each question: 1. Create a clear, concise question 2. Provide exactly 4 options 3. Mark the correct answer with the index (0-3) 4. Ensure options are concise and clear Return ONLY a JSON array with this EXACT format - no other text: [ {{ "question": "Question text here?", "options": [ "Brief option 1", "Brief option 2", "Brief option 3", "Brief option 4" ], "correct_answer": 0 }} ] """ try: response = client.chat.completions.create( messages=[ {"role": "system", "content": "You are a quiz generator. Create clear questions with concise answer options."}, {"role": "user", "content": prompt} ], model="llama-3.2-3b-preview", temperature=0.3, max_tokens=2048 ) response_text = response.choices[0].message.content.strip() response_text = response_text.replace("```json", "").replace("```", "").strip() response_text = response_text[response_text.find("["):response_text.rfind("]")+1] questions = json.loads(response_text) validated_questions = [] for q in questions: if not all(key in q for key in ["question", "options", "correct_answer"]): continue clean_options = [opt.strip()[:100] for opt in q["options"] if isinstance(opt, str)] if len(clean_options) != 4: continue clean_q = { "question": q["question"].strip(), "options": clean_options, "correct_answer": int(q["correct_answer"]) % 4 } validated_questions.append(clean_q) self.current_questions = validated_questions[:num_questions] return True, self.current_questions except Exception as e: print(f"Error in question generation: {str(e)}") return False, [] def calculate_score(self, answers): if not answers or not self.current_questions: return 0, [] total = len(self.current_questions) correct = 0 results = [] for i, (q, a) in enumerate(zip(self.current_questions, answers)): try: if a is not None: selected_index = q["options"].index(a) is_correct = selected_index == q["correct_answer"] if is_correct: correct += 1 results.append({ "is_correct": is_correct, "correct_answer": q["options"][q["correct_answer"]] }) else: results.append({ "is_correct": False, "correct_answer": q["options"][q["correct_answer"]] }) except (ValueError, TypeError) as e: print(f"Error processing answer {i}: {e}") results.append({ "is_correct": False, "correct_answer": q["options"][q["correct_answer"]] }) return (correct / total) * 100, results def create_quiz_interface(): quiz_app = QuizApp() with gr.Blocks(title="CertifyMe AI", theme=gr.themes.Soft()) as demo: # Header gr.Markdown(""" # 🎓 CertifyMe AI ### Transform Your Knowledge into Recognized Achievements """) # Tabs with gr.Tabs() as tabs: # Step 1: Profile Setup with gr.Tab("📋 Step 1: Profile Setup") as tab1: with gr.Row(): name = gr.Textbox(label="Full Name", placeholder="Enter your full name") email = gr.Textbox(label="Email", placeholder="Enter your email") text_input = gr.Textbox( label="Learning Content", placeholder="Enter the text content you want to be assessed on", lines=10 ) num_questions = gr.Slider( minimum=1, maximum=5, value=3, step=1, label="Number of Questions" ) with gr.Row(): company_logo = gr.Image(label="Company Logo (Optional)", type="filepath") participant_photo = gr.Image(label="Your Photo (Optional)", type="filepath") generate_btn = gr.Button("Generate Assessment", variant="primary", size="lg") # Step 2: Take Assessment with gr.Tab("📝 Step 2: Take Assessment") as tab2: question_box = gr.Markdown("") answers = [] feedback = [] for i in range(5): radio = gr.Radio( choices=[], label=f"Question {i+1}", visible=False ) answers.append(radio) fb = gr.Markdown(visible=False) feedback.append(fb) submit_btn = gr.Button("Submit Assessment", variant="primary", size="lg") result_message = gr.Markdown("") # Step 3: Get Certified with gr.Tab("🎓 Step 3: Get Certified") as tab3: score_display = gr.Number(label="Your Score") completion_message = gr.Markdown("") course_name = gr.Textbox( label="Certification Title", value="Professional Assessment Certification" ) certificate_display = gr.Image(label="Your Certificate") # Store questions state questions_state = gr.State([]) def update_questions(text, num_questions): if not text.strip(): return ( gr.update(value="Please enter content to generate questions."), *[gr.update(visible=False) for _ in range(5)], # Radio buttons *[gr.update(visible=False) for _ in range(5)], # Feedback [], # questions state 1, # tab index "Please enter content to generate questions." # result message ) success, questions = quiz_app.generate_questions(text, num_questions) if not success: return ( gr.update(value="Failed to generate questions. Please try again."), *[gr.update(visible=False) for _ in range(5)], *[gr.update(visible=False) for _ in range(5)], [], 1, "Failed to generate questions. Please try again." ) # Create question display with embedded radio buttons questions_md = "# 📝 Assessment Questions\n\n" # Update radio buttons and create question display radio_updates = [] feedback_updates = [] for i, q in enumerate(questions): questions_md += f"### Question {i+1}\n{q['question']}\n\n" radio_updates.append(gr.update( choices=q["options"], label=f"Select your answer for Question {i+1}:", visible=True, value=None )) feedback_updates.append(gr.update(visible=False, value="")) # Hide unused radio buttons for i in range(len(questions), 5): radio_updates.append(gr.update(visible=False)) feedback_updates.append(gr.update(visible=False)) return ( gr.update(value=questions_md), *radio_updates, *feedback_updates, questions, 1, "" ) def submit_answers(q1, q2, q3, q4, q5, questions): answers = [q1, q2, q3, q4, q5][:len(questions)] if not all(a is not None for a in answers): return [gr.update() for _ in range(5)], 0, "Please answer all questions before submitting." score, results = quiz_app.calculate_score(answers) # Create feedback for each answer feedback_updates = [] for i, result in enumerate(results): if result["is_correct"]: feedback_updates.append(gr.update( visible=True, value='