Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
851 lines
34 KiB
Python
851 lines
34 KiB
Python
"""
|
|
赋分引擎:将原始题目回答按赋分规则转换为分数
|
|
基于赋分整理表的规则,实现各类赋分函数
|
|
"""
|
|
import pandas as pd
|
|
import numpy as np
|
|
from typing import Dict, List, Optional, Tuple
|
|
import logging
|
|
import re
|
|
|
|
from ..config import DIMENSION_FRAMEWORK, SUBJECTS
|
|
from .data_engine import DataEngine
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ScoringEngine:
|
|
"""
|
|
赋分引擎
|
|
|
|
赋分逻辑基于"高中课程实施监测指标、题目、赋分整理0127.xlsx"
|
|
核心策略:按维度分组,从原始数据中提取相关字段,按规则赋分,
|
|
然后将赋分结果交给统计引擎做PCA合成
|
|
"""
|
|
|
|
def __init__(self, data_engine: DataEngine):
|
|
self.data_engine = data_engine
|
|
|
|
def score_all_schools(self) -> Dict[str, Dict[str, List[float]]]:
|
|
"""
|
|
对所有学校的所有维度进行赋分
|
|
|
|
返回: {
|
|
school_name: {
|
|
sub_dimension_name: [score1, score2, ...]
|
|
}
|
|
}
|
|
"""
|
|
result = {}
|
|
for school in self.data_engine.schools:
|
|
logger.info(f"正在对 {school} 进行赋分...")
|
|
result[school] = self._score_school(school)
|
|
return result
|
|
|
|
def _score_school(self, school: str) -> Dict[str, List[float]]:
|
|
"""对单个学校进行全维度赋分"""
|
|
scores = {}
|
|
|
|
# 课程领导力
|
|
scores["国家标准遵循"] = self._score_national_standard(school)
|
|
scores["课程结构建设"] = self._score_course_structure(school)
|
|
scores["课程规范落实"] = self._score_course_norms(school)
|
|
|
|
# 教学变革力
|
|
scores["教学方式变革"] = self._score_teaching_reform(school)
|
|
scores["作业设计与管理变革"] = self._score_homework_reform(school)
|
|
|
|
# 学生发展指导力
|
|
scores["学科发展的个性化辅导"] = self._score_personalized_tutoring(school)
|
|
scores["学生生涯发展指导"] = self._score_career_guidance(school)
|
|
|
|
# 教师发展支持力
|
|
scores["培训支持"] = self._score_training_support(school)
|
|
scores["教研支持"] = self._score_research_support(school)
|
|
scores["项目支持"] = self._score_project_support(school)
|
|
|
|
# 教育质量评估力
|
|
scores["科学评价观"] = self._score_scientific_evaluation(school)
|
|
scores["学业质量评估"] = self._score_academic_evaluation(school)
|
|
scores["综合素质评估"] = self._score_comprehensive_evaluation(school)
|
|
scores["实践活动评估"] = self._score_practice_evaluation(school)
|
|
|
|
# 教育条件保障力
|
|
scores["区域推进"] = self._score_regional_promotion(school)
|
|
scores["环境支持"] = self._score_environment_support(school)
|
|
scores["资源支持"] = self._score_resource_support(school)
|
|
|
|
# 数字化赋能力
|
|
scores["教学方式创新"] = self._score_digital_teaching(school)
|
|
scores["评价精准化与个性化"] = self._score_digital_evaluation(school)
|
|
scores["课程迭代优化"] = self._score_digital_curriculum(school)
|
|
|
|
return scores
|
|
|
|
# ========== 课程领导力 ==========
|
|
|
|
def _score_national_standard(self, school: str) -> List[float]:
|
|
"""
|
|
国家标准遵循:开足开齐国家课程
|
|
赋分:必修课程学分低于标准=0,高于标准=1,与标准一致=2
|
|
选必/选修课程:低于标准=0,达到标准=1
|
|
"""
|
|
scores = []
|
|
hours_df = self.data_engine.get_weekly_hours(school)
|
|
if len(hours_df) == 0:
|
|
return [1.0] # 默认中等
|
|
|
|
# 按课程类型汇总
|
|
for course_type, field_name in [
|
|
("必修", "学科必修课周课时"),
|
|
("选必", "学科选择性必修课周课时"),
|
|
("选修", "学科类选修课周课时"),
|
|
]:
|
|
type_df = hours_df[hours_df["字段名称"] == field_name]
|
|
if len(type_df) == 0:
|
|
scores.append(0.5)
|
|
continue
|
|
|
|
# 按学科汇总总课时
|
|
total = type_df.groupby("学科")["字段取值"].sum()
|
|
has_courses = (total > 0).sum()
|
|
total_hours = total.sum()
|
|
|
|
if course_type == "必修":
|
|
# 必修课:与标准一致=2,高于=1,低于=0
|
|
# 简化处理:有多少学科开了课
|
|
exam_subjects = ["语文", "数学", "英语", "物理", "化学", "生物学",
|
|
"历史", "地理", "思想政治"]
|
|
opened = sum(1 for s in exam_subjects if s in total.index and total.get(s, 0) > 0)
|
|
if opened >= len(exam_subjects):
|
|
scores.append(2.0)
|
|
elif opened >= 6:
|
|
scores.append(1.0)
|
|
else:
|
|
scores.append(0.0)
|
|
else:
|
|
# 选必/选修:达到标准=1,低于=0
|
|
if total_hours > 0:
|
|
scores.append(1.0)
|
|
else:
|
|
scores.append(0.0)
|
|
|
|
return scores if scores else [1.0]
|
|
|
|
def _score_course_structure(self, school: str) -> List[float]:
|
|
"""
|
|
课程结构建设:学科类课程结构、校本特色课程结构、综合实践活动与劳动
|
|
赋分:按照离差百分比和填报数值
|
|
"""
|
|
scores = []
|
|
hours_df = self.data_engine.get_weekly_hours(school)
|
|
|
|
if len(hours_df) > 0:
|
|
# 1. 学科类课程结构:各学科三类课程的离差
|
|
by_subject = hours_df.groupby(["学科", "字段名称"])["字段取值"].sum().unstack(fill_value=0)
|
|
if len(by_subject) > 0:
|
|
total_per_subject = by_subject.sum(axis=1)
|
|
overall_total = total_per_subject.sum()
|
|
if overall_total > 0:
|
|
proportions = total_per_subject / overall_total
|
|
mean_prop = proportions.mean()
|
|
deviation = np.abs(proportions - mean_prop).sum()
|
|
# 离差越小越好,标准化到0-3分
|
|
structure_score = max(0, 3 - deviation * 10)
|
|
scores.append(structure_score)
|
|
else:
|
|
scores.append(1.0)
|
|
else:
|
|
scores.append(1.0)
|
|
|
|
# 2. 校本特色课程:跨学科选修课门数、综合主题选修课门数
|
|
course_df = self.data_engine.get_school_course_data(school)
|
|
for field in ["跨学科选修课门数", "综合主题选修课门数", "综合实践选修课门数"]:
|
|
vals = course_df[course_df["字段名称"] == field]["字段取值"]
|
|
if len(vals) > 0:
|
|
try:
|
|
v = float(vals.iloc[0])
|
|
scores.append(min(v / 5, 3.0)) # 归一化
|
|
except (ValueError, TypeError):
|
|
scores.append(0.5)
|
|
|
|
# 3. 综合实践活动与劳动
|
|
for field in ["三年应完成的研究性学习数量", "三年社会考察个数", "三年志愿服务时长"]:
|
|
vals = course_df[course_df["字段名称"] == field]["字段取值"]
|
|
if len(vals) > 0:
|
|
try:
|
|
v = float(vals.iloc[0])
|
|
scores.append(min(v / 10, 3.0))
|
|
except (ValueError, TypeError):
|
|
scores.append(0.5)
|
|
|
|
return scores if scores else [1.0]
|
|
|
|
def _score_course_norms(self, school: str) -> List[float]:
|
|
"""
|
|
课程规范落实:建设规范文本 + 档案规范
|
|
赋分:有=2,无=0
|
|
"""
|
|
scores = []
|
|
norms = self.data_engine.get_course_norms(school)
|
|
|
|
norm_score = 0
|
|
archive_score = 0
|
|
norm_count = 0
|
|
archive_count = 0
|
|
|
|
for n in norms:
|
|
name = str(n.get("字段名称", ""))
|
|
val = str(n.get("字段取值", ""))
|
|
|
|
if "建设规范文本" in name:
|
|
norm_count += 1
|
|
if val and val not in ["0", "nan", "None", ""]:
|
|
norm_score += 2
|
|
elif "档案" in name:
|
|
archive_count += 1
|
|
if "已经建成并使用" in name and val == "1":
|
|
archive_score += 2
|
|
elif "已经建成" in name and val == "1":
|
|
archive_score += 1
|
|
|
|
if norm_count > 0:
|
|
scores.append(norm_score / norm_count * 2)
|
|
if archive_count > 0:
|
|
scores.append(archive_score / archive_count * 2)
|
|
|
|
return scores if scores else [1.0]
|
|
|
|
# ========== 教学变革力 ==========
|
|
|
|
def _score_teaching_reform(self, school: str) -> List[float]:
|
|
"""
|
|
教学方式变革:认识程度 + 落实程度 + 实施方式
|
|
赋分:量表题4/3/2/1分;多选每项1分加总
|
|
"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
sub_scores = []
|
|
|
|
# 认识程度类题目
|
|
for keyword in ["认识程度", "认识"]:
|
|
rows = sub_df[sub_df["字段名称"].str.contains(keyword, na=False)]
|
|
for _, row in rows.iterrows():
|
|
s = self._score_likert(row["字段取值"], reverse=False)
|
|
if s is not None:
|
|
sub_scores.append(s)
|
|
|
|
# 落实程度类题目
|
|
for keyword in ["落实程度", "落实"]:
|
|
rows = sub_df[sub_df["字段名称"].str.contains(keyword, na=False)]
|
|
for _, row in rows.iterrows():
|
|
s = self._score_likert(row["字段取值"], reverse=False)
|
|
if s is not None:
|
|
sub_scores.append(s)
|
|
|
|
# 实施方式(多选,体现形式类)
|
|
form_rows = sub_df[sub_df["字段名称"].str.contains("体现形式", na=False)]
|
|
if len(form_rows) > 0:
|
|
form_count = (form_rows["字段取值"].astype(str) == "1").sum()
|
|
sub_scores.append(min(form_count, 6))
|
|
|
|
if sub_scores:
|
|
scores.append(np.mean(sub_scores))
|
|
|
|
return scores if scores else [2.0]
|
|
|
|
def _score_homework_reform(self, school: str) -> List[float]:
|
|
"""
|
|
作业设计与管理变革:作业设计 + 作业管理
|
|
"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
sub_scores = []
|
|
|
|
# 作业设计:实践类/表现类/跨学科/团队合作作业是否布置
|
|
for hw_type in ["实践类作业_有布置", "表现类作业_有布置", "跨学科作业_有布置", "团队合作类作业_有布置"]:
|
|
rows = sub_df[sub_df["字段名称"] == hw_type]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
sub_scores.append(1.0)
|
|
else:
|
|
sub_scores.append(0.0)
|
|
|
|
# 作业属性标注(多选)
|
|
attr_rows = sub_df[sub_df["字段名称"].str.contains("作业属性标注", na=False)]
|
|
if len(attr_rows) > 0:
|
|
attr_count = (attr_rows["字段取值"].astype(str) == "1").sum()
|
|
sub_scores.append(min(attr_count, 5))
|
|
|
|
# 作业管理:时长控制、批改、评价
|
|
for field, score_map in [
|
|
("回家作业时长控制_学校控制", 3),
|
|
("回家作业时长控制_教研组负责", 2),
|
|
("作业批改范围_全部批改", 3),
|
|
("作业批改范围_部分练习", 1),
|
|
]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
sub_scores.append(score_map)
|
|
|
|
if sub_scores:
|
|
scores.append(np.mean(sub_scores))
|
|
|
|
return scores if scores else [1.5]
|
|
|
|
# ========== 学生发展指导力 ==========
|
|
|
|
def _score_personalized_tutoring(self, school: str) -> List[float]:
|
|
"""个性化辅导"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
|
|
# 辅导时长
|
|
for field, val in [
|
|
("个别辅导时长_每周>2h", 4),
|
|
("个别辅导时长_每周1~2h", 3),
|
|
("个别辅导时长_每周<1h", 2),
|
|
("个别辅导时长_几乎无", 1),
|
|
]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 辅导方式
|
|
for field, val in [
|
|
("个别辅导实施方式_分散辅导", 3),
|
|
("个别辅导实施方式_分组统一辅导", 2),
|
|
("个别辅导实施方式_班级统一辅导", 1),
|
|
]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
return scores if scores else [2.0]
|
|
|
|
def _score_career_guidance(self, school: str) -> List[float]:
|
|
"""生涯发展指导"""
|
|
scores = []
|
|
course_df = self.data_engine.get_school_course_data(school)
|
|
|
|
# 生涯指导实施方式
|
|
for field, val in [
|
|
("生涯指导实施方式_专设课程", 3),
|
|
("生涯指导实施方式_社会考察和志愿服务", 2),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
|
|
# 覆盖率
|
|
rows = course_df[course_df["字段名称"] == "完成生涯指导的学生占比_90%+"]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(4)
|
|
else:
|
|
scores.append(2)
|
|
|
|
# 教师构成
|
|
for field, val in [
|
|
("生涯指导教师构成_本校和外聘结合", 4),
|
|
("生涯指导教师构成_本校为主", 3),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 资源支持
|
|
for resource in ["生涯指导的校外资源支持程度", "生涯指导的校内资源支持程度"]:
|
|
rows = course_df[course_df["字段名称"] == resource]
|
|
if len(rows) > 0:
|
|
s = self._score_resource_level(rows.iloc[0]["字段取值"])
|
|
if s is not None:
|
|
scores.append(s)
|
|
|
|
return scores if scores else [2.0]
|
|
|
|
# ========== 教师发展支持力 ==========
|
|
|
|
def _score_training_support(self, school: str) -> List[float]:
|
|
"""培训支持"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
|
|
# 提供外校培训的教师人数
|
|
rows = sub_df[sub_df["字段名称"] == "提供外校培训的教师人数"]
|
|
if len(rows) > 0:
|
|
try:
|
|
v = float(rows.iloc[0]["字段取值"])
|
|
scores.append(min(v, 5))
|
|
except (ValueError, TypeError):
|
|
pass
|
|
|
|
# 区域培训指导人数
|
|
rows = sub_df[sub_df["字段名称"] == "区域培训指导人数"]
|
|
if len(rows) > 0:
|
|
try:
|
|
v = float(rows.iloc[0]["字段取值"])
|
|
scores.append(min(v, 5))
|
|
except (ValueError, TypeError):
|
|
pass
|
|
|
|
return scores if scores else [1.0]
|
|
|
|
def _score_research_support(self, school: str) -> List[float]:
|
|
"""教研支持"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
|
|
# 教研活动次数
|
|
rows = sub_df[sub_df["字段名称"] == "学科教研组每学期活动次数"]
|
|
if len(rows) > 0:
|
|
try:
|
|
v = float(rows.iloc[0]["字段取值"])
|
|
scores.append(min(v / 3, 4)) # 归一化
|
|
except (ValueError, TypeError):
|
|
pass
|
|
|
|
# 教研活动时长
|
|
rows = sub_df[sub_df["字段名称"] == "学科教研组平均每次活动时长"]
|
|
if len(rows) > 0:
|
|
try:
|
|
v = float(rows.iloc[0]["字段取值"])
|
|
scores.append(min(v / 30, 4)) # 30分钟为基准
|
|
except (ValueError, TypeError):
|
|
pass
|
|
|
|
# 教研计划
|
|
rows = sub_df[sub_df["字段名称"] == "学科教研工作计划_有"]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(2)
|
|
|
|
# 校级展示
|
|
for field in ["学科教研组校级展示_有", "学科教研组区域展示_有", "学科教研组成果发表_有"]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(2)
|
|
|
|
return scores if scores else [1.0]
|
|
|
|
def _score_project_support(self, school: str) -> List[float]:
|
|
"""项目支持"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
course_df = self.data_engine.get_school_course_data(school)
|
|
|
|
# 学科层面的项目
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
for field in ["学科承担的市级教改项目个数", "学科承担的区级教改项目个数", "学科承担的校级教改项目个数"]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0:
|
|
try:
|
|
v = float(rows.iloc[0]["字段取值"])
|
|
scores.append(min(v, 5))
|
|
except (ValueError, TypeError):
|
|
pass
|
|
|
|
# 学校层面的项目
|
|
for field in ["学校负责的市级教改项目个数", "学校参与的市级教改项目个数",
|
|
"学校负责的区级教改项目个数", "学校参与的区级教改项目个数",
|
|
"校级教改项目个数"]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0:
|
|
try:
|
|
v = float(rows.iloc[0]["字段取值"])
|
|
scores.append(min(v, 5))
|
|
except (ValueError, TypeError):
|
|
pass
|
|
|
|
return scores if scores else [0.5]
|
|
|
|
# ========== 教育质量评估力 ==========
|
|
|
|
def _score_scientific_evaluation(self, school: str) -> List[float]:
|
|
"""科学评价观"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
|
|
# 作业评价关注点(多选,关注素养发展的项目越多越好)
|
|
eval_items = sub_df[sub_df["字段名称"].str.contains("作业评价关注点|课堂表现评价关注点|学科实践活动评价关注点", na=False)]
|
|
if len(eval_items) > 0:
|
|
focus_count = (eval_items["字段取值"].astype(str) == "1").sum()
|
|
scores.append(min(focus_count / 3, 4))
|
|
|
|
return scores if scores else [2.0]
|
|
|
|
def _score_academic_evaluation(self, school: str) -> List[float]:
|
|
"""学业质量评估"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
|
|
# 评价工具建成
|
|
for field, val in [
|
|
("作业评价工具_已经建成并使用", 2),
|
|
("课堂表现评价工具_已经建成并使用", 2),
|
|
("作业评价工具_已经建成尚未使用", 1),
|
|
("作业评价工具_尚未建成和使用", 0),
|
|
]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 考试分析
|
|
for field, val in [
|
|
("学期考试分析_执行分析并存档", 3),
|
|
("学期考试分析_执行分析,不要求存档", 2),
|
|
("学期考试分析_教师自己决定", 1),
|
|
]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 表现性评价应用
|
|
for field, val in [
|
|
("表现性评价应用程度_经常", 4),
|
|
("表现性评价应用程度_有时", 3),
|
|
("表现性评价应用程度_总是", 4),
|
|
("表现性评价应用程度_从不", 1),
|
|
]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
return scores if scores else [2.0]
|
|
|
|
def _score_comprehensive_evaluation(self, school: str) -> List[float]:
|
|
"""综合素质评估"""
|
|
scores = []
|
|
course_df = self.data_engine.get_school_course_data(school)
|
|
|
|
# 综评评价体系
|
|
for field, val in [
|
|
("综评评价体系_已经建成并使用", 3),
|
|
("综评评价体系_已经建成尚未使用", 2),
|
|
("综评评价体系_未建成", 1),
|
|
("综评评价体系_不准备建设", 0),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 综评信息化
|
|
for field, val in [
|
|
("综评信息化实现_自建平台支持", 2),
|
|
("综评信息化实现_借助第三方平台支持", 1),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 综评结果使用(多选)
|
|
result_uses = course_df[course_df["字段名称"].str.contains("综评结果使用|综评应用", na=False)]
|
|
if len(result_uses) > 0:
|
|
use_count = (result_uses["字段取值"].astype(str) == "1").sum()
|
|
scores.append(min(use_count, 6))
|
|
|
|
return scores if scores else [1.0]
|
|
|
|
def _score_practice_evaluation(self, school: str) -> List[float]:
|
|
"""实践活动评估"""
|
|
scores = []
|
|
course_df = self.data_engine.get_school_course_data(school)
|
|
|
|
# 研究性学习评价
|
|
for field, val in [
|
|
("研究性学习评价工具_已经建成并使用", 2),
|
|
("研究性学习评价工具_尚未建成和使用", 0),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 社会考察评价
|
|
for field, val in [
|
|
("社会考察评价工具_已经建成并使用", 2),
|
|
("社会考察评价工具_尚未建成和使用", 0),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 学科实践活动评价
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
for subject in SUBJECTS[:5]: # 抽样几个学科
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
for field, val in [
|
|
("学科实践活动工具_已经建成并使用", 2),
|
|
("学科实践活动工具_已经建成尚未使用", 1),
|
|
("学科实践活动工具_尚未建成和使用", 0),
|
|
]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
return scores if scores else [1.0]
|
|
|
|
# ========== 教育条件保障力 ==========
|
|
|
|
def _score_regional_promotion(self, school: str) -> List[float]:
|
|
"""区域推进"""
|
|
scores = []
|
|
course_df = self.data_engine.get_school_course_data(school)
|
|
|
|
# 工作会频率
|
|
for field, val in [
|
|
("区域工作会参与_一月4次以上", 7),
|
|
("区域工作会参与_一月1次", 5),
|
|
("区域工作会参与_二月1次", 3),
|
|
("区域工作会参与_三月1次", 1),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 区域推进措施(多选)
|
|
measures = course_df[course_df["字段名称"].str.contains("区域推进措施", na=False)]
|
|
if len(measures) > 0:
|
|
measure_count = (measures["字段取值"].astype(str) == "1").sum()
|
|
scores.append(min(measure_count, 5))
|
|
|
|
return scores if scores else [2.0]
|
|
|
|
def _score_environment_support(self, school: str) -> List[float]:
|
|
"""环境支持:硬件+信息化"""
|
|
scores = []
|
|
course_df = self.data_engine.get_school_course_data(school)
|
|
|
|
# 场馆供给
|
|
for field, val in [
|
|
("场馆供给_能满足需要", 3),
|
|
("场馆供给_基本满足需要", 2),
|
|
("场馆供给_难以满足需要", 1),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 专用教室供给
|
|
for field, val in [
|
|
("专用教室供给_能满足需要", 3),
|
|
("专用教室供给_基本满足需要", 2),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 信息化平台功能(多选)
|
|
info_funcs = course_df[course_df["字段名称"].str.contains("信息化平台功能", na=False)]
|
|
if len(info_funcs) > 0:
|
|
func_count = (info_funcs["字段取值"].astype(str) == "1").sum()
|
|
scores.append(min(func_count / 3, 5))
|
|
|
|
return scores if scores else [2.0]
|
|
|
|
def _score_resource_support(self, school: str) -> List[float]:
|
|
"""资源支持:校内资源 + 校外资源 + 师资配置"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
|
|
# 校内资源支持程度
|
|
for field in ["必修课校内资源支持程度", "选择性必修课校内资源支持程度"]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0:
|
|
s = self._score_resource_level(rows.iloc[0]["字段取值"])
|
|
if s is not None:
|
|
scores.append(s)
|
|
|
|
# 校外资源支持程度
|
|
for field in ["必修课校外资源支持程度", "选择性必修课校外资源支持程度"]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0:
|
|
s = self._score_resource_level(rows.iloc[0]["字段取值"])
|
|
if s is not None:
|
|
scores.append(s)
|
|
|
|
# 师资:教研组总人数、高级教师比例等
|
|
rows = sub_df[sub_df["字段名称"] == "学科教研组总人数"]
|
|
if len(rows) > 0:
|
|
try:
|
|
total = float(rows.iloc[0]["字段取值"])
|
|
scores.append(min(total / 3, 4))
|
|
except (ValueError, TypeError):
|
|
pass
|
|
|
|
return scores if scores else [2.0]
|
|
|
|
# ========== 数字化赋能力 ==========
|
|
|
|
def _score_digital_teaching(self, school: str) -> List[float]:
|
|
"""教学方式创新"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
|
|
# 信息技术融合认识
|
|
for field in ["信息技术与教学融合的认识_所有人可做到"]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(4)
|
|
break
|
|
else:
|
|
rows = sub_df[sub_df["字段名称"] == "信息技术与教学融合的认识_个别人可做到"]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(1)
|
|
|
|
# 信息化终端使用比例
|
|
for field, val in [
|
|
("信息化终端使用比例_80%+", 4),
|
|
("信息化终端使用比例_60~79%", 3),
|
|
("信息化终端使用比例_30~59%", 2),
|
|
("信息化终端使用比例_30%-", 1),
|
|
]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
return scores if scores else [2.0]
|
|
|
|
def _score_digital_evaluation(self, school: str) -> List[float]:
|
|
"""评价精准化与个性化"""
|
|
scores = []
|
|
subject_df = self.data_engine.get_school_subject_data(school)
|
|
course_df = self.data_engine.get_school_course_data(school)
|
|
|
|
# 学业评价信息化
|
|
for subject in SUBJECTS:
|
|
sub_df = subject_df[subject_df["学科"] == subject]
|
|
for field, val in [
|
|
("学业评价信息化实现_自建平台支持", 3),
|
|
("学业评价信息化实现_借助第三方平台支持", 2),
|
|
("学业评价信息化实现_没有平台支持", 0),
|
|
]:
|
|
rows = sub_df[sub_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 学校层面的信息化支持
|
|
for field, val in [
|
|
("学校信息系统对选课支持程度", None),
|
|
("学校信息系统对排课支持程度", None),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0:
|
|
s = self._score_resource_level(rows.iloc[0]["字段取值"])
|
|
if s is not None:
|
|
scores.append(s)
|
|
|
|
return scores if scores else [1.5]
|
|
|
|
def _score_digital_curriculum(self, school: str) -> List[float]:
|
|
"""课程迭代优化"""
|
|
scores = []
|
|
course_df = self.data_engine.get_school_course_data(school)
|
|
|
|
# 数据连通
|
|
for field, val in [
|
|
("数据连通_有数据能互通", 3),
|
|
("数据连通_有数据不互通", 1),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
break
|
|
|
|
# 管理业务信息化
|
|
for field, val in [
|
|
("管理业务的信息化应用_绝大部分", 4),
|
|
("教学业务的信息化应用_绝大部分", 4),
|
|
]:
|
|
rows = course_df[course_df["字段名称"] == field]
|
|
if len(rows) > 0 and str(rows.iloc[0]["字段取值"]) == "1":
|
|
scores.append(val)
|
|
|
|
# 已完成网络课程数
|
|
rows = course_df[course_df["字段名称"] == "已完成的网络课程门数"]
|
|
if len(rows) > 0:
|
|
try:
|
|
v = float(rows.iloc[0]["字段取值"])
|
|
scores.append(min(v / 3, 4))
|
|
except (ValueError, TypeError):
|
|
pass
|
|
|
|
return scores if scores else [1.5]
|
|
|
|
# ========== 辅助赋分函数 ==========
|
|
|
|
@staticmethod
|
|
def _score_likert(value, scale: int = 4, reverse: bool = False) -> Optional[float]:
|
|
"""
|
|
量表题赋分
|
|
value格式可能是 "1" 或 "2(有一些支持)" 等
|
|
"""
|
|
try:
|
|
val_str = str(value).strip()
|
|
# 提取数字部分
|
|
match = re.match(r'^(\d+)', val_str)
|
|
if match:
|
|
v = int(match.group(1))
|
|
if reverse:
|
|
return float(scale + 1 - v)
|
|
return float(v)
|
|
except (ValueError, TypeError):
|
|
pass
|
|
return None
|
|
|
|
@staticmethod
|
|
def _score_resource_level(value) -> Optional[float]:
|
|
"""资源支持程度赋分:几乎没有=1, 有一些=2, 有足够=3"""
|
|
val_str = str(value).strip()
|
|
match = re.match(r'^(\d+)', val_str)
|
|
if match:
|
|
v = int(match.group(1))
|
|
return float(v)
|
|
if "足够" in val_str or "3" in val_str:
|
|
return 3.0
|
|
elif "一些" in val_str or "2" in val_str:
|
|
return 2.0
|
|
elif "没有" in val_str or "1" in val_str:
|
|
return 1.0
|
|
return None
|