""" 赋分引擎:将原始题目回答按赋分规则转换为分数 基于赋分整理表的规则,实现各类赋分函数 """ 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