diff --git a/250610_DIW_2505A_TEST.xlsx b/250610_DIW_2505A_TEST.xlsx new file mode 100644 index 0000000..87264b0 Binary files /dev/null and b/250610_DIW_2505A_TEST.xlsx differ diff --git a/250610_DIW_2505A_채점결과.xlsx b/250610_DIW_2505A_채점결과.xlsx new file mode 100644 index 0000000..1a81ca2 Binary files /dev/null and b/250610_DIW_2505A_채점결과.xlsx differ diff --git a/250611_DIW_2505A_TEST.xlsx b/250611_DIW_2505A_TEST.xlsx new file mode 100644 index 0000000..882be24 Binary files /dev/null and b/250611_DIW_2505A_TEST.xlsx differ diff --git a/250611_DIW_2505A_채점결과.xlsx b/250611_DIW_2505A_채점결과.xlsx new file mode 100644 index 0000000..d365e35 Binary files /dev/null and b/250611_DIW_2505A_채점결과.xlsx differ diff --git a/DIW_2505A.json b/DIW_2505A.json index d064530..b48cb0e 100644 --- a/DIW_2505A.json +++ b/DIW_2505A.json @@ -315,7 +315,7 @@ "value": "200", "points": 2, "category": "LineSpacing", - "item": "문제 1 줄간격 180% 설정", + "item": "문제 1 줄간격 200% 설정", "desc": "1페이지 문단의 줄간격이 정답이 아닌 문단이 있으면 False(감점)" } }, @@ -340,7 +340,7 @@ "desc": "섹션이 1개 이상이면 점수부여" }, "3": { - "path": "//COLDEF/@Count", + "path": "//COLDEF", "value": "2", "points": 3, "category": "TwoColumn", diff --git a/DIW_2505B.json b/DIW_2505B.json index ba110c8..c268f46 100644 --- a/DIW_2505B.json +++ b/DIW_2505B.json @@ -342,10 +342,10 @@ "desc": "섹션이 1개 이상이면 점수부여" }, "3": { - "path": "//COLDEF/@Count", + "path": "//COLDEF", "value": "2", "points": 3, - "category": "OneAnswer", + "category": "TwoColumn", "item": "② 다단 2단" }, "4": { diff --git a/DIW_2505C.json b/DIW_2505C.json index e42e631..634fe12 100644 --- a/DIW_2505C.json +++ b/DIW_2505C.json @@ -342,10 +342,10 @@ "desc": "섹션이 1개 이상이면 점수부여" }, "3": { - "path": "//COLDEF/@Count", + "path": "//COLDEF", "value": "2", "points": 3, - "category": "OneAnswer", + "category": "TwoColumn", "item": "② 다단 2단" }, "4": { diff --git a/diwScoring2.py b/diwScoring2.py index 84691ee..0101841 100644 --- a/diwScoring2.py +++ b/diwScoring2.py @@ -773,21 +773,46 @@ class XMLScorer: # 다단 확인 [2-3]문항 elif (category or "") == "TwoColumn": - has_section2 = root.xpath('//SECTION[2]') + + # 구역 나눔이 적용 되어 있지 않은 경우 + # (= SECTION[2]가 없을 경우) if not has_section2: - # //P//COLDEF/@Count 속성이 시작하는 P태그 부터 - # @Count 속성이 변한 P태그 이전인덱스 까지가 페이지 단수가 적용되어있는 구간 - - # 모든

요소 가져오기 - p_elements = root.xpath('//P') - # 구간 결과를 저장할 리스트 - sections = [] + # 모든

요소 가져오기 + p_elements = root.xpath('//SECTION/P') + + # PageBreak='true' 속성을 가진 P태그 인덱스 + # [=쪽나눔 이후 페이지의 첫 문단들] + 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 start_index = None - + + # 모든 P태그를 순회하며 단 나눔이 1단인 구간과 2단인 구간을 저장 for i, p in enumerate(p_elements): xml_index = i + 1 # XML 기준 1-based index coldef = p.xpath('.//COLDEF') @@ -803,41 +828,71 @@ class XMLScorer: # 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 start_index = i # 마지막 구간 저장 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: - xml_start = start + 1 # XML 기준 1-based index - xml_end = end + 1 - print(f"📄 {count}단 구간: P[{xml_start}] ~ P[{xml_end}]") - - # PageBreak='true' 속성을 가진 P태그 인덱스 - pagebreak_index = None - for i, p in enumerate(p_elements): - xml_index = i + 1 - if p.get("PageBreak") == "true": - pagebreak_index = xml_index - break - - print(f"📜PageBreak 인덱스 : P[{pagebreak_index}]", ) + # for start, end, count in column_sections: + # xml_start = start + 1 # XML 기준 1-based index + # xml_end = end + 1 + # print(f"📄 {count}단 구간: P[{xml_start}] ~ P[{xml_end}]") - # 다단 2단 구간이 PageBreak='true'이후에도 속하는지 확인 - # 다단 2단 속성이 2페이지 이후에도 속하는지 확인 - for start, end, count in sections: - xml_start = start + 1 - xml_end = end + 1 - if count == '2' and xml_start <= pagebreak_index : - print("ㅇㅇ") + # 2페이지 구간 가져오기 (인덱스는 0-based지만 값은 1-based) + if len(page_ranges) > 1: + second_page_start, second_page_end = page_ranges[1] + # 2페이지가 없을 경우 1페이지(문서 전체) 내용으로 대체 + # 문서 전체에서 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 + + # print("✅ 2페이지에 2단 있음" if has_two_column_in_page2 else "❌ 2페이지에 2단 없음") - break + if has_two_column_in_page2: + self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal") + + # 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 + + if has_correct_column_count: + self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal") + # 한자 elif (category or "") == "Hanja": # 점수 계산 @@ -1208,8 +1263,8 @@ def main(): # 'D', ] - # test_mode = False - test_mode = True #/TEST 폴더 채점시 + test_mode = False + # test_mode = True #/TEST 폴더 채점시 output_excel_paths = [] for exam_type in exam_types: diff --git a/zzz.xbook b/zzz.xbook index d61bd2d..10aa848 100644 --- a/zzz.xbook +++ b/zzz.xbook @@ -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"}] \ No newline at end of file +[{"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"}] \ No newline at end of file diff --git a/회차별채점자료/2505/2505확인필요.xlsx b/회차별채점자료/2505/2505확인필요.xlsx index d1c4bc3..37c18ee 100644 Binary files a/회차별채점자료/2505/2505확인필요.xlsx and b/회차별채점자료/2505/2505확인필요.xlsx differ