v2 - 문제2 45문항
This commit is contained in:
130
diwScoring2.py
130
diwScoring2.py
@@ -11,6 +11,8 @@ from difflib import SequenceMatcher
|
||||
import pandas as pd
|
||||
import base64
|
||||
import math
|
||||
from itertools import chain
|
||||
|
||||
# from xpathSearch import XMLPathHandler
|
||||
|
||||
class XMLScorer:
|
||||
@@ -202,6 +204,7 @@ class XMLScorer:
|
||||
points = criterion.get('points', 0)
|
||||
category = criterion.get('category', None)
|
||||
item = criterion.get('item', None)
|
||||
option = criterion.get('option', None)
|
||||
similar_text = None
|
||||
|
||||
# search_value가 있는 경우
|
||||
@@ -211,7 +214,11 @@ class XMLScorer:
|
||||
xpath = xpath.replace('{searchValue}', similar_text)
|
||||
if xpath2 is not None:
|
||||
xpath2 = xpath2.replace('{searchValue}', similar_text)
|
||||
|
||||
|
||||
if option:
|
||||
xpath = xpath.replace('{option}', option) if xpath else ""
|
||||
xpath2 = xpath2.replace('{option}', option) if xpath2 else ""
|
||||
|
||||
# 문항 별 채점 결과 저장
|
||||
scoring = {
|
||||
'section': section_id,
|
||||
@@ -224,7 +231,7 @@ class XMLScorer:
|
||||
'deductions': [] # 각 기준별 감점 내역
|
||||
}
|
||||
|
||||
if "PageSetting" in (category or ""):
|
||||
if (category or "") == "PageSetting":
|
||||
items = root.xpath(xpath)
|
||||
error_range = criterion.get('tolerance', 0)
|
||||
|
||||
@@ -244,7 +251,7 @@ class XMLScorer:
|
||||
if scoring['points'] > 0:
|
||||
break
|
||||
|
||||
elif "BasicSetting" in (category or ""):
|
||||
elif (category or "") == "BasicSetting":
|
||||
# 바탕글(기본설정) 요소
|
||||
normal_style = root.xpath("//STYLE[@Name='바탕글']")
|
||||
|
||||
@@ -277,17 +284,18 @@ class XMLScorer:
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
|
||||
# 오타 감점 부분은 미리 계산 하고, 이후 점수만 계산
|
||||
elif "오타감점" in (category or ""):
|
||||
elif (category or "") == "오타감점":
|
||||
points = self.get_typo_score()
|
||||
self.total_score += points
|
||||
self.partial_score += points
|
||||
scoring['points'] = points
|
||||
|
||||
# 정답이 하나인 경우
|
||||
elif "SingleAnswer" in (category or ""):
|
||||
elif (category or "") == "OneAnswer":
|
||||
items = root.xpath(xpath)
|
||||
items2 = root.xpath(xpath2) if xpath2 else []
|
||||
|
||||
for item in items:
|
||||
for item in chain(items, items2):
|
||||
user_answer = item
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points)
|
||||
@@ -295,24 +303,21 @@ class XMLScorer:
|
||||
if scoring['points'] > 0:
|
||||
break
|
||||
|
||||
elif "DoubleAnswer" in (category or ""):
|
||||
elif (category or "") == "DoubleAnswer":
|
||||
items1 = root.xpath(xpath)
|
||||
items2 = root.xpath(xpath2)
|
||||
items2 = root.xpath(xpath2) if xpath else []
|
||||
|
||||
user_answer = []
|
||||
for item1, item2 in zip(items1, items2):
|
||||
user_answer.append(item1)
|
||||
user_answer.append(item2)
|
||||
# user_answer[0] = item1
|
||||
# user_answer[1] = item2
|
||||
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points)
|
||||
if scoring['points'] > 0:
|
||||
break
|
||||
|
||||
|
||||
# 사용자 입력값이 mm단위인 경우
|
||||
elif "mmSize" in (category or ""):
|
||||
elif (category or "") == "mmSize":
|
||||
items = root.xpath(xpath)
|
||||
error_range = criterion.get('tolerance', 0)
|
||||
|
||||
@@ -325,7 +330,7 @@ class XMLScorer:
|
||||
if scoring['points'] > 0:
|
||||
break
|
||||
|
||||
elif "ParaShape" in (category or ""):
|
||||
elif (category or "") == "ParaShape":
|
||||
items = root.xpath(xpath)
|
||||
|
||||
for item in items:
|
||||
@@ -341,7 +346,7 @@ class XMLScorer:
|
||||
break
|
||||
|
||||
# Boolean 타입 정답인 경우
|
||||
elif "Boolean" in (category or ""):
|
||||
elif (category or "") == "Boolean":
|
||||
items = root.xpath(xpath)
|
||||
items2 = root.xpath(xpath2) if xpath2 else False
|
||||
|
||||
@@ -350,23 +355,23 @@ class XMLScorer:
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points)
|
||||
|
||||
# 채점기준표 파일에 작성된 rgb값을 그대로 읽어와 HML파일 요소의 int형 rgb값과 비교
|
||||
elif "Color" in (category or ""):
|
||||
items = root.xpath(xpath)
|
||||
elif (category or "") == "Color":
|
||||
items = root.xpath(xpath) if xpath else []
|
||||
items2 = root.xpath(xpath2) if xpath2 else []
|
||||
|
||||
rgb_text = right_answer
|
||||
r, g, b = map(int, rgb_text.split(','))
|
||||
rgb_int = (b << 16) + (g << 8) + r
|
||||
|
||||
for item in items:
|
||||
# items, items2를 순차적으로 순회
|
||||
for item in chain(items, items2):
|
||||
user_answer = int(item)
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, rgb_int, points, method="equal")
|
||||
|
||||
if scoring['points'] > 0:
|
||||
break
|
||||
|
||||
# 문단 첫글자 장식 채점
|
||||
elif "TwoLineSize" in (category or ""):
|
||||
elif (category or "") == "TwoLineSize":
|
||||
items = root.xpath(xpath)
|
||||
error_range = criterion.get('tolerance', 0)
|
||||
for item in items:
|
||||
@@ -380,26 +385,60 @@ class XMLScorer:
|
||||
break
|
||||
|
||||
# 폰트명
|
||||
elif "FontName" in (category or ""):
|
||||
charshape_id = root.xpath(xpath)
|
||||
elif (category or "") == "FontName":
|
||||
charshape_list = root.xpath(xpath)
|
||||
if not charshape_id:
|
||||
charshape_id = None
|
||||
user_answer = None
|
||||
user_answer = ""
|
||||
else:
|
||||
font_id = root.xpath(f"//CHARSHAPE[@Id='{charshape_id[0]}']/FONTID/@Hangul")
|
||||
font_name = root.xpath(f"//FONTFACE[@Lang='Hangul']/FONT[@Id='{font_id[0]}']/@Name")
|
||||
user_answer = font_name[0]
|
||||
for charshape_id in charshape_list:
|
||||
font_id = root.xpath(f"//CHARSHAPE[@Id='{charshape_id}']/FONTID/@Hangul")
|
||||
font_name = root.xpath(f"//FONTFACE[@Lang='Hangul']/FONT[@Id='{font_id[0]}']/@Name")
|
||||
user_answer = font_name[0]
|
||||
|
||||
# 폰트 "견고딕"과 "중고딕"은
|
||||
# 한글프로그램 내부적으로 "한양견고딕", "한양중고딕"으로 저장되므로
|
||||
# 수험자 답변에서 "한양"을 제거
|
||||
if right_answer in ["견고딕", "중고딕"]:
|
||||
user_answer = user_answer.replace("한양", "")
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
|
||||
if scoring['points'] > 0:
|
||||
break
|
||||
|
||||
# 폰트 "견고딕"과 "중고딕"은
|
||||
# 한글프로그램 내부적으로 "한양견고딕", "한양중고딕"으로 저장되므로
|
||||
# 수험자 답변에서 "한양"을 제거
|
||||
if right_answer in ["견고딕", "중고딕"]:
|
||||
user_answer = user_answer.replace("한양", "")
|
||||
# 테이블 폰트명
|
||||
# 테이블 내부 모든 셀의 폰트가 정답과 일치해야 함
|
||||
elif (category or "") == "TableFontName":
|
||||
charshape_list = root.xpath(xpath)
|
||||
|
||||
# 문자속성이 없는 경우
|
||||
if not charshape_list:
|
||||
user_answer = ""
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
else:
|
||||
all_match = True # 모든 항목이 정답과 일치해야 함
|
||||
|
||||
for charshape_id in charshape_list:
|
||||
font_id = root.xpath(f"//CHARSHAPE[@Id='{charshape_id}']/FONTID/@Hangul")
|
||||
font_name = root.xpath(f"//FONTFACE[@Lang='Hangul']/FONT[@Id='{font_id[0]}']/@Name")
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
user_answer = font_name[0]
|
||||
|
||||
# 내부 저장된 접두어 제거
|
||||
if right_answer in ["견고딕", "중고딕"]:
|
||||
user_answer = user_answer.replace("한양", "")
|
||||
|
||||
if user_answer != right_answer:
|
||||
all_match = False
|
||||
break # 하나라도 다르면 바로 오답 처리
|
||||
|
||||
if all_match:
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
else:
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, 0, method="equal") # 오답 처리
|
||||
|
||||
# 폰트 속성
|
||||
elif "FontAttribute" in (category or ""):
|
||||
elif (category or "") == "FontAttribute":
|
||||
charshape = root.xpath(xpath)
|
||||
if not charshape:
|
||||
charshape = None
|
||||
@@ -491,6 +530,7 @@ class XMLScorer:
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
|
||||
# 한자
|
||||
elif "Hanja" in (category or ""):
|
||||
word_list = criterion.get('word', [])
|
||||
|
||||
@@ -516,9 +556,27 @@ class XMLScorer:
|
||||
user_answer = min(score, max_score)
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="partial_score")
|
||||
|
||||
|
||||
elif (category or "") == "chart_type":
|
||||
chart_type_list = {
|
||||
'꺾은선형': "//c:lineChart",
|
||||
'가로막대형': "//c:barChart[c:barDir[@val='bar']]",
|
||||
'세로막대형': "//c:barChart[c:barDir[@val='col']]",
|
||||
'원형': "//c:pieChart",
|
||||
'분산형': "//c:scatterChart"
|
||||
}
|
||||
chart_type = criterion.get('chart_type').replace(" ","")
|
||||
if "묶은" in chart_type:
|
||||
chart_type = chart_type.replace("묶은", "")
|
||||
chart_xpath = chart_type_list[chart_type]
|
||||
|
||||
user_answer = bool(chart_tree.xpath(chart_xpath, namespaces=namespaces))
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points)
|
||||
|
||||
# 문항 채점 결과를 리스트에 입력
|
||||
onePersonResult['score_results'].append(scoring)
|
||||
print(f'scoring: {scoring}')
|
||||
|
||||
onePersonResult['partial_scores'].append({
|
||||
'section': section_id,
|
||||
'score': self.partial_score
|
||||
|
||||
Reference in New Issue
Block a user