2505회 [1-17,18] 하이퍼링크관련 채점기준수정, [2-17] 이미지 삽입 부분 '글저처럼취급', '쪽' 조건 수정
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
250604_DIW_2505C_TEST.xlsx
Normal file
BIN
250604_DIW_2505C_TEST.xlsx
Normal file
Binary file not shown.
BIN
250604_DIW_2505C_채점결과.xlsx
Normal file
BIN
250604_DIW_2505C_채점결과.xlsx
Normal file
Binary file not shown.
@@ -454,14 +454,14 @@
|
|||||||
"item": "③ 크기-높이 (40 mm)"
|
"item": "③ 크기-높이 (40 mm)"
|
||||||
},
|
},
|
||||||
"17": {
|
"17": {
|
||||||
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION/@HorzOffset",
|
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION[not(@TreatAsChar='true') and @HorzRelTo='Page']/@HorzOffset",
|
||||||
"value": "0",
|
"value": "0",
|
||||||
"points": 2,
|
"points": 2,
|
||||||
"category": "mmSize",
|
"category": "mmSize",
|
||||||
"item": "④ 위치 (어울림 : 가로-쪽의 왼쪽 0.0mm)"
|
"item": "④ 위치 (어울림 : 가로-쪽의 왼쪽 0.0mm)"
|
||||||
},
|
},
|
||||||
"18": {
|
"18": {
|
||||||
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION/@VertOffset",
|
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION[not(@TreatAsChar='true') and @HorzRelTo='Page']/@VertOffset",
|
||||||
"value": "23",
|
"value": "23",
|
||||||
"points": 2,
|
"points": 2,
|
||||||
"category": "mmSize",
|
"category": "mmSize",
|
||||||
|
|||||||
@@ -456,14 +456,14 @@
|
|||||||
"item": "③ 크기-높이 (40 mm)"
|
"item": "③ 크기-높이 (40 mm)"
|
||||||
},
|
},
|
||||||
"17": {
|
"17": {
|
||||||
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION/@HorzOffset",
|
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION[not(@TreatAsChar='true') and @HorzRelTo='Page']/@HorzOffset",
|
||||||
"value": "0",
|
"value": "0",
|
||||||
"points": 2,
|
"points": 2,
|
||||||
"category": "mmSize",
|
"category": "mmSize",
|
||||||
"item": "④ 위치 (어울림 : 가로-쪽의 왼쪽 0.0mm)"
|
"item": "④ 위치 (어울림 : 가로-쪽의 왼쪽 0.0mm)"
|
||||||
},
|
},
|
||||||
"18": {
|
"18": {
|
||||||
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION/@VertOffset",
|
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION[not(@TreatAsChar='true') and @HorzRelTo='Page']/@VertOffset",
|
||||||
"value": "24",
|
"value": "24",
|
||||||
"points": 2,
|
"points": 2,
|
||||||
"category": "mmSize",
|
"category": "mmSize",
|
||||||
|
|||||||
@@ -456,14 +456,14 @@
|
|||||||
"item": "③ 크기-높이 (40 mm)"
|
"item": "③ 크기-높이 (40 mm)"
|
||||||
},
|
},
|
||||||
"17": {
|
"17": {
|
||||||
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION/@HorzOffset",
|
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION[not(@TreatAsChar='true') and @HorzRelTo='Page']/@HorzOffset",
|
||||||
"value": "0",
|
"value": "0",
|
||||||
"points": 2,
|
"points": 2,
|
||||||
"category": "mmSize",
|
"category": "mmSize",
|
||||||
"item": "④ 위치 (어울림 : 가로-쪽의 왼쪽 0.0mm)"
|
"item": "④ 위치 (어울림 : 가로-쪽의 왼쪽 0.0mm)"
|
||||||
},
|
},
|
||||||
"18": {
|
"18": {
|
||||||
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION/@VertOffset",
|
"path": "//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION[not(@TreatAsChar='true') and @HorzRelTo='Page']/@VertOffset",
|
||||||
"value": "24",
|
"value": "24",
|
||||||
"points": 2,
|
"points": 2,
|
||||||
"category": "mmSize",
|
"category": "mmSize",
|
||||||
|
|||||||
@@ -126,6 +126,19 @@ class XMLScorer:
|
|||||||
|
|
||||||
# 하나의 XML 파일 채점
|
# 하나의 XML 파일 채점
|
||||||
def _score_xml_file(self, xml_file, chart_xml):
|
def _score_xml_file(self, xml_file, chart_xml):
|
||||||
|
|
||||||
|
def extract_char_text_from_p(p_element):
|
||||||
|
"""
|
||||||
|
주어진 <P> 요소에서 모든 자손 <CHAR>의 텍스트를 추출해 문자열 리스트로 반환합니다.
|
||||||
|
"""
|
||||||
|
full_text = []
|
||||||
|
for p in p_element:
|
||||||
|
char_elements = p.xpath('.//CHAR')
|
||||||
|
combined_text = ''.join([char.text for char in char_elements if char.text])
|
||||||
|
no_space_text = re.sub(r'\s+', '', combined_text) # 공백 문자 제거
|
||||||
|
full_text.append(no_space_text)
|
||||||
|
return full_text
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tree = ET.parse(xml_file)
|
tree = ET.parse(xml_file)
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
@@ -373,6 +386,7 @@ class XMLScorer:
|
|||||||
elif (category or "") == "mmSize":
|
elif (category or "") == "mmSize":
|
||||||
items = root.xpath(xpath)
|
items = root.xpath(xpath)
|
||||||
|
|
||||||
|
|
||||||
# 오차범위 설정
|
# 오차범위 설정
|
||||||
# 한글 프로그램 내부에서 드물게 0mm이지만 1pt로 저장되는 경우가 있음
|
# 한글 프로그램 내부에서 드물게 0mm이지만 1pt로 저장되는 경우가 있음
|
||||||
#
|
#
|
||||||
@@ -385,13 +399,16 @@ class XMLScorer:
|
|||||||
float_string = right_answer.strip().replace("mm", "")
|
float_string = right_answer.strip().replace("mm", "")
|
||||||
right_answer = self.convert_mm_to_pt(float(float_string))
|
right_answer = self.convert_mm_to_pt(float(float_string))
|
||||||
|
|
||||||
for item in items:
|
if not items:
|
||||||
user_answer = float(item)
|
scoring['points'] = 0
|
||||||
|
else:
|
||||||
|
for item in items:
|
||||||
|
user_answer = float(item)
|
||||||
|
|
||||||
self.evaluate_answer(scoring, user_answer, right_answer, points, method="tolerance", tolerance=error_range)
|
self.evaluate_answer(scoring, user_answer, right_answer, points, method="tolerance", tolerance=error_range)
|
||||||
|
|
||||||
if scoring['points'] > 0:
|
if scoring['points'] > 0:
|
||||||
break
|
break
|
||||||
|
|
||||||
elif (category or "") == "ParaShape":
|
elif (category or "") == "ParaShape":
|
||||||
items = root.xpath(xpath)
|
items = root.xpath(xpath)
|
||||||
@@ -505,11 +522,27 @@ class XMLScorer:
|
|||||||
# 폰트 속성
|
# 폰트 속성
|
||||||
elif (category or "") == "FontAttribute":
|
elif (category or "") == "FontAttribute":
|
||||||
# 하이퍼링크 처리
|
# 하이퍼링크 처리
|
||||||
hyperlink_ptag = criterion.get('hyperlink_ptag', None)
|
|
||||||
has_hyperlink_ptag = root.xpath(hyperlink_ptag) if hyperlink_ptag else False
|
# 1. 하이퍼링크를 포함하는 P요소를 가져옴
|
||||||
|
# 2. 그 P요소의 자손 CHAR태그에 있는 텍스트를 하나의 문자열로 변환
|
||||||
|
# 3. P요소의 문자열과 채점하려는 문자열이 일치하는지 확인
|
||||||
|
hyperlink_xpath = criterion.get('hyperlink_ptag', None)
|
||||||
|
hyperlink_ptag = root.xpath(hyperlink_xpath) if hyperlink_xpath else None
|
||||||
|
|
||||||
|
p_tag_text_list = extract_char_text_from_p(hyperlink_ptag) if hyperlink_ptag else []
|
||||||
|
hyperlink_text = search_value.replace(" ", "") if search_value else ""
|
||||||
|
|
||||||
|
# search_value가 hyperlink문자열에 포함되어 있는지 확인
|
||||||
|
# search_value가 hyperlink인 경우와 아닌경우를 구분해 채점
|
||||||
|
search_in_hyperlink = False
|
||||||
|
if hyperlink_text and any(hyperlink_text in text for text in p_tag_text_list):
|
||||||
|
search_in_hyperlink = True
|
||||||
|
else:
|
||||||
|
search_in_hyperlink = False
|
||||||
|
|
||||||
# hyperlink가 아닌 경우(일반적인 텍스트 일 경우)
|
# hyperlink가 아닌 경우(일반적인 텍스트 일 경우)
|
||||||
if not has_hyperlink_ptag:
|
# 하이퍼링크를 포함한 P태그가 없거나 search_value값이 하이퍼링크텍스트에 포함되어 있지 않을 경우
|
||||||
|
if not hyperlink_ptag or not search_in_hyperlink:
|
||||||
charshape_list = root.xpath(xpath)
|
charshape_list = root.xpath(xpath)
|
||||||
if not charshape_list:
|
if not charshape_list:
|
||||||
charshape = None
|
charshape = None
|
||||||
@@ -528,10 +561,9 @@ class XMLScorer:
|
|||||||
break
|
break
|
||||||
|
|
||||||
# 하이퍼링크인 경우
|
# 하이퍼링크인 경우
|
||||||
elif has_hyperlink_ptag:
|
# elif hyperlink_ptag and search_in_hyperlink:
|
||||||
hyperlink_text = search_value.replace(" ", "")
|
else:
|
||||||
|
p_elements = hyperlink_ptag
|
||||||
p_elements = has_hyperlink_ptag
|
|
||||||
|
|
||||||
for p in p_elements:
|
for p in p_elements:
|
||||||
# 수험자가 입력한 텍스트 중 하이퍼링크가 들어간 문단의 모든 텍스트를 가져와
|
# 수험자가 입력한 텍스트 중 하이퍼링크가 들어간 문단의 모든 텍스트를 가져와
|
||||||
@@ -1050,13 +1082,13 @@ def main():
|
|||||||
# 채점하고자 하는 유형은 주석 해제
|
# 채점하고자 하는 유형은 주석 해제
|
||||||
exam_types = [
|
exam_types = [
|
||||||
# 'A',
|
# 'A',
|
||||||
'B',
|
# 'B',
|
||||||
# 'C',
|
'C',
|
||||||
# 'D',
|
# 'D',
|
||||||
]
|
]
|
||||||
|
|
||||||
test_mode = False
|
# test_mode = False
|
||||||
# test_mode = True #/TEST 폴더 채점시
|
test_mode = True #/TEST 폴더 채점시
|
||||||
|
|
||||||
output_excel_paths = []
|
output_excel_paths = []
|
||||||
for exam_type in exam_types:
|
for exam_type in exam_types:
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
[{"kind":2,"language":"xpath","value":"//a:t[text()='클라우드 보안투자']/ancestor::a:r//a:ea/@typeface"},{"kind":2,"language":"xpath","value":"boolean(//FONTFACE[@Lang='Hangul']/FONT[@Id=//CHARSHAPE/FONTID/@Hangul]/@Name='바탕' and //CHARSHAPE/@Height='1000' and //PARASHAPE/PARAMARGIN/@LineSpacing='160' and //PARASHAPE/@Align='Justify')"},{"kind":2,"language":"xpath","value":"//FONTFACE[@Lang='Hangul']/FONT[@Id=//CHARSHAPE/FONTID/@Hangul]/@Name='바탕'"},{"kind":2,"language":"xpath","value":"//FONTFACE[@Lang='Hangul']/FONT[@Id=//CHARSHAPE/FONTID/@Hangul]/@Name='바탕' and //CHARSHAPE/@Height='1000' and //PARASHAPE/PARAMARGIN/@LineSpacing='160' and //PARASHAPE/@Align='Justify')"},{"kind":2,"language":"xpath","value":"//FONTFACE[@Lang='Hangul']/FONT/@Name"},{"kind":2,"language":"xpath","value":"//CHARSHAPE/@Height"},{"kind":2,"language":"xpath","value":"//c:valAx//a:defRPr/@sz"},{"kind":2,"language":"xpath","value":"//c:catAx/c:txPr//a:defRPr/@i"},{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//TABLE/ROW[1]/CELL/@BorderFill]/BOTTOMBORDER/@Width"}]
|
[{"kind":2,"language":"xpath","value":"//a:t[text()='클라우드 보안투자']/ancestor::a:r//a:ea/@typeface"},{"kind":2,"language":"xpath","value":"boolean(//FONTFACE[@Lang='Hangul']/FONT[@Id=//CHARSHAPE/FONTID/@Hangul]/@Name='바탕' and //CHARSHAPE/@Height='1000' and //PARASHAPE/PARAMARGIN/@LineSpacing='160' and //PARASHAPE/@Align='Justify')"},{"kind":2,"language":"xpath","value":"//FONTFACE[@Lang='Hangul']/FONT[@Id=//CHARSHAPE/FONTID/@Hangul]/@Name='바탕'"},{"kind":2,"language":"xpath","value":"//FONTFACE[@Lang='Hangul']/FONT[@Id=//CHARSHAPE/FONTID/@Hangul]/@Name='바탕' and //CHARSHAPE/@Height='1000' and //PARASHAPE/PARAMARGIN/@LineSpacing='160' and //PARASHAPE/@Align='Justify')"},{"kind":2,"language":"xpath","value":"//FONTFACE[@Lang='Hangul']/FONT/@Name"},{"kind":2,"language":"xpath","value":"//CHARSHAPE/@Height"},{"kind":2,"language":"xpath","value":"//P[.//FIELDBEGIN[@Type='Hyperlink'] and .//CHAR[contains(., 'http')]]"},{"kind":2,"language":"xpath","value":"//P[.//FIELDBEGIN[@Type='Hyperlink'] and .//CHAR[contains(., 'http')]]"},{"kind":2,"language":"xpath","value":"//PICTURE[./IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]]/SHAPEOBJECT/POSITION[not(@TreatAsChar='true')]/@HorzOffset"},{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//TABLE/ROW[1]/CELL/@BorderFill]/BOTTOMBORDER/@Width"}]
|
||||||
Reference in New Issue
Block a user