#!/usr/bin/env python3 """ 深度字段审计:逐方法 × 逐字段,精确检查赋分引擎每个赋分函数的数据覆盖。 """ import sys from pathlib import Path from collections import defaultdict import pandas as pd import numpy as np sys.path.insert(0, str(Path(__file__).parent)) sys.path.insert(0, str(Path(__file__).parent.parent.parent / "backend")) from data_engine_era2 import DataEngineEra2 from config_era2 import SUBJECTS def section(title): print(f"\n{'=' * 80}") print(f" {title}") print(f"{'=' * 80}") def check_exact_field(df, field_name, label=""): """检查精确字段名是否存在""" hits = df[df["字段名称"] == field_name] n_schools = hits["学校名称"].nunique() if len(hits) > 0 else 0 status = f"✅ {n_schools}校" if n_schools > 0 else "❌ 不存在" return n_schools, status def check_contains_field(df, keyword, label=""): """检查关键词匹配的字段""" hits = df[df["字段名称"].str.contains(keyword, na=False)] n_fields = hits["字段名称"].nunique() if len(hits) > 0 else 0 n_schools = hits["学校名称"].nunique() if len(hits) > 0 else 0 return n_fields, n_schools def find_similar(all_fields, keyword, top=5): """模糊搜索""" results = [] for f in all_fields: if keyword in str(f): results.append(f) return results[:top] def main(): engine = DataEngineEra2(district_filter=None) engine.load_all() course_df = engine._course_impl subject_df = engine._subject_impl all_course_fields = sorted(course_df["字段名称"].dropna().unique()) all_subject_fields = sorted(subject_df["字段名称"].dropna().unique()) all_fields = set(all_course_fields) | set(all_subject_fields) total_schools = len(engine.schools) print(f"总学校数: {total_schools}") # ===== 按赋分方法逐个检查 ===== results = {} # method -> {field: (status, detail)} def audit_method(method_name, dim_name, checks): """ checks: list of (source, type, field_or_keyword, description) source: 'course' or 'subject' type: 'exact' or 'contains' """ results[method_name] = {"dim": dim_name, "fields": []} df_map = {"course": course_df, "subject": subject_df} for source, check_type, field, desc in checks: df = df_map[source] if check_type == "exact": n_schools, status = check_exact_field(df, field) similar = [] if n_schools == 0: similar = find_similar(all_course_fields if source == "course" else all_subject_fields, field[:4] if len(field) > 4 else field) results[method_name]["fields"].append({ "field": field, "source": source, "type": check_type, "desc": desc, "n_schools": n_schools, "status": status, "similar": similar, }) else: # contains n_fields, n_schools = check_contains_field(df, field) results[method_name]["fields"].append({ "field": field, "source": source, "type": check_type, "desc": desc, "n_schools": n_schools, "n_fields": n_fields, "status": f"✅ {n_fields}字段/{n_schools}校" if n_fields > 0 else "❌", }) # ===== 1. 国家标准遵循 ===== audit_method("_score_national_standard", "国家标准遵循", [ ("subject", "exact", "学科必修课周课时", "必修课周课时"), ("subject", "exact", "学科选择性必修课周课时", "选必课周课时"), ("subject", "exact", "学科类选修课周课时", "选修课周课时"), ]) # ===== 2. 课程结构建设 ===== audit_method("_score_course_structure", "课程结构建设", [ ("course", "exact", "跨学科选修课门数", "跨学科选修课"), ("course", "exact", "综合主题选修课门数", "综合主题选修课"), ("course", "exact", "综合实践选修课门数", "综合实践选修课"), ("course", "exact", "三年应完成的研究性学习数量", "研究性学习数量"), ("course", "exact", "三年社会考察个数", "社会考察"), ("course", "exact", "三年志愿服务时长", "志愿服务"), ]) # ===== 3. 课程规范落实 ===== audit_method("_score_course_norms", "课程规范落实", [ ("course", "contains", "建设规范文本", "规范文本"), ("course", "contains", "档案", "档案规范"), ("course", "contains", "已经建成并使用", "已建成使用"), ("course", "contains", "已经建成尚未使用", "已建成未使用"), ("course", "contains", "尚未建成", "尚未建成"), ]) # ===== 4. 教学方式变革 ===== audit_method("_score_teaching_reform", "教学方式变革", [ ("subject", "contains", "认识程度", "认识程度"), ("subject", "contains", "落实程度", "落实程度"), ("subject", "contains", "体现形式", "实施方式体现形式"), ]) # ===== 5. 作业设计与管理变革 ===== audit_method("_score_homework_reform", "作业设计与管理变革", [ ("subject", "exact", "实践类作业_有布置", "实践类作业"), ("subject", "exact", "表现类作业_有布置", "表现类作业"), ("subject", "exact", "跨学科作业_有布置", "跨学科作业"), ("subject", "exact", "团队合作类作业_有布置", "团队合作类作业"), ("subject", "contains", "作业属性标注", "作业属性标注"), ("subject", "exact", "回家作业时长控制_学校控制", "时长控制-学校"), ("subject", "exact", "回家作业时长控制_教研组负责", "时长控制-教研组"), ("subject", "exact", "作业批改范围_全部批改", "全部批改"), ("subject", "exact", "作业批改范围_部分练习", "部分批改"), ]) # ===== 6. 个性化辅导 ===== audit_method("_score_personalized_tutoring", "学科发展的个性化辅导", [ ("subject", "exact", "个别辅导时长_每周>2h", "辅导>2h"), ("subject", "exact", "个别辅导时长_每周1~2h", "辅导1-2h"), ("subject", "exact", "个别辅导时长_每周<1h", "辅导<1h"), ("subject", "exact", "个别辅导时长_几乎无", "辅导-几乎无"), ("subject", "exact", "个别辅导实施方式_分散辅导", "分散辅导"), ("subject", "exact", "个别辅导实施方式_分组统一辅导", "分组辅导"), ("subject", "exact", "个别辅导实施方式_班级统一辅导", "班级辅导"), ]) # ===== 7. 生涯发展指导 ===== audit_method("_score_career_guidance", "学生生涯发展指导", [ ("course", "exact", "生涯指导实施方式_专设课程", "专设课程"), ("course", "exact", "生涯指导实施方式_社会考察和志愿服务", "社考志愿"), ("course", "exact", "完成生涯指导的学生占比_90%+", "覆盖率90%+"), ("course", "exact", "生涯指导教师构成_本校和外聘结合", "师资-结合"), ("course", "exact", "生涯指导教师构成_本校为主", "师资-本校为主"), ("course", "exact", "生涯指导的校外资源支持程度", "校外资源"), ("course", "exact", "生涯指导的校内资源支持程度", "校内资源"), ]) # ===== 8. 培训支持 ===== audit_method("_score_training_support", "培训支持", [ ("subject", "exact", "提供外校培训的教师人数", "外校培训人数"), ("subject", "exact", "区域培训指导人数", "区域培训人数"), ]) # ===== 9. 教研支持 ===== audit_method("_score_research_support", "教研支持", [ ("subject", "exact", "学科教研组每学期活动次数", "教研活动次数"), ("subject", "exact", "学科教研组平均每次活动时长", "教研活动时长"), ("subject", "exact", "学科教研工作计划_有", "教研计划"), ("subject", "exact", "学科教研组校级展示_有", "校级展示"), ("subject", "exact", "学科教研组区域展示_有", "区域展示"), ("subject", "exact", "学科教研组成果发表_有", "成果发表"), ]) # ===== 10. 项目支持 ===== audit_method("_score_project_support", "项目支持", [ ("subject", "exact", "学科承担的市级教改项目个数", "学科市级项目"), ("subject", "exact", "学科承担的区级教改项目个数", "学科区级项目"), ("subject", "exact", "学科承担的校级教改项目个数", "学科校级项目"), ("course", "exact", "学校负责的市级教改项目个数", "学校负责市级"), ("course", "exact", "学校参与的市级教改项目个数", "学校参与市级"), ("course", "exact", "学校负责的区级教改项目个数", "学校负责区级"), ("course", "exact", "学校参与的区级教改项目个数", "学校参与区级"), ("course", "exact", "校级教改项目个数", "校级项目"), ]) # ===== 11. 科学评价观 ===== audit_method("_score_scientific_evaluation", "科学评价观", [ ("subject", "contains", "作业评价关注点", "作业评价"), ("subject", "contains", "课堂表现评价关注点", "课堂评价"), ("subject", "contains", "学科实践活动评价关注点", "实践评价"), ]) # ===== 12. 学业质量评估 ===== audit_method("_score_academic_evaluation", "学业质量评估", [ ("subject", "exact", "作业评价工具_已经建成并使用", "作业工具-建成使用"), ("subject", "exact", "课堂表现评价工具_已经建成并使用", "课堂工具-建成使用"), ("subject", "exact", "作业评价工具_已经建成尚未使用", "作业工具-建成未用"), ("subject", "exact", "作业评价工具_尚未建成和使用", "作业工具-未建成"), ("subject", "exact", "学期考试分析_执行分析并存档", "考试分析-存档"), ("subject", "exact", "学期考试分析_执行分析,不要求存档", "考试分析-不存档"), ("subject", "exact", "学期考试分析_教师自己决定", "考试分析-自定"), ("subject", "exact", "表现性评价应用程度_经常", "表现性-经常"), ("subject", "exact", "表现性评价应用程度_有时", "表现性-有时"), ("subject", "exact", "表现性评价应用程度_总是", "表现性-总是"), ("subject", "exact", "表现性评价应用程度_从不", "表现性-从不"), ]) # ===== 13. 综合素质评估 ===== audit_method("_score_comprehensive_evaluation", "综合素质评估", [ ("course", "exact", "综评评价体系_已经建成并使用", "综评-建成使用"), ("course", "exact", "综评评价体系_已经建成尚未使用", "综评-建成未用"), ("course", "exact", "综评评价体系_未建成", "综评-未建成"), ("course", "exact", "综评评价体系_不准备建设", "综评-不建设"), ("course", "exact", "综评信息化实现_自建平台支持", "综评IT-自建"), ("course", "exact", "综评信息化实现_借助第三方平台支持", "综评IT-三方"), ("course", "contains", "综评结果使用", "综评结果使用"), ("course", "contains", "综评应用", "综评应用"), ]) # ===== 14. 实践活动评估 ===== audit_method("_score_practice_evaluation", "实践活动评估", [ ("course", "exact", "研究性学习评价工具_已经建成并使用", "研学评价-建成使用"), ("course", "exact", "研究性学习评价工具_尚未建成和使用", "研学评价-未建成"), ("course", "exact", "社会考察评价工具_已经建成并使用", "社考评价-建成使用"), ("course", "exact", "社会考察评价工具_尚未建成和使用", "社考评价-未建成"), ("subject", "exact", "学科实践活动工具_已经建成并使用", "学科实践-建成使用"), ("subject", "exact", "学科实践活动工具_已经建成尚未使用", "学科实践-建成未用"), ("subject", "exact", "学科实践活动工具_尚未建成和使用", "学科实践-未建成"), ]) # ===== 15. 区域推进 ===== audit_method("_score_regional_promotion", "区域推进", [ ("course", "exact", "区域工作会参与_一月4次以上", "工作会-月4+"), ("course", "exact", "区域工作会参与_一月1次", "工作会-月1"), ("course", "exact", "区域工作会参与_二月1次", "工作会-两月1"), ("course", "exact", "区域工作会参与_三月1次", "工作会-季1"), ("course", "contains", "区域推进措施", "推进措施"), ]) # ===== 16. 环境支持 ===== audit_method("_score_environment_support", "环境支持", [ ("course", "exact", "场馆供给_能满足需要", "场馆-满足"), ("course", "exact", "场馆供给_基本满足需要", "场馆-基本满足"), ("course", "exact", "场馆供给_难以满足需要", "场馆-难满足"), ("course", "exact", "专用教室供给_能满足需要", "专用教室-满足"), ("course", "exact", "专用教室供给_基本满足需要", "专用教室-基本满足"), ("course", "contains", "信息化平台功能", "信息化平台功能"), ]) # ===== 17. 资源支持 ===== audit_method("_score_resource_support", "资源支持", [ ("subject", "exact", "必修课校内资源支持程度", "必修校内资源"), ("subject", "exact", "选择性必修课校内资源支持程度", "选必校内资源"), ("subject", "exact", "必修课校外资源支持程度", "必修校外资源"), ("subject", "exact", "选择性必修课校外资源支持程度", "选必校外资源"), ("subject", "exact", "学科教研组总人数", "教研组总人数"), ]) # ===== 18. 教学方式创新 ===== audit_method("_score_digital_teaching", "教学方式创新", [ ("subject", "exact", "信息技术与教学融合的认识_所有人可做到", "IT融合-所有人"), ("subject", "exact", "信息技术与教学融合的认识_个别人可做到", "IT融合-个别人"), ("subject", "exact", "信息化终端使用比例_80%+", "终端-80%+"), ("subject", "exact", "信息化终端使用比例_60~79%", "终端-60~79%"), ("subject", "exact", "信息化终端使用比例_30~59%", "终端-30~59%"), ("subject", "exact", "信息化终端使用比例_30%-", "终端-30%-"), ]) # ===== 19. 评价精准化 ===== audit_method("_score_digital_evaluation", "评价精准化与个性化", [ ("subject", "exact", "学业评价信息化实现_自建平台支持", "学评IT-自建"), ("subject", "exact", "学业评价信息化实现_借助第三方平台支持", "学评IT-三方"), ("subject", "exact", "学业评价信息化实现_没有平台支持", "学评IT-无"), ("course", "exact", "学校信息系统对选课支持程度", "选课系统"), ("course", "exact", "学校信息系统对排课支持程度", "排课系统"), ]) # ===== 20. 课程迭代优化 ===== audit_method("_score_digital_curriculum", "课程迭代优化", [ ("course", "exact", "数据连通_有数据能互通", "数据互通"), ("course", "exact", "数据连通_有数据不互通", "数据不互通"), ("course", "exact", "管理业务的信息化应用_绝大部分", "管理IT-绝大部分"), ("course", "exact", "教学业务的信息化应用_绝大部分", "教学IT-绝大部分"), ("course", "exact", "已完成的网络课程门数", "网络课程数"), ]) # ===== 打印报告 ===== section("完整字段覆盖审计报告") total_fields = 0 total_ok = 0 total_missing = 0 dim_summary = {} for method, info in results.items(): dim = info["dim"] ok = sum(1 for f in info["fields"] if f["n_schools"] > 0) fail = sum(1 for f in info["fields"] if f["n_schools"] == 0) total = len(info["fields"]) total_fields += total total_ok += ok total_missing += fail pct = ok / total * 100 if total > 0 else 0 bar = "█" * int(pct / 5) + "░" * (20 - int(pct / 5)) print(f"\n{'─' * 80}") print(f" {dim} ({method})") print(f" [{bar}] {pct:.0f}% ({ok}/{total})") print(f"{'─' * 80}") for f in info["fields"]: src_label = "课程表" if f["source"] == "course" else "学科表" type_label = "精确" if f["type"] == "exact" else "关键词" print(f" {f['status']:<16} [{src_label}/{type_label}] {f['field']}") if f["n_schools"] == 0 and f.get("similar"): print(f" → 近似: {f['similar'][:3]}") dim_summary[dim] = {"ok": ok, "fail": fail, "total": total, "pct": pct} # ===== 汇总 ===== section("维度覆盖率汇总") print(f"\n{'维度':<20} {'覆盖':>5} {'缺失':>5} {'总数':>5} {'覆盖率':>8}") print(f"{'─' * 50}") for dim, s in dim_summary.items(): marker = "⚠️" if s["pct"] < 60 else "✅" if s["pct"] >= 80 else "⚡" print(f"{dim:<20} {s['ok']:>5} {s['fail']:>5} {s['total']:>5} {s['pct']:>6.0f}% {marker}") print(f"{'─' * 50}") print(f"{'合计':<20} {total_ok:>5} {total_missing:>5} {total_fields:>5} {total_ok/total_fields*100:>6.0f}%") # ===== ETL层面检查:一期有但二期没有的字段名模式 ===== section("ETL字段名差异分析") # 检查常见差异模式 patterns_to_check = [ ("个别辅导时长", "辅导时长字段命名"), ("信息技术与教学融合", "IT融合字段"), ("信息化终端使用比例", "终端使用比例"), ("信息化平台功能", "平台功能"), ("教学业务的信息化", "教学信息化"), ("数据连通", "数据连通"), ("已完成的网络课程", "网络课程"), ("作业批改范围", "作业批改"), ("实践类作业", "实践作业"), ("表现类作业", "表现作业"), ("跨学科作业", "跨学科作业"), ("团队合作类作业", "团队合作作业"), ] for keyword, label in patterns_to_check: course_hits = [f for f in all_course_fields if keyword in str(f)] subject_hits = [f for f in all_subject_fields if keyword in str(f)] if course_hits or subject_hits: print(f"\n ✅ '{keyword}' ({label}):") for h in course_hits: print(f" 课程表: {h}") for h in subject_hits: print(f" 学科表: {h}") else: # 更宽松的搜索 kw_short = keyword[:4] c2 = [f for f in all_course_fields if kw_short in str(f)] s2 = [f for f in all_subject_fields if kw_short in str(f)] print(f"\n ❌ '{keyword}' ({label}): 不存在") if c2 or s2: print(f" 近似(课程表): {c2[:5]}") print(f" 近似(学科表): {s2[:5]}") print(f"\n✅ 深度审计完成!") if __name__ == "__main__": main()