Files
gaokao-volunteer-system/scripts/gaokao-collect-info.py

706 lines
32 KiB
Python
Raw Normal View History

# 高考志愿填报 - 交互式信息收集系统
# 优先级2优化信息收集体验
import json
from datetime import datetime
2026-06-13 14:49:58 +08:00
from typing import Any
class GaokaoInfoCollector:
"""
高考志愿填报信息收集器
采用分步骤引导式交互确保收集完整准确的信息
"""
2026-06-13 14:49:58 +08:00
def __init__(self):
self.data = {
2026-06-13 14:49:58 +08:00
"basic_info": {}, # 基本信息
"exam_info": {}, # 考试信息
"interest_profile": {}, # 兴趣测评
"ability_assessment": {}, # 能力评估
"career_goals": {}, # 职业目标
"family_background": {}, # 家庭背景
"preferences": {}, # 偏好设置
}
self.current_step = 0
self.total_steps = 7
2026-06-13 14:49:58 +08:00
def welcome(self):
"""欢迎界面"""
print("""
🎓 高考志愿填报智能助手 v2.0
本系统将引导您完成志愿填报所需的信息收集
预计用时5-8分钟
💡 提示
请准备高考成绩单一分一段表意向专业名单
建议考生本人参与填写
信息越详细推荐越精准
""")
input("\n按 Enter 键开始...")
2026-06-13 14:49:58 +08:00
def step_1_basic_info(self) -> bool:
"""
步骤1基本信息收集
"""
print("""
步骤 1/7基本信息
请填写考生的基本信息
""")
2026-06-13 14:49:58 +08:00
# 姓名
while True:
name = input("1. 考生姓名:").strip()
if name:
self.data["basic_info"]["name"] = name
break
print(" ⚠️ 姓名不能为空,请重新输入")
2026-06-13 14:49:58 +08:00
# 省份
provinces = [
2026-06-13 14:49:58 +08:00
"北京",
"天津",
"河北",
"山西",
"内蒙古",
"辽宁",
"吉林",
"黑龙江",
"上海",
"江苏",
"浙江",
"安徽",
"福建",
"江西",
"山东",
"河南",
"湖北",
"湖南",
"广东",
"广西",
"海南",
"重庆",
"四川",
"贵州",
"云南",
"西藏",
"陕西",
"甘肃",
"青海",
"宁夏",
"新疆",
]
while True:
print("\n2. 所在省份(输入编号):")
for i, p in enumerate(provinces, 1):
print(f" {i:2d}. {p}", end=" ")
if i % 5 == 0:
print()
try:
choice = int(input("\n请选择:"))
if 1 <= choice <= len(provinces):
2026-06-13 14:49:58 +08:00
self.data["basic_info"]["province"] = provinces[choice - 1]
break
except ValueError:
pass
print(" ⚠️ 无效选择,请重新输入")
2026-06-13 14:49:58 +08:00
# 手机号(可选,用于接收报告)
phone = input("\n3. 家长手机号(可选,用于接收报告):").strip()
if phone:
self.data["basic_info"]["phone"] = phone
2026-06-13 14:49:58 +08:00
print(
f"\n✅ 基本信息已收集:{self.data['basic_info']['name']}{self.data['basic_info']['province']}"
)
return True
2026-06-13 14:49:58 +08:00
def step_2_exam_info(self) -> bool:
"""
步骤2考试信息收集
"""
print("""
步骤 2/7高考信息
请填写高考相关信息
这些信息将用于精准匹配院校和专业
""")
2026-06-13 14:49:58 +08:00
# 高考模式
print("\n1. 高考模式:")
print(" 1. 传统文理分科")
print(" 2. 3+3 模式(浙江、上海、北京、天津、山东、海南)")
print(" 3. 3+1+2 模式(其他新高考省份)")
2026-06-13 14:49:58 +08:00
while True:
try:
mode = int(input("请选择:"))
if mode == 1:
self.data["exam_info"]["mode"] = "传统文理"
self.data["exam_info"]["batch"] = input(" 文/理科:").strip()
elif mode == 2:
self.data["exam_info"]["mode"] = "3+3"
elif mode == 3:
self.data["exam_info"]["mode"] = "3+1+2"
2026-06-13 14:49:58 +08:00
self.data["exam_info"]["main_subject"] = input(
" 首选科目(物理/历史):"
).strip()
else:
raise ValueError
break
except (ValueError, IndexError):
print(" ⚠️ 无效选择,请重新输入")
2026-06-13 14:49:58 +08:00
# 选科组合
print("\n2. 选科组合(已选科目,空格分隔):")
print(" 可选:语文 数学 英语 物理 历史 化学 生物 政治 地理 技术")
subjects_input = input(" 请输入:").strip()
self.data["exam_info"]["subjects"] = subjects_input.split()
2026-06-13 14:49:58 +08:00
# 高考总分
while True:
try:
score = int(input("\n3. 高考总分满分750"))
if 0 <= score <= 750:
self.data["exam_info"]["total_score"] = score
break
print(" ⚠️ 分数应在0-750之间")
except ValueError:
print(" ⚠️ 请输入有效数字")
2026-06-13 14:49:58 +08:00
# 全省位次
while True:
try:
rank = int(input("\n4. 全省位次(一分一段表查询):"))
if rank > 0:
self.data["exam_info"]["rank"] = rank
break
print(" ⚠️ 位次应为正数")
except ValueError:
print(" ⚠️ 请输入有效数字")
2026-06-13 14:49:58 +08:00
# 各科成绩(可选,用于能力评估)
print("\n5. 各科成绩(可选,用于精准匹配):")
subjects_score = {}
for subject in ["语文", "数学", "英语"]:
score_input = input(f" {subject}成绩(回车跳过):").strip()
if score_input:
try:
subjects_score[subject] = int(score_input)
except ValueError:
pass
self.data["exam_info"]["subject_scores"] = subjects_score
2026-06-13 14:49:58 +08:00
print(f"\n✅ 高考信息已收集:{score}分,位次:{rank}")
return True
2026-06-13 14:49:58 +08:00
def step_3_interest_profile(self) -> bool:
"""
步骤3兴趣测评霍兰德模型
"""
print("""
步骤 3/7兴趣测评
这部分用于了解考生的兴趣类型
帮助匹配最适合的专业方向
""")
2026-06-13 14:49:58 +08:00
print("\n💡 说明:请选择最符合实际情况的选项")
print("-" * 60)
2026-06-13 14:49:58 +08:00
questions: list[dict[str, Any]] = [
{
"q": "课余时间,你最喜欢做什么?",
"options": [
("A", "拆解/组装东西(电器、模型、电脑)", "R"),
("B", "看书、研究问题、探索原理", "I"),
("C", "画画、设计、创作、写作", "A"),
("D", "和朋友出去玩、组织活动", "S"),
("E", "做小生意、策划活动、当组织者", "E"),
("F", "整理房间、做规划、记账", "C"),
2026-06-13 14:49:58 +08:00
],
},
{
"q": "如果完全不用担心钱,你最想做什么?",
"options": [
("A", "研究新技术、搞发明创造", "R"),
("B", "做科学研究、发现新知识", "I"),
("C", "成为艺术家、作家、设计师", "A"),
("D", "做志愿者、帮助他人", "S"),
("E", "创办公司、当企业家", "E"),
("F", "做管理、让一切井井有条", "C"),
2026-06-13 14:49:58 +08:00
],
},
{
"q": "你在哪些事情上容易'忘记时间'",
"options": [
("A", "修东西、做手工、编程", "R"),
("B", "解难题、做实验、查资料", "I"),
("C", "创作、设计、欣赏艺术", "A"),
("D", "和人交流、帮助别人解决问题", "S"),
("E", "策划、组织、领导项目", "E"),
("F", "整理数据、制定计划", "C"),
2026-06-13 14:49:58 +08:00
],
},
{
"q": "你明确不喜欢什么类型的事情?(多选)",
"multi": True,
"options": [
("A", "背诵记忆(如历史、法律条文)", "memory"),
("B", "数学计算、逻辑推理", "math"),
("C", "和人打交道、社交应酬", "social"),
("D", "做实验、动手操作", "experiment"),
("E", "写代码、学技术", "tech"),
("F", "我都能接受", "none"),
2026-06-13 14:49:58 +08:00
],
},
]
2026-06-13 14:49:58 +08:00
holland_scores = {"R": 0, "I": 0, "A": 0, "S": 0, "E": 0, "C": 0}
2026-06-13 14:49:58 +08:00
dislikes: list[str] = []
for idx, question in enumerate(questions, 1):
print(f"\n{idx}. {question['q']}")
2026-06-13 14:49:58 +08:00
for opt, text, code in question["options"]:
print(f" {opt}. {text}")
2026-06-13 14:49:58 +08:00
if question.get("multi"):
# 多选
answer = input("请选择可多选ABC").strip().upper()
for char in answer:
2026-06-13 14:49:58 +08:00
for opt, text, code in question["options"]:
if char == opt:
if code == "none":
dislikes = []
else:
dislikes.append(code)
break
else:
# 单选
while True:
answer = input("请选择:").strip().upper()
2026-06-13 14:49:58 +08:00
for opt, text, code in question["options"]:
if answer == opt:
holland_scores[code] += 1
break
else:
print(" ⚠️ 无效选择")
continue
break
2026-06-13 14:49:58 +08:00
# 确定主导兴趣类型
sorted_types = sorted(holland_scores.items(), key=lambda x: x[1], reverse=True)
primary_type = sorted_types[0][0]
secondary_type = sorted_types[1][0]
2026-06-13 14:49:58 +08:00
type_names = {
"R": "现实型Realistic- 动手操作、技术实践",
"I": "研究型Investigative- 分析研究、探索发现",
"A": "艺术型Artistic- 创意表达、艺术创作",
"S": "社会型Social- 帮助他人、教育服务",
"E": "企业型Enterprising- 领导管理、商业经营",
2026-06-13 14:49:58 +08:00
"C": "常规型Conventional- 规范有序、数据处理",
}
2026-06-13 14:49:58 +08:00
self.data["interest_profile"]["holland_code"] = (
f"{primary_type}{secondary_type}"
)
self.data["interest_profile"]["primary_type"] = type_names[primary_type]
self.data["interest_profile"]["secondary_type"] = type_names[secondary_type]
self.data["interest_profile"]["scores"] = holland_scores
self.data["interest_profile"]["dislikes"] = dislikes
2026-06-13 14:49:58 +08:00
print("\n✅ 兴趣测评完成:")
print(f" 主导类型:{type_names[primary_type]}")
print(f" 次要类型:{type_names[secondary_type]}")
if dislikes:
print(f" 明确不喜欢:{', '.join(dislikes)}")
return True
2026-06-13 14:49:58 +08:00
def step_4_ability_assessment(self) -> bool:
"""
步骤4能力评估
"""
print("""
步骤 4/7能力评估
评估各学科能力和软技能
帮助识别优势和短板
""")
2026-06-13 14:49:58 +08:00
print("\n请对以下方面进行自我评估1-5分")
print("1分=很弱 2分=较弱 3分=一般 4分=较强 5分=很强")
print("-" * 60)
2026-06-13 14:49:58 +08:00
subjects = ["数学", "物理", "化学", "生物", "语文", "英语"]
subject_scores = {}
2026-06-13 14:49:58 +08:00
for subject in subjects:
while True:
try:
score = int(input(f"\n{subject}能力1-5"))
if 1 <= score <= 5:
subject_scores[subject] = score
break
print(" ⚠️ 请输入1-5之间的数字")
except ValueError:
print(" ⚠️ 请输入有效数字")
2026-06-13 14:49:58 +08:00
print("\n软技能评估:")
soft_skills = {
"逻辑思维": "分析问题的能力",
"动手操作": "手工、实验、操作设备的能力",
"沟通表达": "与人交流、演讲、写作的能力",
"组织协调": "组织活动、管理项目的能力",
"艺术创作": "绘画、设计、音乐、创意能力",
2026-06-13 14:49:58 +08:00
"抗压能力": "面对压力和挫折的承受力",
}
2026-06-13 14:49:58 +08:00
soft_skill_scores = {}
for skill, desc in soft_skills.items():
while True:
try:
score = int(input(f"\n{skill} - {desc}1-5"))
if 1 <= score <= 5:
soft_skill_scores[skill] = score
break
print(" ⚠️ 请输入1-5之间的数字")
except ValueError:
print(" ⚠️ 请输入有效数字")
2026-06-13 14:49:58 +08:00
# 识别强项和弱项
strong_subjects = [s for s, score in subject_scores.items() if score >= 4]
weak_subjects = [s for s, score in subject_scores.items() if score <= 2]
2026-06-13 14:49:58 +08:00
self.data["ability_assessment"]["subjects"] = subject_scores
self.data["ability_assessment"]["soft_skills"] = soft_skill_scores
self.data["ability_assessment"]["strong"] = strong_subjects
self.data["ability_assessment"]["weak"] = weak_subjects
2026-06-13 14:49:58 +08:00
print("\n✅ 能力评估完成:")
if strong_subjects:
print(f" 优势学科:{', '.join(strong_subjects)}")
if weak_subjects:
print(f" 薄弱学科:{', '.join(weak_subjects)}")
return True
2026-06-13 14:49:58 +08:00
def step_5_career_goals(self) -> bool:
"""
步骤5职业目标
"""
print("""
步骤 5/7职业目标
了解考生的职业期望和发展目标
""")
2026-06-13 14:49:58 +08:00
print("\n1. 您最看重职业的哪些方面按重要性排序输入编号如135")
priorities = [
"收入高、赚钱多",
"工作稳定、不担心失业",
"符合兴趣爱好",
"发展前景好、晋升空间大",
"工作生活平衡、不加班",
"社会地位高、受尊重",
2026-06-13 14:49:58 +08:00
"工作自由、时间灵活",
]
for i, p in enumerate(priorities, 1):
print(f" {i}. {p}")
2026-06-13 14:49:58 +08:00
priority_input = input("\n请选择按重要性排序135").strip()
selected_priorities = []
for char in priority_input[:3]: # 取前3个
try:
idx = int(char) - 1
if 0 <= idx < len(priorities):
selected_priorities.append(priorities[idx])
except ValueError:
pass
self.data["career_goals"]["priorities"] = selected_priorities
2026-06-13 14:49:58 +08:00
print("\n2. 毕业后规划:")
print(" 1. 本科毕业直接工作")
print(" 2. 考研/保研继续深造")
print(" 3. 出国留学")
print(" 4. 考公务员/事业单位")
print(" 5. 不确定")
2026-06-13 14:49:58 +08:00
while True:
try:
plan = int(input("请选择:"))
if 1 <= plan <= 5:
plans = ["本科就业", "考研深造", "出国留学", "考公务员", "不确定"]
2026-06-13 14:49:58 +08:00
self.data["career_goals"]["plan"] = plans[plan - 1]
break
except ValueError:
pass
print(" ⚠️ 无效选择")
2026-06-13 14:49:58 +08:00
print("\n3. 是否有明确的职业方向?(可选)")
print(" 例:医生、程序员、教师、律师、设计师等")
career = input("请输入:").strip()
if career:
self.data["career_goals"]["target_career"] = career
2026-06-13 14:49:58 +08:00
print("\n✅ 职业目标已收集:")
print(f" 优先看重:{', '.join(selected_priorities[:3])}")
print(f" 毕业规划:{self.data['career_goals']['plan']}")
return True
2026-06-13 14:49:58 +08:00
def step_6_family_background(self) -> bool:
"""
步骤6家庭背景
"""
print("""
步骤 6/7家庭情况
了解家庭资源和约束条件
""")
2026-06-13 14:49:58 +08:00
print("\n1. 家庭经济情况:")
print(" 1. 困难(需要助学贷款/奖学金)")
print(" 2. 一般(能负担学费,其他需节省)")
print(" 3. 中等(学费生活费无压力)")
print(" 4. 较好(可支持考研/出国)")
print(" 5. 富裕(无经济压力)")
2026-06-13 14:49:58 +08:00
while True:
try:
level = int(input("请选择:"))
if 1 <= level <= 5:
levels = ["困难", "一般", "中等", "较好", "富裕"]
2026-06-13 14:49:58 +08:00
self.data["family_background"]["economic"] = levels[level - 1]
break
except ValueError:
pass
print(" ⚠️ 无效选择")
2026-06-13 14:49:58 +08:00
print("\n2. 期望就业城市:")
print(" 1. 一线城市(北上广深)")
print(" 2. 新一线城市(杭州、南京、成都等)")
print(" 3. 省会城市")
print(" 4. 家乡/本地城市")
print(" 5. 不限定")
print(" 6. 其他(请填写)")
2026-06-13 14:49:58 +08:00
city_choice = input("请选择:").strip()
if city_choice == "6":
city = input("请填写期望城市:").strip()
else:
cities = ["一线城市", "新一线城市", "省会城市", "家乡/本地", "不限定", ""]
2026-06-13 14:49:58 +08:00
city = (
cities[int(city_choice) - 1]
if city_choice.isdigit() and 1 <= int(city_choice) <= 6
else "不限定"
)
self.data["family_background"]["target_city"] = city
2026-06-13 14:49:58 +08:00
print("\n3. 是否有家族行业资源可利用?(可选)")
print(" 例:父母在医疗系统、家族经商、有法律资源等")
resource = input("请输入:").strip()
if resource:
self.data["family_background"]["family_resource"] = resource
2026-06-13 14:49:58 +08:00
print("\n✅ 家庭情况已收集")
return True
2026-06-13 14:49:58 +08:00
def step_7_preferences(self) -> bool:
"""
步骤7偏好设置
"""
print("""
步骤 7/7偏好设置
最后的个性化设置
""")
2026-06-13 14:49:58 +08:00
print("\n1. 院校层次偏好:")
print(" 1. 优先985/211名校优先")
print(" 2. 优先专业实力(专业排名优先)")
print(" 3. 优先地理位置(城市优先)")
print(" 4. 综合平衡")
2026-06-13 14:49:58 +08:00
while True:
try:
pref = int(input("请选择:"))
if 1 <= pref <= 4:
prefs = ["名校优先", "专业优先", "城市优先", "综合平衡"]
2026-06-13 14:49:58 +08:00
self.data["preferences"]["school_priority"] = prefs[pref - 1]
break
except ValueError:
pass
print(" ⚠️ 无效选择")
2026-06-13 14:49:58 +08:00
print("\n2. 专业方向偏好:(可多选)")
directions = [
"工科类(计算机、电子、机械等)",
"理科类(数学、物理、化学等)",
"医学类(临床、口腔、护理等)",
"经管类(经济、金融、管理等)",
"文科类(中文、外语、新闻等)",
"艺术类(设计、音乐、美术等)",
"师范类(教育、心理等)",
2026-06-13 14:49:58 +08:00
"政法类(法学、政治等)",
]
for i, d in enumerate(directions, 1):
print(f" {i}. {d}")
selected = input("请选择多选135").strip()
selected_dirs = []
for char in selected:
try:
idx = int(char) - 1
if 0 <= idx < len(directions):
selected_dirs.append(directions[idx])
except ValueError:
pass
self.data["preferences"]["major_directions"] = selected_dirs
2026-06-13 14:49:58 +08:00
print("\n3. 是否接受调剂:")
print(" 1. 必须服从调剂(确保录取)")
print(" 2. 可接受部分调剂")
print(" 3. 不服从调剂(优先专业)")
2026-06-13 14:49:58 +08:00
while True:
try:
adjust = int(input("请选择:"))
if 1 <= adjust <= 3:
adjusts = ["必须服从", "部分接受", "不服从"]
2026-06-13 14:49:58 +08:00
self.data["preferences"]["adjustment"] = adjusts[adjust - 1]
break
except ValueError:
pass
print(" ⚠️ 无效选择")
2026-06-13 14:49:58 +08:00
print("\n✅ 偏好设置完成")
return True
2026-06-13 14:49:58 +08:00
def review_and_confirm(self) -> bool:
"""
信息回顾与确认
"""
print("""
📋 信息确认
请核对以下信息确认无误后生成报告
""")
2026-06-13 14:49:58 +08:00
print("\n【基本信息】")
print(f" 姓名:{self.data['basic_info']['name']}")
print(f" 省份:{self.data['basic_info']['province']}")
2026-06-13 14:49:58 +08:00
print("\n【高考信息】")
print(f" 模式:{self.data['exam_info']['mode']}")
print(f" 总分:{self.data['exam_info']['total_score']}")
print(f" 位次:{self.data['exam_info']['rank']}")
2026-06-13 14:49:58 +08:00
print("\n【兴趣类型】")
print(f" 霍兰德代码:{self.data['interest_profile']['holland_code']}")
print(f" 主导类型:{self.data['interest_profile']['primary_type']}")
2026-06-13 14:49:58 +08:00
print("\n【能力评估】")
strong = self.data["ability_assessment"]["strong"]
if strong:
print(f" 优势:{', '.join(strong)}")
2026-06-13 14:49:58 +08:00
print("\n【职业目标】")
print(f" 规划:{self.data['career_goals']['plan']}")
2026-06-13 14:49:58 +08:00
print("\n【家庭情况】")
print(f" 经济:{self.data['family_background']['economic']}")
print(f" 目标城市:{self.data['family_background']['target_city']}")
2026-06-13 14:49:58 +08:00
confirm = input("\n以上信息是否正确Y/n").strip().lower()
2026-06-13 14:49:58 +08:00
return confirm != "n"
def save_data(self, filename=None):
"""
保存数据到文件
"""
if filename is None:
filename = f"/tmp/gaokao_profile_{self.data['basic_info']['name']}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
2026-06-13 14:49:58 +08:00
self.data["meta"] = {"created_at": datetime.now().isoformat(), "version": "2.0"}
with open(filename, "w", encoding="utf-8") as f:
json.dump(self.data, f, ensure_ascii=False, indent=2)
2026-06-13 14:49:58 +08:00
print(f"\n💾 数据已保存到:{filename}")
return filename
2026-06-13 14:49:58 +08:00
def run(self):
"""
运行完整收集流程
"""
self.welcome()
2026-06-13 14:49:58 +08:00
steps = [
("基本信息", self.step_1_basic_info),
("高考信息", self.step_2_exam_info),
("兴趣测评", self.step_3_interest_profile),
("能力评估", self.step_4_ability_assessment),
("职业目标", self.step_5_career_goals),
("家庭情况", self.step_6_family_background),
("偏好设置", self.step_7_preferences),
]
2026-06-13 14:49:58 +08:00
for idx, (name, step_func) in enumerate(steps, 1):
self.current_step = idx
if not step_func():
print(f"\n❌ 步骤 {idx} 未完成,退出收集")
return False
2026-06-13 14:49:58 +08:00
# 确认信息
if not self.review_and_confirm():
print("\n请重新运行程序修改信息")
return False
2026-06-13 14:49:58 +08:00
# 保存数据
data_file = self.save_data()
2026-06-13 14:49:58 +08:00
print("""
信息收集完成
接下来可以
1. 运行可视化报告生成器生成完整报告
2. 使用收集的数据进行志愿匹配分析
""")
2026-06-13 14:49:58 +08:00
return data_file
# 直接运行
if __name__ == "__main__":
collector = GaokaoInfoCollector()
data_file = collector.run()
2026-06-13 14:49:58 +08:00
if data_file:
print(f"\n数据文件:{data_file}")
print("\n提示:您可以使用以下命令生成可视化报告:")
2026-06-13 14:49:58 +08:00
print(" python3 ~/.local/bin/gaokao-visual-report-v2.py")