v2 - 검수중 (하이퍼링크 처리구문 추가)
This commit is contained in:
129
diwScoring2.py
129
diwScoring2.py
@@ -43,7 +43,7 @@ class XMLScorer:
|
||||
return pt
|
||||
|
||||
# 유사한 텍스트 찾기
|
||||
def find_similar_text(self, root, target_text, threshold=0.7):
|
||||
def find_similar_text(self, root, chart_tree, target_text, threshold=0.7):
|
||||
"""
|
||||
전체 문서에서 유사한 텍스트를 찾아 반환
|
||||
|
||||
@@ -64,7 +64,10 @@ class XMLScorer:
|
||||
'c': 'http://schemas.openxmlformats.org/drawingml/2006/chart'
|
||||
}
|
||||
|
||||
all_text = root.xpath(f"//BODY//text() | //TEXTART/@Text | //c:chart//text()", namespaces=namespaces)
|
||||
hwp_text = root.xpath(f"//BODY//text() | //TEXTART/@Text")
|
||||
chart_text = chart_tree.xpath(f"//c:chart//text()", namespaces=namespaces) if chart_tree is not None else []
|
||||
|
||||
all_text = hwp_text + chart_text
|
||||
|
||||
# 유사도 비교
|
||||
max_score = 0
|
||||
@@ -161,7 +164,7 @@ class XMLScorer:
|
||||
# search_value가 있는 경우
|
||||
if search_value is not None:
|
||||
# search_value를 포함하는 텍스트 찾기
|
||||
similar_text = self.find_similar_text(root, search_value)
|
||||
similar_text = self.find_similar_text(root, chart_tree, search_value)
|
||||
xpath = xpath.replace('{searchValue}', similar_text) if xpath else ""
|
||||
xpath2 = xpath2.replace('{searchValue}', similar_text) if xpath2 else ""
|
||||
chart_xpath = chart_xpath.replace('{searchValue}', similar_text) if chart_xpath else ""
|
||||
@@ -237,6 +240,23 @@ class XMLScorer:
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
|
||||
# 1, 2페이지 모두 정답이어야 함
|
||||
elif (category or "") == "PageNumber":
|
||||
items = root.xpath(xpath) if xpath else []
|
||||
|
||||
all_match = True
|
||||
for item in chain(items):
|
||||
user_answer = item
|
||||
if right_answer != user_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 (category or "") == "오타감점":
|
||||
points = self.get_typo_score()
|
||||
@@ -388,9 +408,10 @@ class XMLScorer:
|
||||
if right_answer in ["견고딕", "중고딕"]:
|
||||
user_answer = user_answer.replace("한양", "")
|
||||
|
||||
# 하나라도 다르면 바로 오답 처리
|
||||
if user_answer != right_answer:
|
||||
all_match = False
|
||||
break # 하나라도 다르면 바로 오답 처리
|
||||
break
|
||||
|
||||
if all_match:
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
@@ -399,18 +420,96 @@ class XMLScorer:
|
||||
|
||||
# 폰트 속성
|
||||
elif (category or "") == "FontAttribute":
|
||||
charshape = root.xpath(xpath)
|
||||
if not charshape:
|
||||
charshape = None
|
||||
user_answer = None
|
||||
else:
|
||||
font_attribute = charshape[0].find(right_answer)
|
||||
if font_attribute is not None:
|
||||
user_answer = font_attribute.tag
|
||||
else:
|
||||
user_answer = None
|
||||
# 하이퍼링크 처리
|
||||
hyperlink_ptag = criterion.get('hyperlink_ptag', None)
|
||||
has_ptag = root.xpath(hyperlink_ptag) if hyperlink_ptag else False
|
||||
|
||||
# hyperlink가 아닌 경우(일반적인 텍스트 일 경우)
|
||||
if not has_ptag:
|
||||
charshape = root.xpath(xpath)
|
||||
if not charshape:
|
||||
charshape = None
|
||||
user_answer = None
|
||||
else:
|
||||
font_attribute = charshape[0].find(right_answer)
|
||||
if font_attribute is not None:
|
||||
user_answer = font_attribute.tag
|
||||
else:
|
||||
user_answer = None
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
|
||||
# 하이퍼링크인 경우
|
||||
elif has_ptag:
|
||||
hyperlink_text = search_value.replace(" ", "")
|
||||
|
||||
p_elements = has_ptag
|
||||
|
||||
for p in p_elements:
|
||||
text_list = p.xpath(".//CHAR/text()")
|
||||
full_text = ''.join(text_list).replace(" ", "")
|
||||
# print("full_text: ", full_text)
|
||||
|
||||
# 채점하고자 하는 문자열 (search_value)의 첫 문자
|
||||
first_char = search_value[0]
|
||||
|
||||
# 수험자 답안에서 첫 문자 인덱스 위치
|
||||
user_answer_first_index = full_text.find(first_char)
|
||||
|
||||
if user_answer_first_index != -1:
|
||||
# 수험자 답안에서 첫 문자 인덱스 위치부터 search_value 길이만큼 잘라서 비교
|
||||
trimmed_full_text = full_text[user_answer_first_index:]
|
||||
else:
|
||||
trimmed_full_text = full_text
|
||||
|
||||
# 두 문자열의 유사도 계산
|
||||
similarity = difflib.SequenceMatcher(None, trimmed_full_text, hyperlink_text).ratio()
|
||||
|
||||
# 두 문자열의 유사도에 따라 하이퍼링크 확인
|
||||
# 유사도가 낮은 경우 오답처리
|
||||
if similarity < 0.7:
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, 0, method="equal")
|
||||
|
||||
# 유사도가 높은 경우
|
||||
else:
|
||||
inside_field = False
|
||||
charshape_list = []
|
||||
|
||||
for elem in p.iter():
|
||||
# 시작 지점 확인
|
||||
if elem.tag == "FIELDBEGIN":
|
||||
inside_field = True
|
||||
elif elem.tag == "FIELDEND":
|
||||
inside_field = False
|
||||
elif inside_field and elem.tag == "TEXT":
|
||||
charshape = elem.get("CharShape")
|
||||
if charshape:
|
||||
charshape_list.append(charshape)
|
||||
|
||||
# 하이퍼링크에 해당하는 P태그 내 존재하는 charshape ID값 모두를 비교해 해당 속성(ITALIC, BOLD, UNDERLINE) 확인
|
||||
# 모든 charshape ID값이 정답과 일치하는 경우에만 점수 부여
|
||||
all_attributes_match = True
|
||||
if charshape_list:
|
||||
for charshape_id in charshape_list:
|
||||
charshape = root.xpath(f"//CHARSHAPE[@Id='{charshape_id}']")
|
||||
|
||||
# 속성 태그가 존재하는지 확인
|
||||
font_attribute = charshape[0].find(right_answer)
|
||||
if font_attribute is None:
|
||||
user_answer = None
|
||||
all_attributes_match = False
|
||||
break
|
||||
|
||||
else:
|
||||
user_answer = font_attribute.tag
|
||||
|
||||
if all_attributes_match:
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
else:
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, 0, method="equal")
|
||||
|
||||
|
||||
|
||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||
|
||||
# 특수문자 갯수 채점
|
||||
elif (category or "") == "SpecialChar":
|
||||
|
||||
Reference in New Issue
Block a user