Subh775 commited on
Commit
85787d2
Β·
verified Β·
1 Parent(s): 12b5885

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +340 -8
app.py CHANGED
@@ -6,6 +6,14 @@ from datetime import datetime
6
  import io
7
  import base64
8
  from transformers import pipeline
 
 
 
 
 
 
 
 
9
  import warnings
10
  warnings.filterwarnings("ignore")
11
 
@@ -125,7 +133,7 @@ def generate_ai_insights(student_name, subject, metrics, strengths, improvements
125
  print(f"AI generation error: {e}")
126
  return fallback_insights
127
 
128
- def create_performance_chart(metrics):
129
  """Create a simple performance visualization"""
130
  categories = ['Quiz Average', 'Assignment Average', 'Participation', 'Overall']
131
  scores = [metrics['quiz_avg'], metrics['assignment_avg'],
@@ -155,10 +163,192 @@ def create_performance_chart(metrics):
155
  bar.set_color('#E74C3C') # Red
156
 
157
  plt.tight_layout()
 
 
 
 
 
158
  return fig
159
 
160
- def generate_report(student_name, subject, quiz_scores_str, assignment_scores_str,
161
- participation_score, time_period, additional_notes=""):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  """Main function to generate the complete student report"""
163
 
164
  try:
@@ -245,12 +435,117 @@ def generate_report(student_name, subject, quiz_scores_str, assignment_scores_st
245
  *Report generated by Scoreazy AI Agent | Educational Technology Solutions*
246
  """
247
 
248
- return report, chart
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
 
250
  except ValueError as e:
251
- return f"Error parsing scores: {str(e)}. Please ensure scores are numbers separated by commas.", None
252
  except Exception as e:
253
- return f"Error generating report: {str(e)}", None
254
 
255
  # Create Gradio interface
256
  def create_interface():
@@ -315,6 +610,11 @@ def create_interface():
315
  with gr.Column(scale=1):
316
  chart_output = gr.Plot(label="Performance Chart")
317
 
 
 
 
 
 
318
  # Example button
319
  def load_example():
320
  return (
@@ -327,6 +627,29 @@ def create_interface():
327
  "Student shows strong technical aptitude but could benefit from more consistent participation in class discussions."
328
  )
329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  example_btn = gr.Button("πŸ“‹ Load Example Data", variant="secondary")
331
  example_btn.click(
332
  fn=load_example,
@@ -335,10 +658,10 @@ def create_interface():
335
  )
336
 
337
  generate_btn.click(
338
- fn=generate_report,
339
  inputs=[student_name, subject, quiz_scores, assignment_scores,
340
  participation_score, time_period, additional_notes],
341
- outputs=[report_output, chart_output]
342
  )
343
 
344
  gr.Markdown("""
@@ -349,13 +672,22 @@ def create_interface():
349
  3. **Add participation score** using the slider
350
  4. **Click "Generate Report"** to create AI-powered analysis
351
  5. **Review the comprehensive report** with strengths, improvements, and recommendations
 
352
 
353
  ### πŸ”§ Features:
354
  - βœ… Automated performance analysis
355
  - βœ… AI-generated insights and recommendations
356
  - βœ… Visual performance charts
357
  - βœ… Professional report formatting
 
358
  - βœ… Customizable input parameters
 
 
 
 
 
 
 
359
  """)
360
 
361
  return app
 
6
  import io
7
  import base64
8
  from transformers import pipeline
9
+ from reportlab.lib.pagesizes import letter, A4
10
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle, PageBreak
11
+ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
12
+ from reportlab.lib.units import inch
13
+ from reportlab.lib import colors
14
+ from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY, TA_LEFT
15
+ import tempfile
16
+ import os
17
  import warnings
18
  warnings.filterwarnings("ignore")
19
 
 
133
  print(f"AI generation error: {e}")
134
  return fallback_insights
135
 
136
+ def create_performance_chart(metrics, save_path=None):
137
  """Create a simple performance visualization"""
138
  categories = ['Quiz Average', 'Assignment Average', 'Participation', 'Overall']
139
  scores = [metrics['quiz_avg'], metrics['assignment_avg'],
 
163
  bar.set_color('#E74C3C') # Red
164
 
165
  plt.tight_layout()
166
+
167
+ # Save chart if path provided
168
+ if save_path:
169
+ plt.savefig(save_path, dpi=300, bbox_inches='tight')
170
+
171
  return fig
172
 
173
+ def create_pdf_report(student_name, subject, time_period, metrics, strengths, improvements,
174
+ insights, participation_score, additional_notes="", chart_path=None):
175
+ """Generate a comprehensive PDF report"""
176
+
177
+ # Create temporary PDF file
178
+ temp_pdf = tempfile.NamedTemporaryFile(delete=False, suffix='.pdf')
179
+ pdf_path = temp_pdf.name
180
+ temp_pdf.close()
181
+
182
+ # Create PDF document
183
+ doc = SimpleDocTemplate(pdf_path, pagesize=A4, rightMargin=72, leftMargin=72,
184
+ topMargin=72, bottomMargin=18)
185
+
186
+ # Get styles
187
+ styles = getSampleStyleSheet()
188
+
189
+ # Custom styles
190
+ title_style = ParagraphStyle(
191
+ 'CustomTitle',
192
+ parent=styles['Heading1'],
193
+ fontSize=24,
194
+ spaceAfter=30,
195
+ alignment=TA_CENTER,
196
+ textColor=colors.darkblue
197
+ )
198
+
199
+ heading_style = ParagraphStyle(
200
+ 'CustomHeading',
201
+ parent=styles['Heading2'],
202
+ fontSize=16,
203
+ spaceAfter=12,
204
+ spaceBefore=20,
205
+ textColor=colors.darkblue
206
+ )
207
+
208
+ subheading_style = ParagraphStyle(
209
+ 'CustomSubheading',
210
+ parent=styles['Heading3'],
211
+ fontSize=14,
212
+ spaceAfter=8,
213
+ spaceBefore=12,
214
+ textColor=colors.darkgreen
215
+ )
216
+
217
+ body_style = ParagraphStyle(
218
+ 'CustomBody',
219
+ parent=styles['Normal'],
220
+ fontSize=11,
221
+ spaceAfter=6,
222
+ alignment=TA_JUSTIFY
223
+ )
224
+
225
+ # Build PDF content
226
+ story = []
227
+
228
+ # Title
229
+ story.append(Paragraph("πŸ“Š Student Performance Report", title_style))
230
+ story.append(Spacer(1, 12))
231
+
232
+ # Student Information Table
233
+ student_data = [
234
+ ['Student Name:', student_name],
235
+ ['Subject/Course:', subject],
236
+ ['Reporting Period:', time_period],
237
+ ['Report Generated:', datetime.now().strftime('%B %d, %Y')],
238
+ ['Generated By:', 'Scoreazy AI Agent']
239
+ ]
240
+
241
+ student_table = Table(student_data, colWidths=[2*inch, 4*inch])
242
+ student_table.setStyle(TableStyle([
243
+ ('BACKGROUND', (0, 0), (0, -1), colors.lightblue),
244
+ ('TEXTCOLOR', (0, 0), (0, -1), colors.darkblue),
245
+ ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
246
+ ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
247
+ ('FONTNAME', (1, 0), (1, -1), 'Helvetica'),
248
+ ('FONTSIZE', (0, 0), (-1, -1), 12),
249
+ ('GRID', (0, 0), (-1, -1), 1, colors.black),
250
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
251
+ ]))
252
+
253
+ story.append(student_table)
254
+ story.append(Spacer(1, 20))
255
+
256
+ # Performance Summary
257
+ story.append(Paragraph("πŸ“ˆ Performance Summary", heading_style))
258
+
259
+ performance_data = [
260
+ ['Metric', 'Score', 'Grade'],
261
+ ['Overall Performance', f"{metrics['overall_avg']}%", metrics['grade']],
262
+ ['Quiz Average', f"{metrics['quiz_avg']}%", ''],
263
+ ['Assignment Average', f"{metrics['assignment_avg']}%", ''],
264
+ ['Participation Score', f"{participation_score}%", '']
265
+ ]
266
+
267
+ performance_table = Table(performance_data, colWidths=[2.5*inch, 1.5*inch, 1*inch])
268
+ performance_table.setStyle(TableStyle([
269
+ ('BACKGROUND', (0, 0), (-1, 0), colors.darkblue),
270
+ ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
271
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
272
+ ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
273
+ ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
274
+ ('FONTSIZE', (0, 0), (-1, -1), 11),
275
+ ('GRID', (0, 0), (-1, -1), 1, colors.black),
276
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
277
+ ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
278
+ ]))
279
+
280
+ story.append(performance_table)
281
+ story.append(Spacer(1, 20))
282
+
283
+ # Add chart if available
284
+ if chart_path and os.path.exists(chart_path):
285
+ story.append(Paragraph("πŸ“Š Performance Visualization", heading_style))
286
+ chart_img = Image(chart_path, width=6*inch, height=3.6*inch)
287
+ story.append(chart_img)
288
+ story.append(Spacer(1, 20))
289
+
290
+ # Strengths Section
291
+ story.append(Paragraph("βœ… Identified Strengths", heading_style))
292
+
293
+ for i, strength in enumerate(strengths, 1):
294
+ story.append(Paragraph(f"<b>{i}. {strength.title()}</b>", subheading_style))
295
+ story.append(Paragraph(f"Student demonstrates consistent performance and understanding in this area, "
296
+ f"showing mastery of key concepts and skills.", body_style))
297
+ story.append(Spacer(1, 8))
298
+
299
+ # Areas for Improvement
300
+ story.append(Paragraph("⚠️ Areas for Improvement", heading_style))
301
+
302
+ for i, improvement in enumerate(improvements, 1):
303
+ story.append(Paragraph(f"<b>{i}. {improvement.title()}</b>", subheading_style))
304
+ story.append(Paragraph(f"This area presents opportunities for growth and enhanced learning outcomes. "
305
+ f"Focused attention in this area will yield significant improvements.", body_style))
306
+ story.append(Spacer(1, 8))
307
+
308
+ # Recommendations
309
+ story.append(Paragraph("🎯 Personalized Recommendations", heading_style))
310
+
311
+ for i, rec in enumerate(insights['recommendations'], 1):
312
+ story.append(Paragraph(f"<b>{i}.</b> {rec}", body_style))
313
+ story.append(Spacer(1, 6))
314
+
315
+ # Additional Notes
316
+ if additional_notes:
317
+ story.append(Spacer(1, 20))
318
+ story.append(Paragraph("πŸ“ Additional Notes", heading_style))
319
+ story.append(Paragraph(additional_notes, body_style))
320
+
321
+ # Next Steps
322
+ story.append(Spacer(1, 20))
323
+ story.append(Paragraph("πŸ“… Next Steps", heading_style))
324
+ next_steps = [
325
+ "Review this report with student and parent/guardian",
326
+ "Monitor progress on recommended improvement areas over the next 2-3 weeks",
327
+ "Schedule follow-up assessment to track improvement",
328
+ "Continue building on identified strengths through advanced challenges",
329
+ "Implement suggested study strategies and learning techniques"
330
+ ]
331
+
332
+ for step in next_steps:
333
+ story.append(Paragraph(f"β€’ {step}", body_style))
334
+ story.append(Spacer(1, 4))
335
+
336
+ # Footer
337
+ story.append(Spacer(1, 30))
338
+ footer_style = ParagraphStyle(
339
+ 'Footer',
340
+ parent=styles['Normal'],
341
+ fontSize=10,
342
+ alignment=TA_CENTER,
343
+ textColor=colors.grey
344
+ )
345
+ story.append(Paragraph("Report generated by Scoreazy AI Agent | Educational Technology Solutions", footer_style))
346
+ story.append(Paragraph("For questions or support, please contact your instructor", footer_style))
347
+
348
+ # Build PDF
349
+ doc.build(story)
350
+
351
+ return pdf_path
352
  """Main function to generate the complete student report"""
353
 
354
  try:
 
435
  *Report generated by Scoreazy AI Agent | Educational Technology Solutions*
436
  """
437
 
438
+ def generate_report(student_name, subject, quiz_scores_str, assignment_scores_str,
439
+ participation_score, time_period, additional_notes=""):
440
+ """Main function to generate the complete student report"""
441
+
442
+ try:
443
+ # Parse input scores
444
+ quiz_scores = [float(x.strip()) for x in quiz_scores_str.split(',') if x.strip()]
445
+ assignment_scores = [float(x.strip()) for x in assignment_scores_str.split(',') if x.strip()]
446
+
447
+ # Validate scores
448
+ all_scores = quiz_scores + assignment_scores + [participation_score]
449
+ if any(score < 0 or score > 100 for score in all_scores):
450
+ return "Error: All scores must be between 0 and 100.", None, None
451
+
452
+ # Calculate metrics
453
+ metrics = calculate_metrics(quiz_scores, assignment_scores, participation_score)
454
+ metrics['participation'] = participation_score
455
+
456
+ # Analyze performance
457
+ strengths, improvements = analyze_performance(metrics, quiz_scores, assignment_scores)
458
+
459
+ # Generate AI insights
460
+ insights = generate_ai_insights(student_name, subject, metrics, strengths, improvements)
461
+
462
+ # Create temporary file for chart
463
+ chart_temp = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
464
+ chart_path = chart_temp.name
465
+ chart_temp.close()
466
+
467
+ # Create visualization
468
+ chart = create_performance_chart(metrics, save_path=chart_path)
469
+
470
+ # Generate PDF report
471
+ pdf_path = create_pdf_report(
472
+ student_name, subject, time_period, metrics, strengths, improvements,
473
+ insights, participation_score, additional_notes, chart_path
474
+ )
475
+
476
+ # Generate report text for display
477
+ report = f"""
478
+ # πŸ“Š Student Performance Report
479
+
480
+ **Student Name:** {student_name}
481
+ **Subject:** {subject}
482
+ **Reporting Period:** {time_period}
483
+ **Generated Date:** {datetime.now().strftime('%B %d, %Y')}
484
+
485
+ ---
486
+
487
+ ## πŸ“ˆ Performance Summary
488
+ - **Overall Grade:** {metrics['grade']} ({metrics['overall_avg']}%)
489
+ - **Quiz Average:** {metrics['quiz_avg']}%
490
+ - **Assignment Average:** {metrics['assignment_avg']}%
491
+ - **Participation Score:** {participation_score}%
492
+
493
+ ---
494
+
495
+ ## βœ… Identified Strengths
496
+ """
497
+
498
+ for i, strength in enumerate(strengths, 1):
499
+ report += f"{i}. **{strength.title()}**: Demonstrates consistent performance and understanding in this area.\n"
500
+
501
+ report += "\n## ⚠️ Areas for Improvement\n"
502
+
503
+ for i, improvement in enumerate(improvements, 1):
504
+ report += f"{i}. **{improvement.title()}**: Focus area for enhanced learning outcomes.\n"
505
+
506
+ report += f"""
507
+ ---
508
+
509
+ ## 🎯 Recommendations
510
+
511
+ """
512
+ for i, rec in enumerate(insights['recommendations'], 1):
513
+ report += f"{i}. {rec}\n"
514
+
515
+ if additional_notes:
516
+ report += f"""
517
+ ---
518
+
519
+ ## πŸ“ Additional Notes
520
+ {additional_notes}
521
+ """
522
+
523
+ report += """
524
+ ---
525
+
526
+ ## πŸ“… Next Steps
527
+ - Review this report with student and parent/guardian
528
+ - Monitor progress on recommended improvement areas
529
+ - Schedule follow-up assessment in 2-3 weeks
530
+ - Continue building on identified strengths
531
+
532
+ ---
533
+
534
+ *Report generated by Scoreazy AI Agent | Educational Technology Solutions*
535
+ """
536
+
537
+ # Clean up temporary chart file
538
+ try:
539
+ os.unlink(chart_path)
540
+ except:
541
+ pass
542
+
543
+ return report, chart, pdf_path
544
 
545
  except ValueError as e:
546
+ return f"Error parsing scores: {str(e)}. Please ensure scores are numbers separated by commas.", None, None
547
  except Exception as e:
548
+ return f"Error generating report: {str(e)}", None, None
549
 
550
  # Create Gradio interface
551
  def create_interface():
 
610
  with gr.Column(scale=1):
611
  chart_output = gr.Plot(label="Performance Chart")
612
 
613
+ # PDF Download Section
614
+ with gr.Row():
615
+ pdf_output = gr.File(label="πŸ“„ Download PDF Report", visible=False)
616
+ download_status = gr.Markdown("", visible=False)
617
+
618
  # Example button
619
  def load_example():
620
  return (
 
627
  "Student shows strong technical aptitude but could benefit from more consistent participation in class discussions."
628
  )
629
 
630
+ def generate_and_update(student_name, subject, quiz_scores, assignment_scores,
631
+ participation_score, time_period, additional_notes):
632
+ """Generate report and update interface with PDF"""
633
+ report, chart, pdf_path = generate_report(
634
+ student_name, subject, quiz_scores, assignment_scores,
635
+ participation_score, time_period, additional_notes
636
+ )
637
+
638
+ if pdf_path and os.path.exists(pdf_path):
639
+ return (
640
+ report,
641
+ chart,
642
+ gr.update(value=pdf_path, visible=True),
643
+ gr.update(value="βœ… **PDF Report Generated Successfully!** Click the download button above to save your report.", visible=True)
644
+ )
645
+ else:
646
+ return (
647
+ report,
648
+ chart,
649
+ gr.update(visible=False),
650
+ gr.update(value="❌ Error generating PDF report." if pdf_path is None else "", visible=bool(report))
651
+ )
652
+
653
  example_btn = gr.Button("πŸ“‹ Load Example Data", variant="secondary")
654
  example_btn.click(
655
  fn=load_example,
 
658
  )
659
 
660
  generate_btn.click(
661
+ fn=generate_and_update,
662
  inputs=[student_name, subject, quiz_scores, assignment_scores,
663
  participation_score, time_period, additional_notes],
664
+ outputs=[report_output, chart_output, pdf_output, download_status]
665
  )
666
 
667
  gr.Markdown("""
 
672
  3. **Add participation score** using the slider
673
  4. **Click "Generate Report"** to create AI-powered analysis
674
  5. **Review the comprehensive report** with strengths, improvements, and recommendations
675
+ 6. **Download PDF version** for offline viewing and sharing
676
 
677
  ### πŸ”§ Features:
678
  - βœ… Automated performance analysis
679
  - βœ… AI-generated insights and recommendations
680
  - βœ… Visual performance charts
681
  - βœ… Professional report formatting
682
+ - βœ… **PDF download with embedded charts**
683
  - βœ… Customizable input parameters
684
+
685
+ ### πŸ“„ PDF Report Includes:
686
+ - Complete performance analysis with charts
687
+ - Professional formatting for printing
688
+ - All recommendations and insights
689
+ - Visual performance graphs
690
+ - Ready for sharing with parents/educators
691
  """)
692
 
693
  return app