Exemple #1
0
 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)
Exemple #2
0
 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]
Exemple #3
0
    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.')
Exemple #4
0
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'))
Exemple #5
0
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()
Exemple #6
0
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'))
Exemple #7
0
 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)
Exemple #8
0
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)
Exemple #9
0
    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)
Exemple #10
0
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)
Exemple #11
0
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)
Exemple #12
0
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)