123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- """
- 高校整卷数据生成器
- """
- from generator import generator
- import config
- import pandas as pd
- import numpy as np
- import random
- import json
- import openpyxl
- import commonhandle
- import os
- from gxmarkingcloudInf import gxmarkingcloudInf
- from imagebuilder import imageBuilder
- import logger
- class gxgenerator(generator):
- def __init__(self):
- self.courseLst = []
- course_content = config.course.split(",")
- self.questionLst = []
- self.dataoutputpath = str(config.examId)
- if not os.path.exists(self.dataoutputpath):
- os.makedirs(self.dataoutputpath)
- for courses in course_content:
- if len(courses.split("#")) < 3:
- raise Exception("课程参数未配置齐全,请检查")
- self.courseLst.append(
- {"code": courses.split("#")[0], "name": courses.split("#")[1], "imagenum": int(courses.split("#")[2])})
- object_num = config.singlechoice_num + config.multichoice_num + config.trueorfalse_num
- if object_num == 0 and config.subjective_num == 0:
- raise Exception("总题目数量为0,请保证至少含有一道客观题或者一道主观题")
- self.choice = []
- for i in range(int(config.choice_len)):
- self.choice.append(chr(65 + i))
- self.single_choice_order = []
- self.multi_choice_order = []
- self.trueorfalse_order = []
- order = 1
- for idx in range(int(config.singlechoice_num)):
- self.single_choice_order.append(order)
- order = order + 1
- for idx in range(int(config.multichoice_num)):
- self.multi_choice_order.append(order)
- order = order + 1
- for idx in range(int(config.trueorfalse_num)):
- self.trueorfalse_order.append(order)
- order = order + 1
- self.inf=gxmarkingcloudInf()
- self.inf.selectExam()
- def studentgenerator(self):
- student_temp_path = self.dataoutputpath + os.sep + "temp"
- if os.path.exists(student_temp_path + os.sep + "student_temp.xlsx"):
- os.remove(student_temp_path + os.sep + "student_temp.xlsx")
- if os.path.exists(student_temp_path + os.sep + "upload.json"):
- os.remove(student_temp_path + os.sep + "upload.json")
- self.student_name_prefix = "张大_"
- self.org_name_prefix = "数据中心_"
- self.signtable_prefix = 19000000
- self.student_code_prefix = 19000000
- self.identity_num_prefix = 19000000
- self.batch_prefix="A"
- student_template_file = openpyxl.load_workbook("template/gx/考生数据导入模板.xlsx")
- student_sheet = student_template_file.active
- start_row = 3
- for idx in range(1,int(config.studentnum)+1):
- # 随机获取课程
- courses = random.choice(self.courseLst)
- if config.signtable_num != 0:
- signtable = self.signtable_prefix + random.choice(range(1, config.signtable_num + 1))
- else:
- signtable = ""
- student_sheet.cell(start_row, 1, self.org_name_prefix + self.org_name_prefix +str(random.choice(range(1,int(config.org_num)))))
- student_sheet.cell(start_row, 2, courses["code"])
- student_sheet.cell(start_row, 3, courses["name"])
- student_sheet.cell(start_row, 4, self.identity_num_prefix + idx)
- student_sheet.cell(start_row, 5, self.student_code_prefix + idx)
- student_sheet.cell(start_row, 6, self.student_name_prefix + str(idx))
- student_sheet.cell(start_row, 7, signtable)
- student_sheet.cell(start_row, 8, "")
- student_sheet.cell(start_row, 9, "")
- student_sheet.cell(start_row, 10, "")
- student_sheet.cell(start_row, 11, "")
- student_sheet.cell(start_row, 12, "")
- student_sheet.cell(start_row, 13, "")
- student_sheet.cell(start_row, 14, "")
- student_sheet.cell(start_row, 15, "")
- student_sheet.cell(start_row, 16, self.batch_prefix+str(idx//int(config.batch_num)+1))
- start_row=start_row+1
- student_template_file.save(self.dataoutputpath+os.sep+"student.xlsx")
- def papergenerator(self):
- #生成object导入文件
- object_template_file=openpyxl.load_workbook("template/gx/客观题导入模板.xlsx")
- object_sheet=object_template_file.active
- start_row = 3
- for course in self.courseLst:
- main_number=1
- sub_number=1
- for i in range(1,int(config.subjective_num)+1):
- object_sheet.cell(start_row, 1, course["code"])
- object_sheet.cell(start_row, 2, course["name"])
- object_sheet.cell(start_row, 3, main_number)
- object_sheet.cell(start_row, 4, sub_number)
- object_sheet.cell(start_row, 5, "第%d大题"%(main_number))
- object_sheet.cell(start_row, 6, random.choice(self.choice))
- object_sheet.cell(start_row, 7, config.question_point)
- sub_number=sub_number+1
- start_row=start_row+1
- main_number = main_number + 1
- sub_number=1
- for i in range(1,int(config.multichoice_num)+1):
- object_sheet.cell(start_row, 1, course["code"])
- object_sheet.cell(start_row, 2, course["name"])
- object_sheet.cell(start_row, 3, main_number)
- object_sheet.cell(start_row, 4, sub_number)
- object_sheet.cell(start_row, 5, "第%d大题"%(main_number))
- #生成随机答案数量
- question_num=random.choice(range(1,len(self.choice)+1))
- righanswer=random.sample(self.choice,question_num)
- righanswer.sort()
- object_sheet.cell(start_row, 6, "".join(righanswer))
- object_sheet.cell(start_row, 7, config.question_point)
- sub_number = sub_number + 1
- start_row=start_row+1
- main_number=main_number+1
- sub_number = 1
- for i in range(1, int(config.trueorfalse_num) + 1):
- object_sheet.cell(start_row, 1, course["code"])
- object_sheet.cell(start_row, 2, course["name"])
- object_sheet.cell(start_row, 3, main_number)
- object_sheet.cell(start_row, 4, sub_number)
- object_sheet.cell(start_row, 5, "第%d大题" % (main_number))
- # 生成随机答案数量
- object_sheet.cell(start_row, 6, random.choice(["A","B"]))
- object_sheet.cell(start_row, 7, config.question_point)
- sub_number = sub_number + 1
- start_row = start_row + 1
- object_template_file.save(self.dataoutputpath+os.sep+"object.xlsx")
- #生成主观题数据
- subject_template_file = openpyxl.load_workbook("template/gx/主观题导入模板.xlsx")
- subject_sheet = subject_template_file.active
- start_row = 3
- for course in self.courseLst:
- main_number = 1
- sub_number = 1
- for i in range(1, int(config.subjective_num) + 1):
- subject_sheet.cell(start_row, 1, course["code"])
- subject_sheet.cell(start_row, 2, course["name"])
- subject_sheet.cell(start_row, 3, main_number)
- subject_sheet.cell(start_row, 4, "第%d大题" % (main_number))
- subject_sheet.cell(start_row, 5, sub_number)
- subject_sheet.cell(start_row, 6, config.question_point)
- subject_sheet.cell(start_row, 7, config.interval_score)
- sub_number = sub_number + 1
- start_row = start_row + 1
- subject_template_file.save(self.dataoutputpath+os.sep+"subjective.xlsx")
- def importData(self):
- """
- 导入数据
- """
- self.inf.importStudent()
- self.inf.importSubjectivePaper()
- self.inf.importObjectivePaper()
- def filterManual(self,line):
- if line["准考证号"] in list(self.mauallst.values):
- line["maual"]=True
- else:
- line["maual"]=False
- return line
- def filterabsent(self,line):
- if line["准考证号"] in list(self.noabsentLst.values):
- line["absent"] = False
- else:
- line["absent"] = True
- return line
- def imagegenerator(self):
- """
- 生成签到表图片和学生作答图片及裁切图
- 签到表路径{examId}/{签到表编号}/1
- .jpg
- """
- # 读取临时文件数据
- student_temp_path = self.dataoutputpath + os.sep + "temp"
- student_data_frame = pd.read_excel(student_temp_path + os.sep + "student_temp.xlsx")
- student_data_frame["课程代码"] = student_data_frame["课程代码"].astype('str')
- student_data_frame["准考证号"] = student_data_frame["准考证号"].astype('str')
- student_data_frame["学号"] = student_data_frame["学号"].astype('str')
- student_data_frame["签到表编号"] = student_data_frame["签到表编号"].astype('str')
- student_data_signtable_group = student_data_frame.groupby("签到表编号")
- commonhandle.generateSignTable(student_data_frame, student_data_signtable_group)
- with open(student_temp_path + os.sep + "upload.json", 'r', encoding='utf8')as fp:
- json_data = json.load(fp)
- for key, student_data in student_data_frame.iterrows():
- if not student_data["absent"]:
- # 开始生成文件
- course_code = student_data["课程代码"]
- for course in self.courseLst:
- if str(course_code) == str(course["code"]):
- sheet_num = course["imagenum"]
- break
- # checkstudent获取学生的信息
- student_check_data = self.inf.queryStudent(student_data["准考证号"])
- sheet_path = str(config.examId) + os.sep + "image" + os.sep + "ft-sheet" + os.sep + str(
- config.examId) + "-" + str(
- student_check_data["campusCode"]) + os.sep + course_code
- slice_path = str(config.examId) + os.sep + "image" + os.sep + "ft-slice" + os.sep + str(
- config.examId) + "-" + str(
- student_check_data["campusCode"]) + os.sep + course_code
- if not os.path.exists(sheet_path):
- os.makedirs(sheet_path)
- if not os.path.exists(slice_path):
- os.makedirs(slice_path)
- used_num = 1
- object_answerdata = json_data[student_data["准考证号"]]["objectanswer"]
- subject_answer_List = json_data[student_data["准考证号"]]["subject_answer"]
- if object_answerdata:
- first_image = imageBuilder(int(config.image_width), int(config.image_length),
- color=(255, 255, 255, 255))
- first_image.draw_text(200, 500, object_answerdata)
- image_path = sheet_path + os.sep + student_check_data["examNumber"] + "-" + str(used_num) + ".jpg"
- first_image.saveimage(image_path)
- used_num = used_num + 1
- unused_num = sheet_num - used_num + 1
- sheet_list = []
- sheet_list_path = []
- for i in range(1, unused_num + 1):
- image = imageBuilder(int(config.image_width), int(config.image_length),
- color=(255, 255, 255, 255))
- image_path = sheet_path + os.sep + student_check_data["examNumber"] + "-" + str(
- used_num) + ".jpg"
- sheet_list_path.append(image_path)
- used_num = used_num + 1
- sheet_list.append(image)
- if len(subject_answer_List) != 0:
- # 裁切图数量
- slice_num = len(subject_answer_List)
- slice_index = 1
- data_group = np.array_split(range(slice_num), unused_num)
- image_index = 0
- for split_data in data_group:
- index_data = 0
- image = sheet_list[image_index]
- if len(split_data)>0:
- for split_single in split_data:
- # print("font pos:",config.image_length//len(split_data)*index_data+50,subject_answer_List[split_single])
- #
- image.draw_text(200, int(config.image_length) // len(split_data) * index_data + 50,
- subject_answer_List[split_single])
- # 生成slice截图
- split_image = image.splitImage(
- (0, int(config.image_length) // len(split_data) * index_data,
- 2200, int(config.image_length) // len(split_data) * (
- index_data + 1) - 50))
- split_image_path = slice_path + os.sep + student_check_data["examNumber"] + "-" + str(
- slice_index) + ".jpg"
- split_image.save(split_image_path)
- slice_index = slice_index + 1
- index_data = index_data + 1
- else:
- image.draw_text(200, 50,
- "补充")
- split_image = image.splitImage(
- (0, 0,
- 2200, int(config.image_length)))
- split_image_path = slice_path + os.sep + student_check_data["examNumber"] + "-" + str(
- slice_index) + ".jpg"
- split_image.save(split_image_path)
- slice_index = slice_index + 1
- index_data = index_data + 1
- image.saveimage(sheet_list_path[image_index])
- image_index = image_index + 1
- def addMaker(self):
- for course in self.courseLst:
- count = input("请输入要创建的评卷员数量:")
- self.inf.batchcreateMarker(count, course["code"])
- def uploadstudent(self):
- student_temp_path = self.dataoutputpath + os.sep + "temp"
- if not os.path.exists(student_temp_path):
- os.makedirs(student_temp_path)
- if os.path.exists(student_temp_path + os.sep + "student_temp.xlsx"):
- student_data_frame = pd.read_excel(student_temp_path + os.sep + "student_temp.xlsx")
- else:
- student_data_frame = pd.read_excel(self.dataoutputpath + os.sep + "student.xlsx", header=1)
- student_data_frame["课程代码"] = student_data_frame["课程代码"].astype('str')
- student_data_frame["准考证号"] = student_data_frame["准考证号"].astype('str')
- student_data_frame["学号"] = student_data_frame["学号"].astype('str')
- student_data_frame["签到表编号"] = student_data_frame["签到表编号"].astype('str')
- # 根据
- student_absent_frame = student_data_frame.sample(
- int(len(student_data_frame) * (100 - int(config.absentper)) / 100))
- self.noabsentLst = student_absent_frame["准考证号"]
- student_data_frame = student_data_frame.apply(self.filterabsent, axis=1)
- # 从中随机出manual
- student_maual_frame = student_absent_frame.sample(
- int(len(student_absent_frame) * (100 - int(config.manualper)) / 100))
- self.nomauallst = student_maual_frame["准考证号"]
- student_data_frame = student_data_frame.apply(self.filterManual, axis=1)
- # 存储到temp文件夹下
- student_data_frame.to_excel(student_temp_path + os.sep + "student_temp.xlsx", index=False)
- # 取出题目信息
- object_data_frame = pd.read_excel(self.dataoutputpath + os.sep + "object.xlsx", header=1)
- object_data_frame["科目代码"] = object_data_frame["科目代码"].astype('str')
- object_group = object_data_frame.groupby("科目代码")
- subject_data_frame = pd.read_excel(self.dataoutputpath + os.sep + "subjective.xlsx", header=1)
- subject_data_frame["科目代码"] = subject_data_frame["科目代码"].astype('str')
- subbject_group = subject_data_frame.groupby("科目代码")
- uploadList = {}
- for key, student_data in student_data_frame.iterrows():
- if not student_data["absent"]:
- rightper = random.choice(range(101))
- course_code = student_data["课程代码"]
- for course in self.courseLst:
- if str(course_code) == str(course["code"]):
- sheet_num = course["imagenum"]
- break
- # 生成客观题作答信息
- object_course_data = object_group.get_group(str(course_code))
- object_answerdata = commonhandle.generateObjectAnswer(rightper, student_data, object_course_data,
- self.single_choice_order, self.multi_choice_order,
- self.choice)
- subject_course_data = subbject_group.get_group(str(course_code))
- subject_answer_List = commonhandle.generategxSubjectAnswer(student_data, subject_course_data)
- uploadList[student_data["准考证号"]] = {"objectanswer": object_answerdata,
- "subject_answer": subject_answer_List}
- student_upload_data = {
- "examNumber": student_data["准考证号"],
- "sliceCount": config.subjective_num,
- "sheetCount": sheet_num,
- "answers": object_answerdata,
- "batchCode": "",
- "absent": False,
- "manual": student_data["maual"]
- }
- logger.info(student_upload_data)
- self.inf.scanstudent(student_upload_data)
- else:
- student_upload_data = {
- "examNumber": student_data["准考证号"],
- "sliceCount": 0,
- "sheetCount": 0,
- "answers": "",
- "batchCode": "",
- "absent": True,
- "manual": False
- }
- logger.info(student_upload_data)
- self.inf.scanstudent(student_upload_data)
- with open(student_temp_path + os.sep + "upload.json", "w", encoding="utf-8") as file:
- json_str = json.dumps(uploadList, indent=4, ensure_ascii=False)
- file.write(json_str)
- # builder=gxgenerator()
- # #builder.studentgenerator()
- # # builder.papergenerator()
- # builder.imagegenerator()
|