from generator import generator """ 高校整卷数据生成器 """ from generator import generator import config import pandas as pd import json import numpy as np import random import commonhandle import openpyxl import os from ftmarkingcloudInf import ftmarkingcloudInf from imagebuilder import imageBuilder import logger class ftgenerator(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.initTeacherandClassandColleage() self.inf=ftmarkingcloudInf() self.inf.selectExam() def initTeacherandClassandColleage(self): """ 生成学院老师班级,只要有一个为空都直接抛异常 总共有多少老师,每个学院下有多少班级,班级由老师平均分配 """ colleage_prefix="学院_" teacher_prefix="教师_" class_prefix="班级_" self.colleageLst={} if config.teacher_num!=0 and config.colleage_num!=0 and config.classundercolleage_num!=0: teacher_postfix = range(1, config.teacher_num + 1) for i in range(1,(config.colleage_num+1)): colleage_name=colleage_prefix+str(i) self.colleageLst[colleage_name]={} for j in range(1,config.classundercolleage_num+1): classname=colleage_name+"_"+class_prefix+str(j) postfix=random.choice(teacher_postfix) self.colleageLst[colleage_name][classname]=teacher_prefix+str(postfix) 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/ft/考生数据导入模板.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 +str(random.choice(range(1,config.org_num)))) student_sheet.cell(start_row, 1, courses["code"]) student_sheet.cell(start_row, 2, courses["name"]) student_sheet.cell(start_row, 3, self.identity_num_prefix + idx) student_sheet.cell(start_row, 4, self.student_code_prefix + idx) student_sheet.cell(start_row, 5, self.student_name_prefix + str(idx)) student_sheet.cell(start_row, 6, signtable) student_sheet.cell(start_row, 7, self.org_name_prefix+str(random.choice(range(1,config.org_num+1)))) student_sheet.cell(start_row, 8, "") student_sheet.cell(start_row, 9, "") student_sheet.cell(start_row, 10, "") student_sheet.cell(start_row, 11, "") if self.colleageLst: colleage_name=random.choice(list(self.colleageLst.keys())) class_name=random.choice(list(self.colleageLst[colleage_name].keys())) teachername=self.colleageLst[colleage_name][class_name] else: colleage_name="" class_name="" teachername="" student_sheet.cell(start_row, 12, colleage_name) student_sheet.cell(start_row, 13, class_name) student_sheet.cell(start_row, 14, teachername) student_sheet.cell(start_row, 15, "") 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/ft/客观题导入模板.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,config.singlechoice_num+1): object_sheet.cell(start_row, 1, course["code"]) object_sheet.cell(start_row, 2, course["name"]) object_sheet.cell(start_row, 4, "第%d大题"%(main_number)) object_sheet.cell(start_row, 5, main_number) object_sheet.cell(start_row, 6, sub_number) object_sheet.cell(start_row, 7, random.choice(self.choice)) object_sheet.cell(start_row, 8, 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,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, 4, "第%d大题"%(main_number)) object_sheet.cell(start_row, 5, main_number) object_sheet.cell(start_row, 6, sub_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, 7, "".join(righanswer)) object_sheet.cell(start_row, 8, 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, 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, 4, "第%d大题" % (main_number)) object_sheet.cell(start_row, 5, main_number) object_sheet.cell(start_row, 6, sub_number) # 生成随机答案数量 object_sheet.cell(start_row, 7, random.choice(["A","B"])) object_sheet.cell(start_row, 8, 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/ft/主观题导入模板.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, 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, "第%d大题" % (main_number)) subject_sheet.cell(start_row, 4, 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) subject_sheet.cell(start_row, 8, main_number) #图片预先按照subnumber顺序进行填入 subject_sheet.cell(start_row, 9, main_number) main_number = main_number+1 sub_number = sub_number + 1 start_row = start_row + 1 subject_template_file.save(self.dataoutputpath+os.sep+"subjective.xlsx") def importData(self): """ 导入数据 """ print("start to import student data") self.inf.importStudent() print("start to import subjective data") self.inf.importSubjectivePaper() print("start to import objective data") self.inf.importObjectivePaper() def addMaker(self): for course in self.courseLst: count=input("请输入要创建的评卷员数量:") self.inf.batchcreateMarker(count,course["code"]) def filterManual(self,line): if line["准考证号"] in list(self.nomauallst.values): line["maual"]=False else: line["maual"]=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["准考证号"]) print(student_check_data) sheet_path = str(config.examId) + os.sep + "image" + os.sep + "sheet" + os.sep + str(config.examId) + os.sep+ str( student_check_data["examNumber"][-3:]) slice_path = str(config.examId) + os.sep + "image" + os.sep + "slice" + os.sep + str(config.examId) + os.sep + str( student_check_data["secrectNumber"][-3:]) 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" used_num = used_num + 1 sheet_list.append(image) sheet_list_path.append(image_path) 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] image.draw_text(0, 50, student_check_data["secrectNumber"]) 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["secrectNumber"] + "-" + 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, str(student_check_data["examNumber"])+"补充"+str(image_index)) split_image = image.splitImage( (0, 0, 2200, int(config.image_length))) split_image_path = slice_path + os.sep + student_check_data["secrectNumber"] + "-" + 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 filterabsent(self,line): if line["准考证号"] in list(self.noabsentLst.values): line["absent"] = False else: line["absent"] = True return line 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 # 生成客观题作答信息 if str(course_code) in object_group.groups: 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) else: object_answerdata="" if str(course_code) in subbject_group.groups: subject_course_data = subbject_group.get_group(str(course_code)) subject_answer_List = commonhandle.generateSubjectAnswer(student_data,subject_course_data) else: subject_answer_List=[] 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) logger.info("缺考不做上传") #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) generator=ftgenerator() # generator.studentgenerator() # # generator.papergenerator() # generator.importData() # generator.uploadstudent() generator.imagegenerator() # #