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
|