EduTechTeam commited on
Commit
78d5d5c
·
verified ·
1 Parent(s): e7a39ef

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +150 -0
app.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ import gradio as gr
4
+ import os
5
+
6
+ def process_admissions(file_path, capacity=120):
7
+ """
8
+ Loads, filters, and processes student admission data based on defined rules.
9
+
10
+ Args:
11
+ file_path (str): The path to the CSV file containing the student data.
12
+ capacity (int): The maximum number of students to admit.
13
+
14
+ Returns:
15
+ tuple: A tuple containing:
16
+ - pd.DataFrame: A DataFrame containing all students with admission status ('正取' or '備取'),
17
+ or an empty DataFrame if an error occurred or no valid data.
18
+ - str: The file path to the saved CSV, or None if an error occurred or no valid data.
19
+ """
20
+ try:
21
+ df = pd.read_csv(file_path)
22
+ print("DataFrame loaded successfully.")
23
+
24
+ if df is not None:
25
+ # Filter out rows where any column contains '未填報-未填寫'
26
+ df_filtered = df[~(df == '未填報-未填寫').any(axis=1)].copy()
27
+ print(f"DataFrame after filtering: {len(df_filtered)} rows remaining.")
28
+
29
+ if df_filtered.empty:
30
+ print("No valid entries found after filtering.")
31
+ return pd.DataFrame(), None
32
+
33
+ # Shuffle the filtered DataFrame to ensure random selection within priority groups
34
+ df_shuffled = df_filtered.sample(frac=1, random_state=42).reset_index(drop=True)
35
+
36
+ admitted_students_list = []
37
+ remaining_df = df_shuffled.copy()
38
+
39
+ # Prioritize one person per institution, up to capacity
40
+ first_admissions_indices = remaining_df.groupby('機關名稱').head(1).index
41
+ num_first_admissions = min(len(first_admissions_indices), capacity)
42
+ admitted_students_list.append(remaining_df.loc[first_admissions_indices[:num_first_admissions]])
43
+ remaining_df = remaining_df.drop(first_admissions_indices[:num_first_admissions])
44
+
45
+ # Prioritize a second person per institution if capacity permits
46
+ current_admitted_count = sum(len(df) for df in admitted_students_list)
47
+ if current_admitted_count < capacity:
48
+ second_admissions_indices = remaining_df.groupby('機關名稱').head(1).index
49
+ additional_capacity = capacity - current_admitted_count
50
+ num_second_admissions = min(len(second_admissions_indices), additional_capacity)
51
+ admitted_students_list.append(remaining_df.loc[second_admissions_indices[:num_second_admissions]])
52
+ remaining_df = remaining_df.drop(second_admissions_indices[:num_second_admissions])
53
+
54
+ # Allow more if capacity permits, up to the total capacity
55
+ current_admitted_count = sum(len(df) for df in admitted_students_list)
56
+ if current_admitted_count < capacity:
57
+ additional_capacity = capacity - current_admitted_count
58
+ additional_admissions_indices = remaining_df.head(additional_capacity).index
59
+ admitted_students_list.append(remaining_df.loc[additional_admissions_indices])
60
+ remaining_df = remaining_df.drop(additional_admissions_indices)
61
+
62
+
63
+ # Combine all selected students and drop duplicates
64
+ admitted_df = pd.concat(admitted_students_list).drop_duplicates().reset_index(drop=True)
65
+
66
+ # Assign '正取' status and order
67
+ if not admitted_df.empty:
68
+ admitted_df['錄取順序'] = [f'正取{i+1}' for i in range(len(admitted_df))]
69
+
70
+ # Assign '備取' status to the remaining students
71
+ if not remaining_df.empty:
72
+ remaining_df['錄取順序'] = [f'備取{i+1}' for i in range(len(remaining_df))]
73
+ else:
74
+ remaining_df['錄取順序'] = [] # Ensure column exists even if empty
75
+
76
+
77
+ # Combine admitted and remaining students
78
+ final_df = pd.concat([admitted_df, remaining_df]).reset_index(drop=True)
79
+
80
+ print("Final Student List with Admission Status:")
81
+ display(final_df.head())
82
+ print("\nFinal Student List Info:")
83
+ display(final_df.info())
84
+
85
+
86
+ # Save the processed DataFrame to a temporary CSV file
87
+ output_csv_path = "admitted_students_processed.csv"
88
+ final_df.to_csv(output_csv_path, index=False, encoding='utf-8-sig')
89
+ print(f"Processed data saved to {output_csv_path}")
90
+
91
+ return final_df, output_csv_path
92
+
93
+ else:
94
+ print("DataFrame not loaded. Cannot perform processing.")
95
+ return pd.DataFrame(), None
96
+
97
+ except FileNotFoundError:
98
+ print(f"Error: '{file_path}' not found. Please ensure the file is in the correct directory.")
99
+ return pd.DataFrame(), None
100
+ except Exception as e:
101
+ print(f"An error occurred during processing: {e}")
102
+ return pd.DataFrame(), None
103
+
104
+ # Assuming process_admissions is defined and available in the environment
105
+ # It should return a tuple: (DataFrame, file_path)
106
+
107
+ def process_admissions_and_return_df_and_file(file_path, capacity):
108
+ """
109
+ Processes student admission data and returns the DataFrame and the path to the saved CSV.
110
+
111
+ Args:
112
+ file_path (str): The path to the uploaded CSV file.
113
+ capacity (int): The maximum number of students to admit.
114
+
115
+ Returns:
116
+ tuple: A tuple containing:
117
+ - pd.DataFrame: The processed DataFrame (including 正取 and 備取).
118
+ - str: The file path to the saved CSV, or None if processing failed.
119
+ """
120
+ final_df, output_csv_path = process_admissions(file_path, capacity) # Call process_admissions which returns final_df and path
121
+ return final_df, output_csv_path # Return final_df and path
122
+
123
+
124
+ if 'process_admissions' in locals():
125
+ # Define the Gradio interface
126
+ interface = gr.Interface(
127
+ fn=process_admissions_and_return_df_and_file,
128
+ inputs=[
129
+ gr.File(label="Upload CSV File"),
130
+ gr.Number(label="Admission Capacity", value=120, precision=0) # Add number input for capacity
131
+ ],
132
+ outputs=[
133
+ gr.Dataframe(label="Admitted Students List"), # Changed label to reflect it includes all students
134
+ gr.File(label="Download Admitted Students CSV")
135
+ ],
136
+ title="Student Admission Processing",
137
+ description="Upload a CSV file to process student admissions based on institutional priority and capacity, and get a list with admission order and a downloadable CSV."
138
+ )
139
+
140
+ print("Gradio interface designed with capacity input.")
141
+ else:
142
+ print("The 'process_admissions' function is not defined. Please ensure the data processing logic is defined in a previous step.")
143
+
144
+
145
+ if 'interface' in locals():
146
+ print("Launching Gradio interface...")
147
+ interface.launch()
148
+
149
+ else:
150
+ print("Gradio interface not found. Please ensure the previous steps were executed successfully.")