Update app.py
Browse files
app.py
CHANGED
|
@@ -313,6 +313,62 @@ def plot_intervention_statistics(intervention_stats):
|
|
| 313 |
|
| 314 |
return fig
|
| 315 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
def compute_student_metrics(df):
|
| 317 |
# Filter DataFrame for sessions where intervention happened
|
| 318 |
intervention_df = df[df[INTERVENTION_COLUMN].str.strip().str.lower() == 'yes']
|
|
@@ -345,30 +401,57 @@ def compute_student_metrics(df):
|
|
| 345 |
attendance_pct = (sessions_attended / intervention_sessions_held) * 100 if intervention_sessions_held > 0 else 0
|
| 346 |
attendance_pct = round(attendance_pct) # Round to whole number
|
| 347 |
|
| 348 |
-
#
|
| 349 |
-
|
| 350 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 351 |
|
| 352 |
-
#
|
| 353 |
-
|
| 354 |
-
|
|
|
|
|
|
|
|
|
|
| 355 |
|
| 356 |
-
|
| 357 |
-
|
| 358 |
|
| 359 |
-
|
| 360 |
-
|
| 361 |
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
engagement_pct = round(engagement_pct) # Round to whole number
|
| 365 |
|
| 366 |
-
|
|
|
|
|
|
|
|
|
|
| 367 |
student_metrics[student_name] = {
|
| 368 |
'Attendance (%)': attendance_pct,
|
| 369 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
}
|
| 371 |
|
|
|
|
|
|
|
| 372 |
# Create a DataFrame from student_metrics
|
| 373 |
student_metrics_df = pd.DataFrame.from_dict(student_metrics, orient='index').reset_index()
|
| 374 |
student_metrics_df.rename(columns={'index': 'Student'}, inplace=True)
|
|
|
|
| 313 |
|
| 314 |
return fig
|
| 315 |
|
| 316 |
+
# def compute_student_metrics(df):
|
| 317 |
+
# # Filter DataFrame for sessions where intervention happened
|
| 318 |
+
# intervention_df = df[df[INTERVENTION_COLUMN].str.strip().str.lower() == 'yes']
|
| 319 |
+
# intervention_sessions_held = len(intervention_df)
|
| 320 |
+
|
| 321 |
+
# # Get list of student columns
|
| 322 |
+
# student_columns = [col for col in df.columns if col.startswith('Student Attendance')]
|
| 323 |
+
|
| 324 |
+
# student_metrics = {}
|
| 325 |
+
|
| 326 |
+
# for col in student_columns:
|
| 327 |
+
# student_name = col.replace('Student Attendance [', '').replace(']', '').strip()
|
| 328 |
+
# # Get the attendance data for the student
|
| 329 |
+
# student_data = intervention_df[[col]].copy()
|
| 330 |
+
|
| 331 |
+
# # Treat blank entries as 'Absent'
|
| 332 |
+
# student_data[col] = student_data[col].fillna('Absent')
|
| 333 |
+
|
| 334 |
+
# # Assign attendance values
|
| 335 |
+
# attendance_values = student_data[col].apply(lambda x: 1 if x in [
|
| 336 |
+
# ENGAGED_STR,
|
| 337 |
+
# PARTIALLY_ENGAGED_STR,
|
| 338 |
+
# NOT_ENGAGED_STR
|
| 339 |
+
# ] else 0)
|
| 340 |
+
|
| 341 |
+
# # Number of Sessions Attended
|
| 342 |
+
# sessions_attended = attendance_values.sum()
|
| 343 |
+
|
| 344 |
+
# # Attendance (%)
|
| 345 |
+
# attendance_pct = (sessions_attended / intervention_sessions_held) * 100 if intervention_sessions_held > 0 else 0
|
| 346 |
+
# attendance_pct = round(attendance_pct) # Round to whole number
|
| 347 |
+
|
| 348 |
+
# # For engagement calculation, include only sessions where attendance is not 'Absent'
|
| 349 |
+
# valid_engagement_indices = attendance_values[attendance_values == 1].index
|
| 350 |
+
# engagement_data = student_data.loc[valid_engagement_indices, col]
|
| 351 |
+
|
| 352 |
+
# # Assign engagement values
|
| 353 |
+
# engagement_values = engagement_data.apply(lambda x: 1 if x == ENGAGED_STR
|
| 354 |
+
# else 0.5 if x == PARTIALLY_ENGAGED_STR else 0)
|
| 355 |
+
|
| 356 |
+
# # Sum of Engagement Values
|
| 357 |
+
# sum_engagement_values = engagement_values.sum()
|
| 358 |
+
|
| 359 |
+
# # Number of Sessions Attended for engagement (should be same as sessions_attended)
|
| 360 |
+
# number_sessions_attended = len(valid_engagement_indices)
|
| 361 |
+
|
| 362 |
+
# # Engagement (%)
|
| 363 |
+
# engagement_pct = (sum_engagement_values / number_sessions_attended) * 100 if number_sessions_attended > 0 else 0
|
| 364 |
+
# engagement_pct = round(engagement_pct) # Round to whole number
|
| 365 |
+
|
| 366 |
+
# # Store metrics
|
| 367 |
+
# student_metrics[student_name] = {
|
| 368 |
+
# 'Attendance (%)': attendance_pct,
|
| 369 |
+
# 'Engagement (%)': engagement_pct
|
| 370 |
+
# }
|
| 371 |
+
|
| 372 |
def compute_student_metrics(df):
|
| 373 |
# Filter DataFrame for sessions where intervention happened
|
| 374 |
intervention_df = df[df[INTERVENTION_COLUMN].str.strip().str.lower() == 'yes']
|
|
|
|
| 401 |
attendance_pct = (sessions_attended / intervention_sessions_held) * 100 if intervention_sessions_held > 0 else 0
|
| 402 |
attendance_pct = round(attendance_pct) # Round to whole number
|
| 403 |
|
| 404 |
+
# Calculate the number of students in each engagement category
|
| 405 |
+
engagement_counts = {
|
| 406 |
+
'Engaged': 0,
|
| 407 |
+
'Partially Engaged': 0,
|
| 408 |
+
'Not Engaged': 0,
|
| 409 |
+
'Absent': 0
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
# Count the engagement states
|
| 413 |
+
for x in student_data[col]:
|
| 414 |
+
if x == ENGAGED_STR:
|
| 415 |
+
engagement_counts['Engaged'] += 1
|
| 416 |
+
elif x == PARTIALLY_ENGAGED_STR:
|
| 417 |
+
engagement_counts['Partially Engaged'] += 1
|
| 418 |
+
elif x == NOT_ENGAGED_STR:
|
| 419 |
+
engagement_counts['Not Engaged'] += 1
|
| 420 |
+
else:
|
| 421 |
+
engagement_counts['Absent'] += 1 # Count as Absent if not engaged
|
| 422 |
|
| 423 |
+
# Calculate percentages for engagement states
|
| 424 |
+
total_sessions = sum(engagement_counts.values())
|
| 425 |
+
|
| 426 |
+
# Engagement (%)
|
| 427 |
+
engagement_pct = (engagement_counts['Engaged'] / total_sessions * 100) if total_sessions > 0 else 0
|
| 428 |
+
engagement_pct = round(engagement_pct)
|
| 429 |
|
| 430 |
+
engaged_pct = (engagement_counts['Engaged'] / total_sessions * 100) if total_sessions > 0 else 0
|
| 431 |
+
engaged_pct = round(engaged_pct)
|
| 432 |
|
| 433 |
+
partially_engaged_pct = (engagement_counts['Partially Engaged'] / total_sessions * 100) if total_sessions > 0 else 0
|
| 434 |
+
partially_engaged_pct = round(partially_engaged_pct)
|
| 435 |
|
| 436 |
+
not_engaged_pct = (engagement_counts['Not Engaged'] / total_sessions * 100) if total_sessions > 0 else 0
|
| 437 |
+
not_engaged_pct = round(not_engaged_pct)
|
|
|
|
| 438 |
|
| 439 |
+
absent_pct = (engagement_counts['Absent'] / total_sessions * 100) if total_sessions > 0 else 0
|
| 440 |
+
absent_pct = round(absent_pct)
|
| 441 |
+
|
| 442 |
+
# Store metrics in the required order
|
| 443 |
student_metrics[student_name] = {
|
| 444 |
'Attendance (%)': attendance_pct,
|
| 445 |
+
'Attendance': sessions_attended, # Raw number of sessions attended
|
| 446 |
+
'Engagement (%)': engagement_pct,
|
| 447 |
+
'Engaged (%)': engaged_pct,
|
| 448 |
+
'Partially Engaged (%)': partially_engaged_pct,
|
| 449 |
+
'Not Engaged (%)': not_engaged_pct,
|
| 450 |
+
'Absent (%)': absent_pct
|
| 451 |
}
|
| 452 |
|
| 453 |
+
return student_metrics
|
| 454 |
+
|
| 455 |
# Create a DataFrame from student_metrics
|
| 456 |
student_metrics_df = pd.DataFrame.from_dict(student_metrics, orient='index').reset_index()
|
| 457 |
student_metrics_df.rename(columns={'index': 'Student'}, inplace=True)
|