from json import load
def main(zhiyuan_fn, kaosheng_fn):
failure = 0
# 读取志愿信息
zhiyuan_result = {}
with open(zhiyuan_fn, encoding='utf8') as fp:
# 跳过第一行的表头
fp.readline()
for line in fp:
key, num, course = line.split(',')
# 计划人数,选科要求,拟录取学生名单,设置每个志愿的初始状态
zhiyuan_result[key] = (int(num), course.strip(), [])
# 读取学生位次、选科以及志愿填报信息
# 数据格式为:{'考生1':(位次, '选科情况','志愿1', '志愿2', ..., '志愿96), ...}
with open(kaosheng_fn, encoding='utf8') as fp:
data = load(fp)
# 按位次升序排序
# 格式为:[('考生1', (位次, '选科情况','志愿1', '志愿2', ..., '志愿96)), ...]
data = sorted(data.items(), key=lambda item:item[1][0])
# 开始投档
for kaosheng, (weici, xuanke, *tianbaozhiyuan) in data:
xuanke = set(xuanke.split('+'))
# 按顺序遍历该考生填报的志愿名称
for zhy in tianbaozhiyuan:
# 获取该志愿的计划人数、选科要求、已录取考生名单
renshu, xuanke_yaoqiu, mingdan = zhiyuan_result[zhy]
if renshu == len(mingdan):
# 该志愿已录满,检查下一个志愿
continue
else:
# 选科要求可能的形式有:不限、物理、物理+化学、
# 物理+化学+生物、物理|化学、物理|化学|生物
condition = ((xuanke_yaoqiu == '不限') or
(xuanke_yaoqiu in xuanke) or
('+' in xuanke_yaoqiu and
set(xuanke_yaoqiu.split('+')) <= xuanke) or
('|' in xuanke_yaoqiu and
set(xuanke_yaoqiu.split('|')) & xuanke))
if condition:
zhiyuan_result[zhy][2].append(kaosheng)
print(f'{kaosheng} 被 {zhy} 录取。')
break
else:
# 填报的所有志愿都没有录取
failure += 1
print(f'{kaosheng} 录取失败。')
func = lambda key:zhiyuan_result[key][0]>len(zhiyuan_result[key][2])
zhengjizhiyuan = tuple(filter(func, zhiyuan_result.keys()))
# 返回录取失败的考生人数和需要征集志愿(即没招满)的志愿数量
return (failure, len(zhengjizhiyuan))
print(main('各志愿计划人数与选科要求.csv', '考生位次选科与志愿填报.json'))