capradeepgujaran commited on
Commit
b1c910f
1 Parent(s): 4ccbe29

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +188 -121
app.py CHANGED
@@ -20,31 +20,35 @@ class QuizApp:
20
  prompt = f"""Generate {num_questions} multiple choice questions based on this text:
21
  {text}
22
 
23
- Return the response in this JSON format:
24
- {{
25
- "questions": [
26
- {{
27
- "question": "Question text",
28
- "options": ["option1", "option2", "option3", "option4"],
29
- "correct_answers": [0, 1]
30
- }}
31
- ]
32
- }}
33
- Only return the JSON, no other text."""
34
-
35
- # Use Groq API directly
36
- response = client.chat.completions.create(
37
- messages=[{"role": "user", "content": prompt}],
38
- model="llama-3.2-3b-preview",
39
- temperature=0.7,
40
- max_tokens=1024
41
- )
42
 
43
  try:
 
 
 
 
 
 
 
 
44
  questions = json.loads(response.choices[0].message.content)
45
- self.current_questions = questions["questions"]
46
- return json.dumps(questions["questions"], indent=2)
47
- except json.JSONDecodeError:
 
 
 
 
 
 
48
  return json.dumps({"error": "Failed to generate valid questions. Please try again."})
49
 
50
  def calculate_score(self, answers):
@@ -58,127 +62,190 @@ class QuizApp:
58
  correct += 1
59
 
60
  return (correct / total) * 100
61
- except:
 
62
  return 0
63
 
64
  def generate_certificate(self, name, score, course_name, company_logo=None, participant_photo=None):
65
- # Create certificate
66
- certificate = Image.new('RGB', (1200, 800), 'white')
67
- draw = ImageDraw.Draw(certificate)
68
-
69
- # Load a default font
70
  try:
71
- title_font = ImageFont.truetype("arial.ttf", 60)
72
- text_font = ImageFont.truetype("arial.ttf", 40)
73
- except:
74
- # Fallback to default font
75
- title_font = ImageFont.load_default()
76
- text_font = ImageFont.load_default()
77
-
78
- # Add certificate content
79
- draw.text((600, 100), "Certificate of Completion", font=title_font, fill='black', anchor="mm")
80
- draw.text((600, 300), f"This is to certify that", font=text_font, fill='black', anchor="mm")
81
- draw.text((600, 380), name, font=text_font, fill='black', anchor="mm")
82
- draw.text((600, 460), f"has successfully completed", font=text_font, fill='black', anchor="mm")
83
- draw.text((600, 540), course_name, font=text_font, fill='black', anchor="mm")
84
- draw.text((600, 620), f"with a score of {score:.1f}%", font=text_font, fill='black', anchor="mm")
85
-
86
- # Add date
87
- current_date = datetime.now().strftime("%B %d, %Y")
88
- draw.text((600, 700), current_date, font=text_font, fill='black', anchor="mm")
89
-
90
- # Add logo if provided
91
- if company_logo is not None:
92
- try:
93
- logo = Image.open(company_logo)
94
- logo = logo.resize((150, 150))
95
- certificate.paste(logo, (50, 50))
96
- except Exception as e:
97
- print(f"Error adding logo: {e}")
98
-
99
- # Add photo if provided
100
- if participant_photo is not None:
101
  try:
102
- photo = Image.open(participant_photo)
103
- photo = photo.resize((150, 150))
104
- certificate.paste(photo, (1000, 50))
105
- except Exception as e:
106
- print(f"Error adding photo: {e}")
107
-
108
- # Save to temporary file
109
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
110
- certificate.save(temp_file.name)
111
- return temp_file.name
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
  def create_quiz_app():
114
  quiz_app = QuizApp()
115
 
116
- with gr.Blocks(title="QuizForge AI") as demo:
117
- gr.Markdown("# QuizForge AI")
118
- gr.Markdown("### Generate personalized quizzes and earn certificates powered by AI")
119
 
120
- # User Information Tab
121
- with gr.Tab("Step 1: User Information"):
122
- with gr.Row():
123
- name = gr.Textbox(label="Full Name", placeholder="Enter your full name")
124
- email = gr.Textbox(label="Email", placeholder="Enter your email")
125
-
126
- text_input = gr.Textbox(
127
- label="Content for Quiz",
128
- placeholder="Enter the text content for generating questions",
129
- lines=10
130
- )
131
-
132
- with gr.Row():
133
- num_questions = gr.Slider(
134
- minimum=1,
135
- maximum=10,
136
- value=5,
137
- step=1,
138
- label="Number of Questions"
139
  )
140
 
141
- with gr.Row():
142
- company_logo = gr.Image(label="Company Logo (Optional)", type="filepath")
143
- participant_photo = gr.Image(label="Participant Photo (Optional)", type="filepath")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
- generate_btn = gr.Button("Generate Quiz", variant="primary")
146
-
147
- # Quiz Tab
148
- with gr.Tab("Step 2: Take Quiz"):
149
- gr.Markdown("""
150
- ### Instructions:
151
- 1. Questions will appear in JSON format below
152
- 2. Each question has multiple options
153
- 3. Enter answers as array indices (e.g., [0, 2] for first and third options)
154
- 4. Submit when ready to get your score
155
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
- questions_display = gr.JSON(label="Questions")
158
- answers_input = gr.JSON(label="Your Answers (Enter indices of correct options)")
159
- submit_btn = gr.Button("Submit Answers", variant="primary")
160
- score_display = gr.Number(label="Your Score")
 
 
 
 
 
 
 
 
 
 
 
161
 
162
- # Certificate Tab
163
- with gr.Tab("Step 3: Get Certificate"):
164
- gr.Markdown("### Your certificate will be generated automatically if you score 80% or above")
165
- course_name = gr.Textbox(
166
- label="Course Name",
167
- value="QuizForge AI Certification"
168
- )
169
- certificate_display = gr.Image(label="Certificate")
170
 
171
  # Event handlers
172
  generate_btn.click(
173
- fn=quiz_app.generate_questions,
174
  inputs=[text_input, num_questions],
175
- outputs=questions_display
 
 
 
 
176
  )
177
 
178
  submit_btn.click(
179
- fn=quiz_app.calculate_score,
180
  inputs=[answers_input],
181
- outputs=score_display
 
 
 
 
182
  )
183
 
184
  score_display.change(
@@ -198,4 +265,4 @@ if __name__ == "__main__":
198
  exit(1)
199
 
200
  demo = create_quiz_app()
201
- demo.launch(share=True)
 
20
  prompt = f"""Generate {num_questions} multiple choice questions based on this text:
21
  {text}
22
 
23
+ Format your response as a list of questions, where each question is a JSON object with the following structure:
24
+ [
25
+ {{
26
+ "question": "Question text",
27
+ "options": ["option1", "option2", "option3", "option4"],
28
+ "correct_answers": [0, 1]
29
+ }}
30
+ ]
31
+ Only return the JSON array, no other text."""
 
 
 
 
 
 
 
 
 
 
32
 
33
  try:
34
+ response = client.chat.completions.create(
35
+ messages=[{"role": "user", "content": prompt}],
36
+ model="llama2-70b-4096",
37
+ temperature=0.7,
38
+ max_tokens=1024
39
+ )
40
+
41
+ # Parse the response directly as a list
42
  questions = json.loads(response.choices[0].message.content)
43
+ if isinstance(questions, list):
44
+ self.current_questions = questions
45
+ else:
46
+ # If we get an object with a questions key, extract the list
47
+ self.current_questions = questions.get("questions", [])
48
+
49
+ return json.dumps(self.current_questions, indent=2)
50
+ except Exception as e:
51
+ print(f"Error generating questions: {e}")
52
  return json.dumps({"error": "Failed to generate valid questions. Please try again."})
53
 
54
  def calculate_score(self, answers):
 
62
  correct += 1
63
 
64
  return (correct / total) * 100
65
+ except Exception as e:
66
+ print(f"Error calculating score: {e}")
67
  return 0
68
 
69
  def generate_certificate(self, name, score, course_name, company_logo=None, participant_photo=None):
 
 
 
 
 
70
  try:
71
+ # Create certificate with a light blue background
72
+ certificate = Image.new('RGB', (1200, 800), '#F0F8FF')
73
+ draw = ImageDraw.Draw(certificate)
74
+
75
+ # Load fonts
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  try:
77
+ title_font = ImageFont.truetype("arial.ttf", 60)
78
+ text_font = ImageFont.truetype("arial.ttf", 40)
79
+ subtitle_font = ImageFont.truetype("arial.ttf", 30)
80
+ except:
81
+ print("Using default font as Arial not found")
82
+ title_font = ImageFont.load_default()
83
+ text_font = ImageFont.load_default()
84
+ subtitle_font = ImageFont.load_default()
85
+
86
+ # Add decorative border
87
+ draw.rectangle([20, 20, 1180, 780], outline='#4682B4', width=3)
88
+
89
+ # Draw certificate content
90
+ draw.text((600, 100), "CertifyMe AI", font=title_font, fill='#4682B4', anchor="mm")
91
+ draw.text((600, 160), "Certificate of Achievement", font=subtitle_font, fill='#4682B4', anchor="mm")
92
+ draw.text((600, 300), "This is to certify that", font=text_font, fill='black', anchor="mm")
93
+ draw.text((600, 380), name, font=text_font, fill='#4682B4', anchor="mm")
94
+ draw.text((600, 460), "has successfully completed", font=text_font, fill='black', anchor="mm")
95
+ draw.text((600, 540), course_name, font=text_font, fill='#4682B4', anchor="mm")
96
+ draw.text((600, 620), f"with a score of {score:.1f}%", font=text_font, fill='black', anchor="mm")
97
+
98
+ # Add date
99
+ current_date = datetime.now().strftime("%B %d, %Y")
100
+ draw.text((600, 700), current_date, font=text_font, fill='black', anchor="mm")
101
+
102
+ # Add logo if provided
103
+ if company_logo is not None:
104
+ try:
105
+ logo = Image.open(company_logo)
106
+ logo = logo.resize((150, 150))
107
+ certificate.paste(logo, (50, 50))
108
+ except Exception as e:
109
+ print(f"Error adding logo: {e}")
110
+
111
+ # Add photo if provided
112
+ if participant_photo is not None:
113
+ try:
114
+ photo = Image.open(participant_photo)
115
+ photo = photo.resize((150, 150))
116
+ certificate.paste(photo, (1000, 50))
117
+ except Exception as e:
118
+ print(f"Error adding photo: {e}")
119
+
120
+ # Save certificate
121
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
122
+ certificate.save(temp_file.name)
123
+ return temp_file.name
124
+ except Exception as e:
125
+ print(f"Error generating certificate: {e}")
126
+ return None
127
 
128
  def create_quiz_app():
129
  quiz_app = QuizApp()
130
 
131
+ with gr.Blocks(title="CertifyMe AI") as demo:
132
+ # Store current tab state
133
+ current_tab = gr.State(0)
134
 
135
+ gr.Markdown("""
136
+ # CertifyMe AI
137
+ ### Transform Your Knowledge into Recognized Achievements
138
+ Get AI-powered assessments and professional certificates for any learning content.
139
+ """)
140
+
141
+ # Create tabs
142
+ with gr.Tabs() as tabs:
143
+ # Step 1: Profile Setup
144
+ with gr.Tab("📋 Step 1: Profile Setup", id=0) as tab1:
145
+ with gr.Row():
146
+ name = gr.Textbox(label="Full Name", placeholder="Enter your full name")
147
+ email = gr.Textbox(label="Email", placeholder="Enter your email")
148
+
149
+ text_input = gr.Textbox(
150
+ label="Learning Content",
151
+ placeholder="Enter the text content you want to be assessed on",
152
+ lines=10
 
153
  )
154
 
155
+ with gr.Row():
156
+ num_questions = gr.Slider(
157
+ minimum=1,
158
+ maximum=10,
159
+ value=5,
160
+ step=1,
161
+ label="Number of Questions"
162
+ )
163
+
164
+ with gr.Row():
165
+ company_logo = gr.Image(
166
+ label="Company Logo (Optional)",
167
+ type="filepath"
168
+ )
169
+ participant_photo = gr.Image(
170
+ label="Your Photo (Optional)",
171
+ type="filepath"
172
+ )
173
+
174
+ generate_btn = gr.Button("Generate Assessment", variant="primary")
175
 
176
+ # Instructions for Step 1
177
+ gr.Markdown("""
178
+ ### Instructions:
179
+ 1. Enter your full name and email
180
+ 2. Paste or type the learning content you want to be assessed on
181
+ 3. Select the number of questions for your assessment
182
+ 4. Optionally upload a company logo and your photo for the certificate
183
+ 5. Click 'Generate Assessment' to proceed
184
+ """)
185
+
186
+ # Step 2: Take Assessment
187
+ with gr.Tab("📝 Step 2: Take Assessment", id=1) as tab2:
188
+ gr.Markdown("""
189
+ ### Assessment Instructions:
190
+ 1. Review each question carefully
191
+ 2. For each question, you may select one or more correct options
192
+ 3. Enter your answers as arrays of indices (e.g., [0, 2] for first and third options)
193
+ 4. Click 'Submit Assessment' when you're ready
194
+ 5. You need 80% or higher to earn your certificate
195
+ """)
196
+
197
+ questions_display = gr.JSON(label="Assessment Questions")
198
+ answers_input = gr.JSON(
199
+ label="Your Answers",
200
+ placeholder="Enter answers as arrays of indices, e.g., [[0], [1, 2], [3]]"
201
+ )
202
+ submit_btn = gr.Button("Submit Assessment", variant="primary")
203
+ score_display = gr.Number(label="Your Score")
204
 
205
+ # Step 3: Get Certified
206
+ with gr.Tab("🎓 Step 3: Get Certified", id=2) as tab3:
207
+ gr.Markdown("""
208
+ ### Certification
209
+ - Your certificate will be generated automatically if you score 80% or above
210
+ - The certificate includes your name, score, and completion date
211
+ - Company logo and photo will be included if provided
212
+ - You can download your certificate once it's generated
213
+ """)
214
+
215
+ course_name = gr.Textbox(
216
+ label="Certification Title",
217
+ value="Professional Assessment Certification"
218
+ )
219
+ certificate_display = gr.Image(label="Your Certificate")
220
 
221
+ # Helper functions for tab navigation
222
+ def generate_and_switch_tab(text, num_questions):
223
+ questions = quiz_app.generate_questions(text, num_questions)
224
+ return questions, 1
225
+
226
+ def submit_and_switch_tab(answers):
227
+ score = quiz_app.calculate_score(answers)
228
+ return score, 2
229
 
230
  # Event handlers
231
  generate_btn.click(
232
+ fn=generate_and_switch_tab,
233
  inputs=[text_input, num_questions],
234
+ outputs=[questions_display, current_tab]
235
+ ).then(
236
+ fn=lambda tab: gr.Tabs(selected=tab),
237
+ inputs=[current_tab],
238
+ outputs=[tabs]
239
  )
240
 
241
  submit_btn.click(
242
+ fn=submit_and_switch_tab,
243
  inputs=[answers_input],
244
+ outputs=[score_display, current_tab]
245
+ ).then(
246
+ fn=lambda tab: gr.Tabs(selected=tab),
247
+ inputs=[current_tab],
248
+ outputs=[tabs]
249
  )
250
 
251
  score_display.change(
 
265
  exit(1)
266
 
267
  demo = create_quiz_app()
268
+ demo.launch()