2505회 [2-3] 다단문항 수정
This commit is contained in:
BIN
250610_DIW_2505A_TEST.xlsx
Normal file
BIN
250610_DIW_2505A_TEST.xlsx
Normal file
Binary file not shown.
BIN
250610_DIW_2505A_채점결과.xlsx
Normal file
BIN
250610_DIW_2505A_채점결과.xlsx
Normal file
Binary file not shown.
BIN
250611_DIW_2505A_TEST.xlsx
Normal file
BIN
250611_DIW_2505A_TEST.xlsx
Normal file
Binary file not shown.
BIN
250611_DIW_2505A_채점결과.xlsx
Normal file
BIN
250611_DIW_2505A_채점결과.xlsx
Normal file
Binary file not shown.
@@ -315,7 +315,7 @@
|
|||||||
"value": "200",
|
"value": "200",
|
||||||
"points": 2,
|
"points": 2,
|
||||||
"category": "LineSpacing",
|
"category": "LineSpacing",
|
||||||
"item": "문제 1 줄간격 180% 설정",
|
"item": "문제 1 줄간격 200% 설정",
|
||||||
"desc": "1페이지 문단의 줄간격이 정답이 아닌 문단이 있으면 False(감점)"
|
"desc": "1페이지 문단의 줄간격이 정답이 아닌 문단이 있으면 False(감점)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -340,7 +340,7 @@
|
|||||||
"desc": "섹션이 1개 이상이면 점수부여"
|
"desc": "섹션이 1개 이상이면 점수부여"
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"path": "//COLDEF/@Count",
|
"path": "//COLDEF",
|
||||||
"value": "2",
|
"value": "2",
|
||||||
"points": 3,
|
"points": 3,
|
||||||
"category": "TwoColumn",
|
"category": "TwoColumn",
|
||||||
|
|||||||
@@ -342,10 +342,10 @@
|
|||||||
"desc": "섹션이 1개 이상이면 점수부여"
|
"desc": "섹션이 1개 이상이면 점수부여"
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"path": "//COLDEF/@Count",
|
"path": "//COLDEF",
|
||||||
"value": "2",
|
"value": "2",
|
||||||
"points": 3,
|
"points": 3,
|
||||||
"category": "OneAnswer",
|
"category": "TwoColumn",
|
||||||
"item": "② 다단 2단"
|
"item": "② 다단 2단"
|
||||||
},
|
},
|
||||||
"4": {
|
"4": {
|
||||||
|
|||||||
@@ -342,10 +342,10 @@
|
|||||||
"desc": "섹션이 1개 이상이면 점수부여"
|
"desc": "섹션이 1개 이상이면 점수부여"
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"path": "//COLDEF/@Count",
|
"path": "//COLDEF",
|
||||||
"value": "2",
|
"value": "2",
|
||||||
"points": 3,
|
"points": 3,
|
||||||
"category": "OneAnswer",
|
"category": "TwoColumn",
|
||||||
"item": "② 다단 2단"
|
"item": "② 다단 2단"
|
||||||
},
|
},
|
||||||
"4": {
|
"4": {
|
||||||
|
|||||||
111
diwScoring2.py
111
diwScoring2.py
@@ -773,21 +773,46 @@ class XMLScorer:
|
|||||||
|
|
||||||
# 다단 확인 [2-3]문항
|
# 다단 확인 [2-3]문항
|
||||||
elif (category or "") == "TwoColumn":
|
elif (category or "") == "TwoColumn":
|
||||||
|
|
||||||
has_section2 = root.xpath('//SECTION[2]')
|
has_section2 = root.xpath('//SECTION[2]')
|
||||||
|
|
||||||
|
# 구역 나눔이 적용 되어 있지 않은 경우
|
||||||
|
# (= SECTION[2]가 없을 경우)
|
||||||
if not has_section2:
|
if not has_section2:
|
||||||
# //P//COLDEF/@Count 속성이 시작하는 P태그 부터
|
|
||||||
# @Count 속성이 변한 P태그 이전인덱스 까지가 페이지 단수가 적용되어있는 구간
|
|
||||||
|
|
||||||
# 모든 <P> 요소 가져오기
|
# 모든 <P> 요소 가져오기
|
||||||
p_elements = root.xpath('//P')
|
p_elements = root.xpath('//SECTION/P')
|
||||||
|
|
||||||
# 구간 결과를 저장할 리스트
|
# PageBreak='true' 속성을 가진 P태그 인덱스
|
||||||
sections = []
|
# [=쪽나눔 이후 페이지의 첫 문단들]
|
||||||
|
pagebreak_index_list = []
|
||||||
|
for i, p in enumerate(p_elements):
|
||||||
|
xml_index = i + 1
|
||||||
|
if p.get("PageBreak") == "true":
|
||||||
|
pagebreak_index_list.append(xml_index)
|
||||||
|
|
||||||
|
# 페이지 별 시작 문단~끝 문단 구간 저장
|
||||||
|
page_ranges = []
|
||||||
|
start = 1 # XML은 1-based index
|
||||||
|
# pagebreak_index_list에 따라 구간 나누기
|
||||||
|
for index in pagebreak_index_list:
|
||||||
|
end = index - 1
|
||||||
|
page_ranges.append((start, end))
|
||||||
|
start = index
|
||||||
|
|
||||||
|
# 마지막 페이지 구간 추가
|
||||||
|
page_ranges.append((start, len(p_elements))) # 끝까지
|
||||||
|
|
||||||
|
# 출력 확인
|
||||||
|
# for i, (start, end) in enumerate(page_ranges, 1):
|
||||||
|
# print(f"📄 Page {i}: {start} ~ {end}")
|
||||||
|
|
||||||
|
# 단수 구간 결과를 저장할 리스트
|
||||||
|
column_sections = []
|
||||||
|
|
||||||
current_count = None
|
current_count = None
|
||||||
start_index = None
|
start_index = None
|
||||||
|
|
||||||
|
# 모든 P태그를 순회하며 단 나눔이 1단인 구간과 2단인 구간을 저장
|
||||||
for i, p in enumerate(p_elements):
|
for i, p in enumerate(p_elements):
|
||||||
xml_index = i + 1 # XML 기준 1-based index
|
xml_index = i + 1 # XML 기준 1-based index
|
||||||
coldef = p.xpath('.//COLDEF')
|
coldef = p.xpath('.//COLDEF')
|
||||||
@@ -803,41 +828,71 @@ class XMLScorer:
|
|||||||
|
|
||||||
# Count 값이 변경되었을 때 이전 구간을 저장
|
# Count 값이 변경되었을 때 이전 구간을 저장
|
||||||
elif column_count != current_count:
|
elif column_count != current_count:
|
||||||
sections.append((start_index, i - 1, current_count))
|
column_sections.append((start_index, i - 1, current_count))
|
||||||
# 새 구간 시작
|
# 새 구간 시작
|
||||||
current_count = column_count
|
current_count = column_count
|
||||||
start_index = i
|
start_index = i
|
||||||
|
|
||||||
# 마지막 구간 저장
|
# 마지막 구간 저장
|
||||||
if current_count is not None and start_index is not None:
|
if current_count is not None and start_index is not None:
|
||||||
sections.append((start_index, len(p_elements) - 1, current_count))
|
column_sections.append((start_index, len(p_elements) - 1, current_count))
|
||||||
|
|
||||||
# 결과 출력
|
# 결과 출력
|
||||||
for start, end, count in sections:
|
# for start, end, count in column_sections:
|
||||||
xml_start = start + 1 # XML 기준 1-based index
|
# xml_start = start + 1 # XML 기준 1-based index
|
||||||
xml_end = end + 1
|
# xml_end = end + 1
|
||||||
print(f"📄 {count}단 구간: P[{xml_start}] ~ P[{xml_end}]")
|
# print(f"📄 {count}단 구간: P[{xml_start}] ~ P[{xml_end}]")
|
||||||
|
|
||||||
# PageBreak='true' 속성을 가진 P태그 인덱스
|
# 2페이지 구간 가져오기 (인덱스는 0-based지만 값은 1-based)
|
||||||
pagebreak_index = None
|
if len(page_ranges) > 1:
|
||||||
for i, p in enumerate(p_elements):
|
second_page_start, second_page_end = page_ranges[1]
|
||||||
xml_index = i + 1
|
|
||||||
if p.get("PageBreak") == "true":
|
# 2페이지가 없을 경우 1페이지(문서 전체) 내용으로 대체
|
||||||
pagebreak_index = xml_index
|
# 문서 전체에서 2단 문단이 있을 경우는 정답
|
||||||
|
else:
|
||||||
|
second_page_start, second_page_end = page_ranges[0]
|
||||||
|
# 2페이지가 없을 경우 오답 처리
|
||||||
|
# else:
|
||||||
|
# user_answer = None
|
||||||
|
|
||||||
|
# 2단 포함 여부 확인 변수
|
||||||
|
has_two_column_in_page2 = False
|
||||||
|
|
||||||
|
# 2단 구간이 2페이지 범위와 겹치는지 확인
|
||||||
|
# col_start : 다단 시작 P태그 인덱스
|
||||||
|
# col_end : 다단 끝 P태그 인덱스
|
||||||
|
# col_count : 다단 수
|
||||||
|
for col_start, col_end, col_count in column_sections:
|
||||||
|
two_col_start = col_start + 1 # 1-based
|
||||||
|
two_col_end = col_end + 1
|
||||||
|
|
||||||
|
if col_count == '2':
|
||||||
|
# 구간이 겹치는지 확인
|
||||||
|
if two_col_end >= second_page_start and two_col_start <= second_page_end:
|
||||||
|
has_two_column_in_page2 = True
|
||||||
|
user_answer = col_count
|
||||||
break
|
break
|
||||||
|
|
||||||
print(f"📜PageBreak 인덱스 : P[{pagebreak_index}]", )
|
# print("✅ 2페이지에 2단 있음" if has_two_column_in_page2 else "❌ 2페이지에 2단 없음")
|
||||||
|
|
||||||
# 다단 2단 구간이 PageBreak='true'이후에도 속하는지 확인
|
if has_two_column_in_page2:
|
||||||
# 다단 2단 속성이 2페이지 이후에도 속하는지 확인
|
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||||
for start, end, count in sections:
|
|
||||||
xml_start = start + 1
|
|
||||||
xml_end = end + 1
|
|
||||||
if count == '2' and xml_start <= pagebreak_index :
|
|
||||||
print("ㅇㅇ")
|
|
||||||
|
|
||||||
|
# SECTION[2]가 존재하는 경우
|
||||||
|
else: # has_section2
|
||||||
|
coldef_in_section2 = has_section2[0].xpath('//COLDEF')
|
||||||
|
has_correct_column_count = False
|
||||||
|
|
||||||
|
for coldef in coldef_in_section2:
|
||||||
|
column_count = coldef.get('Count')
|
||||||
|
user_answer = column_count
|
||||||
|
if user_answer == right_answer:
|
||||||
|
has_correct_column_count = True
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if has_correct_column_count:
|
||||||
|
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
|
||||||
|
|
||||||
# 한자
|
# 한자
|
||||||
elif (category or "") == "Hanja":
|
elif (category or "") == "Hanja":
|
||||||
# 점수 계산
|
# 점수 계산
|
||||||
@@ -1208,8 +1263,8 @@ def main():
|
|||||||
# '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":"//SECTION[1]//TEXT[CHAR[text()='DIAT']]/@CharShape"},{"kind":2,"language":"xpath","value":"//CHARSHAPE[@Id=//SECTION[1]//TEXT[CHAR[text()='{searchValue}']]/@CharShape]/@Height"},{"kind":2,"language":"xpath","value":"//P"},{"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"}]
|
[{"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":"/HWPML/BODY/SECTION/P[19]"},{"kind":2,"language":"xpath","value":"//SECTION"},{"kind":2,"language":"xpath","value":"//P"},{"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"}]
|
||||||
Binary file not shown.
Reference in New Issue
Block a user