def post(self, request, *args, **kwargs): ques_nr = request.POST['ques_nr'] mat_nr = request.POST['mat_nr'] if ques_nr and mat_nr: object_list = StudentAns.objects.filter(exam=get_exam( self.request), matriculation_num=mat_nr, question_num=ques_nr) context = {'object_list': object_list} return render(request, 'grader/studentans_list.html', context) elif ques_nr: object_list = StudentAns.objects.filter(exam=get_exam( self.request), question_num=ques_nr) context = {'object_list': object_list} return render(request, 'grader/studentans_list.html', context) elif mat_nr: object_list = StudentAns.objects.filter(exam=get_exam( self.request), matriculation_num=mat_nr) context = {'object_list': object_list} return render(request, 'grader/studentans_list.html', context) else: object_list = StudentAns.objects.filter( exam=get_exam(self.request)) context = {'object_list': object_list} return render(request, 'grader/studentans_list.html', context)
def get_queryset(self): order = self.kwargs.get('order', None) if order: return StudentAns.objects.filter( exam=get_exam(self.request)).order_by( order, 'matching_confidence')[:50] return StudentAns.objects.filter( exam=get_exam(self.request)).order_by('question_num')[:50]
def readAns(self, request): """ scan all cleaned image, read student ans and save the ans to data base """ print('Reading answer sheets....') current_exam = get_exam(request) current_exam_id = str(current_exam.id) studentsAns = [] # get all question with loc questions = get_list_or_404(Question, exam=get_exam(request)) # print(questions) questions_loc = [(q.question_number, q.page, q.topLeftX, q.topLeftY, q.bottomRightX, q.bottomRightY)for q in questions] # print(questions_loc) # questionsLoc = readConfig.getQuestionsLoc() # questionLoc=== [['question_no', 'page_no', 'leftx', 'left top', right x, 'right top'],[]] cleanImages = os.listdir(self.cleanedPath) for image in cleanImages: exam_id, mat_number, page_number = image.split('_') page_number, ext = page_number.split('.') # imageName = os.path.join(self.cleanedPath, image) im = Image.open(os.path.join(self.cleanedPath, image)) for question in questions_loc: # print('page num'+page_number) # print('page num'+str(question[1])) if(question[1] == int(page_number) and exam_id == current_exam_id): # print('matched page:'+ page_number) questionNo = question[0] region = im.crop(question[2:]) # region.show() # sys.exit() try: print(f"reading question no:{questionNo} from region {region}") ans = pytesseract.image_to_string(region, lang= 'eng') except Exception as e: print(f"failed to read question no {questionNo}. error:{str(e)}") # ans = pytesseract.image_to_string(region, lang= 'ger') ans = ans.replace('\n', ' ') student_ans = StudentAns( exam=current_exam, matriculation_num=mat_number, question_num=questionNo, students_ans= ans, ) student_ans.save() ### save students ans to dbase print(student_ans) # studentsAns.append([mat_number, questionNo, ans]) # append student ans in studentAns.json student_ans_file = os.path.join(settings.BASE_DIR, 'studentAns.json') with open(student_ans_file, 'w') as outfile: json.dump(studentsAns, outfile) print('Answers saved successfully.')
def delete_ans(request): """ delete all ans fro the currently selected exam """ if request.method == 'POST': StudentAns.objects.filter(exam=get_exam(request)).delete() return HttpResponseRedirect(reverse('grader:ans_list'))
def auto_grade_all_ans(request, tobe_grade_question=None): """ grade all ans if tobe_grade_question is not passed. else re-grade only passed question in tobe_grade_question """ stemmer = Stemmer() current_exam = get_exam(request) if not tobe_grade_question: questions = Question.objects.filter(exam = current_exam) else: print(tobe_grade_question.question_number) questions = Question.objects.filter(exam=current_exam, question_number=tobe_grade_question.question_number) # create list of tuple containing question num and stems of ans q_num_ans_stem = [(q.question_number, stemmer.sent_2_stem(q.questionAns)) for q in questions] # print(q_num_ans_stem) if not tobe_grade_question: student_ans_list = StudentAns.objects.filter(exam=current_exam) else: student_ans_list = StudentAns.objects.filter(exam=current_exam, question_num=tobe_grade_question.question_number) for student_ans in student_ans_list: question_num = student_ans.question_num print(question_num) current_q_stems = [x[1] for x in q_num_ans_stem if x[0] == question_num] confidence = stemmer.get_confidence(current_q_stems[0], student_ans.students_ans) # print(confidence) student_ans.matching_confidence = confidence question = questions.get(question_number=question_num) if confidence > question.threshold: auto_grade = question.allotedMarks else: auto_grade = 0 student_ans.auto_grade = auto_grade student_ans.save()
def finalize_result(request): exam = get_exam(request) student_anss = StudentAns.objects.filter(exam=exam) for ans in student_anss: if not ans.manually_graded: ans.final_grade = ans.auto_grade ans.save() return HttpResponseRedirect(reverse('grader:ans_list'))
def move_image_to_cleaned_image(self, request, imageName, im, mat_number, page_number): exam_id = get_exam(request).id imName, imExt = imageName.split('.') if(imExt.lower() == 'png' or 'jpg'): newFileName = str(exam_id)+'_'+ mat_number + '_' + str(page_number) + '.' + imExt im.save(os.path.join(self.cleanedPath, newFileName)) #delete image from the raw_image folder os.remove(os.path.join(self.rawPath, imageName)) self.readFileCount += 1 else: print('image must be png or jpg.') self.move_image_to_unread_image(imageName, im)
def update_exam_grade_thresh(request): exam = get_exam(request) if request.method == 'POST': # return HttpResponse("posted") form = ExamGradeUpdateForm(request.POST, instance=exam) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('grader:final_result')) form = ExamGradeUpdateForm(instance=exam) context = { 'form': form, } return render(request, 'grader/exam_grade_update_thresh.html', context)
def processAnsScript(self, request): """ read all images of current exam from raw_image dir. resize them to std a4 size. moved them to cleaned_image dir for further processing. """ images = os.listdir( self.rawPath ) # get this list from db query when images will be uploaded through django for imageName in images: print('new iter', imageName) try: im_exam_id, im_mat_nr, name = imageName.split('_') im_page_nr, im_ext = name.split('.') except Exception as e: print('problem spliting image name in processAnsScript' + str(e)) if (im_exam_id != str(get_exam(request).id)): print('exam_id mismatch') continue fileName = os.path.join(self.rawPath, imageName) with Image.open(fileName) as im: # im = Image.open(fileName) # im = im.convert('L') im = im.resize(self.a4size) if int(im_page_nr) not in range(1, self.totalPage): # move this page to unread image dir, delete image from raw dir and continue to next iteration self.move_image_to_unread_image(imageName, im) # to be done- delete the image from the raw dir print('im_page_nr not in range' + im_page_nr) continue if (im_mat_nr not in self.candidates): print('Mat number not in candidates list. handle excepton') self.move_image_to_unread_image(imageName, im) print('im_mat_nr not in candidate list') continue self.move_image_to_cleaned_image(request, imageName, im, im_mat_nr, im_page_nr) print(str(self.readFileCount) + ' files copied to cleaned dir') print( str(self.unreadFileCount) + ' files couldn\'t read. copied to unread dir') return (self.readFileCount, self.unreadFileCount)
def upload(request): """ upload all scanned image to raw_image dir. exam_id is prefixed to each image before saving. images from this dir will be removed once it is read or failed to read during read action. """ upload_file_count = 0 if request.method == "POST": myfiles = request.FILES.getlist('myfile') # print(myfiles) exam = get_exam(request) for file in myfiles: fs = FileSystemStorage() fs.save('raw_image/' + str(exam.id) + '_' + file.name, file) upload_file_count += 1 context = {'upload_file_count': upload_file_count} return render(request, 'grader/upload_ans_script.html', context) else: context = {} return render(request, 'grader/upload_ans_script.html', context)
def final_result(request): exam = get_exam(request) appeared = StudentAns.objects.filter( exam=exam).values('matriculation_num').distinct() appeared_list = [x['matriculation_num'] for x in appeared] total_appeared = len(appeared_list) grades = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] results = [] for mat_num in appeared_list: achieved_marks = 0 ans_list = StudentAns.objects.filter(exam=exam, matriculation_num=mat_num) for ans in ans_list: achieved_marks += ans.final_grade total_marks = exam.total_marks achieved_percentage = (achieved_marks / total_marks) * 100 if (achieved_percentage < exam.grade_5_0): grade = 5.00 grades[11] += 1 elif (achieved_percentage >= exam.grade_4_0 and achieved_percentage < exam.grade_3_7): grade = 4.00 grades[10] += 1 elif (achieved_percentage >= exam.grade_3_7 and achieved_percentage < exam.grade_3_3): grade = 3.70 grades[9] += 1 elif (achieved_percentage >= exam.grade_3_3 and achieved_percentage < exam.grade_3_0): grade = 3.30 grades[8] += 1 elif (achieved_percentage >= exam.grade_3_0 and achieved_percentage < exam.grade_2_7): grade = 3.00 grades[7] += 1 elif (achieved_percentage >= exam.grade_2_7 and achieved_percentage < exam.grade_2_3): grade = 2.70 grades[6] += 1 elif (achieved_percentage >= exam.grade_2_3 and achieved_percentage < exam.grade_2_0): grade = 2.30 grades[5] += 1 elif (achieved_percentage >= exam.grade_2_0 and achieved_percentage < exam.grade_1_7): grade = 2.00 grades[4] += 1 elif (achieved_percentage >= exam.grade_1_7 and achieved_percentage < exam.grade_1_3): grade = 1.70 grades[3] += 1 elif (achieved_percentage >= exam.grade_1_3 and achieved_percentage < exam.grade_1_0): grade = 1.30 grades[2] += 1 elif (achieved_percentage >= exam.grade_1_0 and achieved_percentage < exam.grade_0_7): grade = 1.00 grades[1] += 1 elif (achieved_percentage >= exam.grade_0_7): grade = 0.70 grades[0] += 1 results.append((mat_num, achieved_marks, achieved_percentage, grade)) count_p_f = [0, 0] for result in results: if result[2] < 5.0: count_p_f[0] += 1 else: count_p_f[1] += 1 context = { 'total_appeared': total_appeared, 'total_marks': total_marks, 'results': results, 'grades': grades, 'count_p_f': count_p_f, } return render(request, 'grader/final_result.html', context)
def ans_details(request, pk=None): """ renders details of an ans with original written subimage """ exam = get_exam(request) # posted from the ans_details page by clicking the next button # check which radio button was selected and set the pk according to that if request.method == 'POST': all_ans = StudentAns.objects.filter(exam=exam) option = request.POST['next_choice'] if (option == 'random'): # iter randomly same_anss = all_ans random_ans = random.choice(same_anss) pk = random_ans.pk elif (option == 'student'): # iter all ans of this student id = request.POST['pk'] current_ans = all_ans.get(pk=id) # get the next ans of this student same_anss = all_ans.filter( exam=exam, matriculation_num=current_ans.matriculation_num) random_ans = random.choice(same_anss) pk = random_ans.pk else: # same question iter for random student id = request.POST['pk'] current_ans = all_ans.get(pk=id) # get a random pk of another ans with same question id same_anss = all_ans.filter(exam=exam, question_num=current_ans.question_num) # print(same_anss) random_ans = random.choice(same_anss) pk = random_ans.pk if pk: student_ans = StudentAns.objects.get(pk=pk) else: # get a random mat num from this exam return HttpResponse( 'did you forget to implement this page without pk url prt') question = get_object_or_404(Question, exam=exam, question_number=student_ans.question_num) page_num = question.page # uncomment the appropriate line to choose the correct img ext. # image_name = str(exam.id) +'_'+ str(student_ans.matriculation_num) +'_'+ str(page_num) + '.png' image_name = str(exam.id) + '_' + str( student_ans.matriculation_num) + '_' + str(page_num) + '.jpg' top_x = question.topLeftX top_y = question.topLeftY bottom_x = question.bottomRightX bottom_y = question.bottomRightY # get the related image crop the specific part and pass to template as base64 encoded data img_path = os.path.join(settings.MEDIA_ROOT, 'cleaned_image', image_name) try: img = cv.imread(img_path) sub_img = img[top_y:bottom_y, top_x:bottom_x] ret, frame_buff = cv.imencode('.png', sub_img) frame_b64 = base64.b64encode(frame_buff) frame_b64 = frame_b64.decode('utf8') # raise ValueError('subimage not found') except Exception as e: # return HttpResponse("could not read the subimage. check img ext on line 184/185." + str(e)) frame_b64 = None # print(frame_b64) context = { 'exam': exam, 'pk': pk, 'student_ans': student_ans, 'img': frame_b64, 'question': question, } return render(request, 'grader/ans_details.html', context)