Rename main.py to app.py
Browse files- main.py → app.py +124 -124
main.py → app.py
RENAMED
|
@@ -1,124 +1,124 @@
|
|
| 1 |
-
from flask import Flask, jsonify, render_template, request
|
| 2 |
-
import pandas as pd
|
| 3 |
-
import re
|
| 4 |
-
from datetime import datetime, timedelta
|
| 5 |
-
|
| 6 |
-
app = Flask(__name__)
|
| 7 |
-
|
| 8 |
-
# 加载 Excel 数据
|
| 9 |
-
grade_files = {
|
| 10 |
-
"22级": r"
|
| 11 |
-
"23级": r"
|
| 12 |
-
"24级": r"
|
| 13 |
-
}
|
| 14 |
-
|
| 15 |
-
# 预加载所有年级数据
|
| 16 |
-
dataframes = {}
|
| 17 |
-
for grade, file_path in grade_files.items():
|
| 18 |
-
df = pd.read_excel(file_path)
|
| 19 |
-
df["grade"] = grade # 添加年级字段
|
| 20 |
-
dataframes[grade] = df
|
| 21 |
-
|
| 22 |
-
all_data = pd.concat(dataframes.values(), ignore_index=True)
|
| 23 |
-
|
| 24 |
-
# 第一周的开始日期
|
| 25 |
-
first_week_start_date = datetime(2024, 9, 2) # 第一周星期一的日期
|
| 26 |
-
|
| 27 |
-
# 周次解析函数
|
| 28 |
-
def parse_weeks(weeks_str):
|
| 29 |
-
if not weeks_str or pd.isna(weeks_str):
|
| 30 |
-
return set()
|
| 31 |
-
weeks = set()
|
| 32 |
-
for part in weeks_str.split(","):
|
| 33 |
-
try:
|
| 34 |
-
if "-" in part:
|
| 35 |
-
start, end = map(int, part.split("-"))
|
| 36 |
-
weeks.update(range(start, end + 1))
|
| 37 |
-
else:
|
| 38 |
-
weeks.add(int(part))
|
| 39 |
-
except ValueError:
|
| 40 |
-
print(f"跳过无效周次: {part}")
|
| 41 |
-
continue
|
| 42 |
-
return weeks
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
# 星期与节次解析函数
|
| 46 |
-
def parse_day_and_period(period_str):
|
| 47 |
-
if not period_str or pd.isna(period_str):
|
| 48 |
-
return None
|
| 49 |
-
try:
|
| 50 |
-
day_match = re.search(r"[一二三四五六日]", period_str)
|
| 51 |
-
period_match = re.search(r"\[(\d+)-(\d+)节\]", period_str)
|
| 52 |
-
|
| 53 |
-
if day_match and period_match:
|
| 54 |
-
day = "一二三四五六日".index(day_match.group()) + 1
|
| 55 |
-
start, end = map(int, period_match.groups())
|
| 56 |
-
periods = list(range(start, end + 1))
|
| 57 |
-
return day, periods
|
| 58 |
-
except Exception as e:
|
| 59 |
-
print(f"解析失败: {period_str}, 错误: {e}")
|
| 60 |
-
return None
|
| 61 |
-
|
| 62 |
-
# 根据周次和星期计算实际日期
|
| 63 |
-
def calculate_date(week, day):
|
| 64 |
-
days_from_start = (week - 1) * 7 + (day - 1) # 从第一周开始的天数差
|
| 65 |
-
return first_week_start_date + timedelta(days=days_from_start)
|
| 66 |
-
|
| 67 |
-
@app.route("/")
|
| 68 |
-
def index():
|
| 69 |
-
return render_template("index.html")
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
@app.route("/api/courses")
|
| 73 |
-
def get_courses():
|
| 74 |
-
week = request.args.get("week", 1)
|
| 75 |
-
grade = request.args.get("grade", None)
|
| 76 |
-
admin_class = request.args.get("admin_class", None)
|
| 77 |
-
|
| 78 |
-
# 筛选数据
|
| 79 |
-
filtered_data = all_data
|
| 80 |
-
if grade:
|
| 81 |
-
filtered_data = filtered_data[filtered_data["grade"] == grade]
|
| 82 |
-
if admin_class:
|
| 83 |
-
filtered_data = filtered_data[filtered_data["行政班级"].str.contains(admin_class, na=False)]
|
| 84 |
-
|
| 85 |
-
# 筛选课程类型:只要必修课
|
| 86 |
-
filtered_data = filtered_data[filtered_data["课程类别"].str.contains("必修课", na=False)]
|
| 87 |
-
|
| 88 |
-
if week:
|
| 89 |
-
week = int(week)
|
| 90 |
-
filtered_data = filtered_data[
|
| 91 |
-
filtered_data["周次"].apply(lambda x: week in parse_weeks(x) if pd.notna(x) else False)
|
| 92 |
-
]
|
| 93 |
-
|
| 94 |
-
# 解析课程信息
|
| 95 |
-
results = []
|
| 96 |
-
for _, row in filtered_data.iterrows():
|
| 97 |
-
day_and_period = parse_day_and_period(row["节次"])
|
| 98 |
-
if day_and_period:
|
| 99 |
-
day, periods = day_and_period
|
| 100 |
-
course_date = calculate_date(week, day) # 计算课程日期
|
| 101 |
-
results.append({
|
| 102 |
-
"课程": row["课程"],
|
| 103 |
-
"教师": row["教师"],
|
| 104 |
-
"地点": row["地点"],
|
| 105 |
-
"星期": day,
|
| 106 |
-
"日期": course_date.strftime("%Y-%m-%d"), # 格式化为字符串
|
| 107 |
-
"节次": periods,
|
| 108 |
-
"节次范围": f"第{periods[0]}-{periods[-1]}节",
|
| 109 |
-
"周次": row["周次"]
|
| 110 |
-
})
|
| 111 |
-
|
| 112 |
-
# 按星期和节次排序
|
| 113 |
-
results = sorted(results, key=lambda x: (x["星期"], x["节次"][0]))
|
| 114 |
-
return jsonify(results)
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
@app.route("/api/classes")
|
| 118 |
-
def get_classes():
|
| 119 |
-
classes = all_data["行政班级"].dropna().unique().tolist()
|
| 120 |
-
return jsonify(sorted(classes))
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
if __name__ == "__main__":
|
| 124 |
-
app.run(debug=True)
|
|
|
|
| 1 |
+
from flask import Flask, jsonify, render_template, request
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import re
|
| 4 |
+
from datetime import datetime, timedelta
|
| 5 |
+
|
| 6 |
+
app = Flask(__name__)
|
| 7 |
+
|
| 8 |
+
# 加载 Excel 数据
|
| 9 |
+
grade_files = {
|
| 10 |
+
"22级": r"数据表\22级.xlsx",
|
| 11 |
+
"23级": r"数据表\23级.xlsx",
|
| 12 |
+
"24级": r"数据表\24级.xlsx",
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
# 预加载所有年级数据
|
| 16 |
+
dataframes = {}
|
| 17 |
+
for grade, file_path in grade_files.items():
|
| 18 |
+
df = pd.read_excel(file_path)
|
| 19 |
+
df["grade"] = grade # 添加年级字段
|
| 20 |
+
dataframes[grade] = df
|
| 21 |
+
|
| 22 |
+
all_data = pd.concat(dataframes.values(), ignore_index=True)
|
| 23 |
+
|
| 24 |
+
# 第一周的开始日期
|
| 25 |
+
first_week_start_date = datetime(2024, 9, 2) # 第一周星期一的日期
|
| 26 |
+
|
| 27 |
+
# 周次解析函数
|
| 28 |
+
def parse_weeks(weeks_str):
|
| 29 |
+
if not weeks_str or pd.isna(weeks_str):
|
| 30 |
+
return set()
|
| 31 |
+
weeks = set()
|
| 32 |
+
for part in weeks_str.split(","):
|
| 33 |
+
try:
|
| 34 |
+
if "-" in part:
|
| 35 |
+
start, end = map(int, part.split("-"))
|
| 36 |
+
weeks.update(range(start, end + 1))
|
| 37 |
+
else:
|
| 38 |
+
weeks.add(int(part))
|
| 39 |
+
except ValueError:
|
| 40 |
+
print(f"跳过无效周次: {part}")
|
| 41 |
+
continue
|
| 42 |
+
return weeks
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
# 星期与节次解析函数
|
| 46 |
+
def parse_day_and_period(period_str):
|
| 47 |
+
if not period_str or pd.isna(period_str):
|
| 48 |
+
return None
|
| 49 |
+
try:
|
| 50 |
+
day_match = re.search(r"[一二三四五六日]", period_str)
|
| 51 |
+
period_match = re.search(r"\[(\d+)-(\d+)节\]", period_str)
|
| 52 |
+
|
| 53 |
+
if day_match and period_match:
|
| 54 |
+
day = "一二三四五六日".index(day_match.group()) + 1
|
| 55 |
+
start, end = map(int, period_match.groups())
|
| 56 |
+
periods = list(range(start, end + 1))
|
| 57 |
+
return day, periods
|
| 58 |
+
except Exception as e:
|
| 59 |
+
print(f"解析失败: {period_str}, 错误: {e}")
|
| 60 |
+
return None
|
| 61 |
+
|
| 62 |
+
# 根据周次和星期计算实际日期
|
| 63 |
+
def calculate_date(week, day):
|
| 64 |
+
days_from_start = (week - 1) * 7 + (day - 1) # 从第一周开始的天数差
|
| 65 |
+
return first_week_start_date + timedelta(days=days_from_start)
|
| 66 |
+
|
| 67 |
+
@app.route("/")
|
| 68 |
+
def index():
|
| 69 |
+
return render_template("index.html")
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
@app.route("/api/courses")
|
| 73 |
+
def get_courses():
|
| 74 |
+
week = request.args.get("week", 1)
|
| 75 |
+
grade = request.args.get("grade", None)
|
| 76 |
+
admin_class = request.args.get("admin_class", None)
|
| 77 |
+
|
| 78 |
+
# 筛选数据
|
| 79 |
+
filtered_data = all_data
|
| 80 |
+
if grade:
|
| 81 |
+
filtered_data = filtered_data[filtered_data["grade"] == grade]
|
| 82 |
+
if admin_class:
|
| 83 |
+
filtered_data = filtered_data[filtered_data["行政班级"].str.contains(admin_class, na=False)]
|
| 84 |
+
|
| 85 |
+
# 筛选课程类型:只要必修课
|
| 86 |
+
filtered_data = filtered_data[filtered_data["课程类别"].str.contains("必修课", na=False)]
|
| 87 |
+
|
| 88 |
+
if week:
|
| 89 |
+
week = int(week)
|
| 90 |
+
filtered_data = filtered_data[
|
| 91 |
+
filtered_data["周次"].apply(lambda x: week in parse_weeks(x) if pd.notna(x) else False)
|
| 92 |
+
]
|
| 93 |
+
|
| 94 |
+
# 解析课程信息
|
| 95 |
+
results = []
|
| 96 |
+
for _, row in filtered_data.iterrows():
|
| 97 |
+
day_and_period = parse_day_and_period(row["节次"])
|
| 98 |
+
if day_and_period:
|
| 99 |
+
day, periods = day_and_period
|
| 100 |
+
course_date = calculate_date(week, day) # 计算课程日期
|
| 101 |
+
results.append({
|
| 102 |
+
"课程": row["课程"],
|
| 103 |
+
"教师": row["教师"],
|
| 104 |
+
"地点": row["地点"],
|
| 105 |
+
"星期": day,
|
| 106 |
+
"日期": course_date.strftime("%Y-%m-%d"), # 格式化为字符串
|
| 107 |
+
"节次": periods,
|
| 108 |
+
"节次范围": f"第{periods[0]}-{periods[-1]}节",
|
| 109 |
+
"周次": row["周次"]
|
| 110 |
+
})
|
| 111 |
+
|
| 112 |
+
# 按星期和节次排序
|
| 113 |
+
results = sorted(results, key=lambda x: (x["星期"], x["节次"][0]))
|
| 114 |
+
return jsonify(results)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
@app.route("/api/classes")
|
| 118 |
+
def get_classes():
|
| 119 |
+
classes = all_data["行政班级"].dropna().unique().tolist()
|
| 120 |
+
return jsonify(sorted(classes))
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
if __name__ == "__main__":
|
| 124 |
+
app.run(debug=True)
|