Update app.py
Browse files
app.py
CHANGED
@@ -277,7 +277,7 @@ def compute_intervention_statistics(df):
|
|
277 |
|
278 |
# Intervention Frequency (%)
|
279 |
intervention_frequency = (sessions_held / total_days) * 100 if total_days > 0 else 0
|
280 |
-
intervention_frequency = round(intervention_frequency,
|
281 |
|
282 |
# Reorder columns as specified
|
283 |
stats = {
|
@@ -301,11 +301,14 @@ def plot_intervention_statistics(intervention_stats):
|
|
301 |
ax.bar(['Intervention Sessions'], [sessions_not_held], bottom=[sessions_held], label='Not Held', color='#91D6B8')
|
302 |
|
303 |
# Display values on the bars
|
304 |
-
ax.text(0, sessions_held / 2, str(sessions_held), ha='center', va='center', color='white'
|
305 |
-
|
|
|
|
|
306 |
|
307 |
# Update chart settings
|
308 |
ax.set_ylabel('Frequency')
|
|
|
309 |
# Reverse the legend order to match the new stacking order
|
310 |
handles, labels = ax.get_legend_handles_labels()
|
311 |
ax.legend(handles[::-1], labels[::-1])
|
@@ -313,62 +316,6 @@ 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']
|
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']
|
@@ -442,7 +389,7 @@ def compute_student_metrics(df):
|
|
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,
|
@@ -450,12 +397,22 @@ def compute_student_metrics(df):
|
|
450 |
'Absent (%)': absent_pct
|
451 |
}
|
452 |
|
453 |
-
|
|
|
|
|
|
|
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)
|
458 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
459 |
|
460 |
def plot_student_metrics(student_metrics_df):
|
461 |
# Create the figure and axis
|
@@ -463,6 +420,7 @@ def plot_student_metrics(student_metrics_df):
|
|
463 |
|
464 |
# Width for the bars
|
465 |
bar_width = 0.35 # Width of the bars
|
|
|
466 |
index = range(len(student_metrics_df)) # Index for each student
|
467 |
|
468 |
# Plot Attendance and Engagement bars side by side
|
@@ -494,6 +452,9 @@ def plot_student_metrics(student_metrics_df):
|
|
494 |
ax.legend(loc='upper right', bbox_to_anchor=(1.25, 1), borderaxespad=0.)
|
495 |
ax.set_xticks(index) # Set x-ticks to the index
|
496 |
ax.set_xticklabels(student_metrics_df['Student'], rotation=0, ha='right') # Set student names as x-tick labels
|
|
|
|
|
|
|
497 |
|
498 |
# Display the plot
|
499 |
plt.tight_layout() # Adjust layout to fit elements
|
|
|
277 |
|
278 |
# Intervention Frequency (%)
|
279 |
intervention_frequency = (sessions_held / total_days) * 100 if total_days > 0 else 0
|
280 |
+
intervention_frequency = round(intervention_frequency, 0)
|
281 |
|
282 |
# Reorder columns as specified
|
283 |
stats = {
|
|
|
301 |
ax.bar(['Intervention Sessions'], [sessions_not_held], bottom=[sessions_held], label='Not Held', color='#91D6B8')
|
302 |
|
303 |
# Display values on the bars
|
304 |
+
ax.text(0, sessions_held / 2, str(sessions_held), ha='center', va='center', color='white',
|
305 |
+
fontweight='bold', fontsize=14)
|
306 |
+
ax.text(0, sessions_held + sessions_not_held / 2, str(sessions_not_held), ha='center', va='center', color='black',
|
307 |
+
fontweight='bold', fontsize=14)
|
308 |
|
309 |
# Update chart settings
|
310 |
ax.set_ylabel('Frequency')
|
311 |
+
ax.set_title('Intervention Sessions Held vs Not Held', fontsize=16) # Optional: Increased title font size
|
312 |
# Reverse the legend order to match the new stacking order
|
313 |
handles, labels = ax.get_legend_handles_labels()
|
314 |
ax.legend(handles[::-1], labels[::-1])
|
|
|
316 |
|
317 |
return fig
|
318 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
def compute_student_metrics(df):
|
320 |
# Filter DataFrame for sessions where intervention happened
|
321 |
intervention_df = df[df[INTERVENTION_COLUMN].str.strip().str.lower() == 'yes']
|
|
|
389 |
# Store metrics in the required order
|
390 |
student_metrics[student_name] = {
|
391 |
'Attendance (%)': attendance_pct,
|
392 |
+
'Attendance #': sessions_attended, # Raw number of sessions attended
|
393 |
'Engagement (%)': engagement_pct,
|
394 |
'Engaged (%)': engaged_pct,
|
395 |
'Partially Engaged (%)': partially_engaged_pct,
|
|
|
397 |
'Absent (%)': absent_pct
|
398 |
}
|
399 |
|
400 |
+
# # Create a DataFrame from student_metrics
|
401 |
+
# student_metrics_df = pd.DataFrame.from_dict(student_metrics, orient='index').reset_index()
|
402 |
+
# student_metrics_df.rename(columns={'index': 'Student'}, inplace=True)
|
403 |
+
# return student_metrics_df
|
404 |
|
405 |
# Create a DataFrame from student_metrics
|
406 |
student_metrics_df = pd.DataFrame.from_dict(student_metrics, orient='index').reset_index()
|
407 |
student_metrics_df.rename(columns={'index': 'Student'}, inplace=True)
|
408 |
+
|
409 |
+
# Use Pandas styler to bold specific columns and then export to HTML
|
410 |
+
styled_df = student_metrics_df.style \
|
411 |
+
.set_properties(**{'font-weight': 'bold'}, subset=pd.IndexSlice[:, ['Student', 'Attendance (%)', 'Engagement (%)']]) \
|
412 |
+
.set_table_styles([{'selector': 'th.colheading', 'props': [('font-weight', 'bold')]}], overwrite=False)
|
413 |
+
|
414 |
+
# Return the styled DataFrame as an HTML string
|
415 |
+
return styled_df.to_html()
|
416 |
|
417 |
def plot_student_metrics(student_metrics_df):
|
418 |
# Create the figure and axis
|
|
|
420 |
|
421 |
# Width for the bars
|
422 |
bar_width = 0.35 # Width of the bars
|
423 |
+
|
424 |
index = range(len(student_metrics_df)) # Index for each student
|
425 |
|
426 |
# Plot Attendance and Engagement bars side by side
|
|
|
452 |
ax.legend(loc='upper right', bbox_to_anchor=(1.25, 1), borderaxespad=0.)
|
453 |
ax.set_xticks(index) # Set x-ticks to the index
|
454 |
ax.set_xticklabels(student_metrics_df['Student'], rotation=0, ha='right') # Set student names as x-tick labels
|
455 |
+
# Set the y-axis limits and tick locations
|
456 |
+
ax.set_ylim(0, 100) # Range from 0 to 100
|
457 |
+
ax.yaxis.set_ticks(range(0, 101, 10)) # Increments of 10
|
458 |
|
459 |
# Display the plot
|
460 |
plt.tight_layout() # Adjust layout to fit elements
|