""" 高校整卷数据生成器 """ 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()