v2 - 문제2 45문항

This commit is contained in:
2025-05-15 18:06:06 +09:00
parent 872d5f6da6
commit 20c4359cb8
8 changed files with 197 additions and 66 deletions

Binary file not shown.

View File

@@ -637,7 +637,6 @@
"37": {
"path": "//BORDERFILL[@Id=//TABLE/ROW[1]/CELL/@BorderFill]/FILLBRUSH/WINDOWBRUSH/@FaceColor",
"path2": "//BORDERFILL[@Id=//CELLZONE[@StartRowAddr='0' and @EndRowAddr='0' and @StartColAddr='0' and @EndColAddr='2']/@BorderFill]/FILLBRUSH/WINDOWBRUSH/@FaceColor",
"searchValue": null,
"value": "2862825",
"points": 2,
"category": "표",

View File

@@ -49,7 +49,7 @@
"searchValue": "클라우드컴퓨팅컨퍼런스",
"value": "맑은 고딕",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드컴퓨팅컨퍼런스)/① 글씨체 (맑은 고딕)"
},
"2": {
@@ -83,7 +83,7 @@
"searchValue": "클라우드컴퓨팅컨퍼런스",
"value": "true",
"points": 2,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드컴퓨팅컨퍼런스)/⑤ 위치 (글자처럼 취급)"
},
"6": {
@@ -91,7 +91,7 @@
"searchValue": "클라우드컴퓨팅컨퍼런스",
"value": "Center",
"points": 2,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드컴퓨팅컨퍼런스)/⑥ 정렬 (가운데 정렬)"
},
"7": {
@@ -180,7 +180,7 @@
"searchValue": "참여안내",
"value": "Center",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (● 참여안내 ●)/② 정렬 (가운데 정렬)"
},
"17": {
@@ -216,7 +216,7 @@
"searchValue": "2025. 04. 26.",
"value": "1400",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (2025. 04. 26.)/① 크기 (14pt)",
"desc": "1pt당 100"
},
@@ -225,7 +225,7 @@
"searchValue": "2025. 04. 26.",
"value": "Center",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (2025. 04. 26.)/② 정렬 (가운데 정렬)"
},
"22": {
@@ -241,7 +241,7 @@
"searchValue": "글로벌멀티클라우드협의회",
"value": "2600",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (글로벌멀티클라우드협의회)/② 크기 (26pt)"
},
"24": {
@@ -249,7 +249,7 @@
"searchValue": "글로벌멀티클라우드협의회",
"value": "Center",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (글로벌멀티클라우드협의회)/③ 정렬 (가운데 정렬)"
},
"25": {
@@ -265,7 +265,7 @@
"searchValue": "DIAT",
"value": "900",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (DIAT)/② 크기 (9pt)"
},
"27": {
@@ -273,14 +273,14 @@
"searchValue": "DIAT",
"value": "Right",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (DIAT)/③ 정렬 (오른쪽 정렬)"
},
"28": {
"path": "//PAGENUM/@FormatType",
"value": "LatinCapital",
"points": 2,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "① 쪽 번호 매기기 (A,B,C 순으로)",
"desc": {
"가,나,다":"HangulSyllable",
@@ -299,7 +299,7 @@
"path": "//PAGENUM/@Pos",
"value": "BottomRight",
"points": 2,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "오른쪽 아래"
},
"30": {
@@ -335,7 +335,7 @@
"path": "//SECTION[2]//COLDEF/@Count",
"value": "2",
"points": 3,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "② 다단 2단"
},
"4": {
@@ -369,7 +369,7 @@
"searchValue": "클라우드 컴퓨팅",
"value": "50",
"points": 2,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드 컴퓨팅)/④ 글상자 모서리 (반원)"
},
"8": {
@@ -385,7 +385,7 @@
"searchValue": "클라우드 컴퓨팅",
"value": "true",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드 컴퓨팅)/⑥ 글상자 위치 (글자처럼 취급)"
},
"10": {
@@ -393,7 +393,7 @@
"searchValue": "클라우드 컴퓨팅",
"value": "Center",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드 컴퓨팅)/⑦ 글상자 정렬 (가운데 정렬)"
},
"11": {
@@ -410,7 +410,7 @@
"searchValue": "클라우드 컴퓨팅",
"value": "2000",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드 컴퓨팅)/⑨ 글씨크기 (20pt)",
"desc":"1pt당 100"
},
@@ -419,7 +419,7 @@
"searchValue": "클라우드 컴퓨팅",
"value": "Center",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드 컴퓨팅)/⑩ 정렬 (가운데 정렬)"
},
"14": {
@@ -471,7 +471,7 @@
"searchValue": "1. 주목하는 최신 트렌드",
"value": "1200",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구① (1. 주목하는 최신 트렌드)/② 크기 (12pt)"
},
"21": {
@@ -495,7 +495,7 @@
"searchValue": "2. 기술의 경제적 가치",
"value": "1200",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구② (2. 기술의 경제적 가치)/② 크기 (12pt)"
},
"24": {
@@ -528,7 +528,7 @@
"searchValue": "인터넷을 통해 액세스할 수 있는 가상화된 서버에서 실행되는 프로그램과 데이터베이스를 제공하는 환경",
"value": "900",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드)/③ 크기 (9pt)"
},
"28": {
@@ -536,7 +536,7 @@
"searchValue": "인터넷을 통해 액세스할 수 있는 가상화된 서버에서 실행되는 프로그램과 데이터베이스를 제공하는 환경",
"value": "Ideograph",
"points": 2,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "문구 (클라우드)/④ 각주 번호모양",
"desc": {
"가,나,다":"HangulSyllable",
@@ -601,7 +601,7 @@
"searchValue": "클라우드 보안(단위: 백만 달러)",
"value": "1200",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "제목 문구 (클라우드 보안(단위: 백만 달러))/② 크기 (12pt)"
},
"35": {
@@ -617,9 +617,83 @@
"searchValue": "클라우드 보안(단위: 백만 달러)",
"value": "Center",
"points": 1,
"category": "SingleAnswer",
"category": "OneAnswer",
"item": "제목 문구 (클라우드 보안(단위: 백만 달러))/④ 정렬 (가운데 정렬)"
},
"37": {
"path": "//BORDERFILL[@Id=//TABLE/ROW[1]/CELL/@BorderFill]/FILLBRUSH/WINDOWBRUSH/@FaceColor",
"path2": "//BORDERFILL[@Id=//CELLZONE[@StartRowAddr='0' and @EndRowAddr='0' and @StartColAddr='0' and @EndColAddr=(ancestor::TABLE[1]/@ColCount)-1]/@BorderFill]/FILLBRUSH/WINDOWBRUSH/@FaceColor",
"value": "233,174,43",
"points": 2,
"category": "Color",
"item": "위쪽 제목 셀/① 색상(RGB:233,174,43)"
},
"38": {
"path": "//CHARSHAPE[@Id=//TABLE/ROW[1]/descendant::TEXT/@CharShape]",
"value": "BOLD",
"points": 1,
"category": "FontAttribute",
"item": "위쪽 제목 셀/② 진하게",
"desc": "글자 속성이라 CELLZONE으로 적용 되지 않음"
},
"39": {
"path": "//BORDERFILL[@Id=//TABLE/ROW[1]/CELL/@BorderFill]/BOTTOMBORDER/@Type",
"path2": "//BORDERFILL[@Id=//CELLZONE[@StartRowAddr='0' and @EndRowAddr='0' and @StartColAddr='0' and @EndColAddr=(ancestor::TABLE[1]/@ColCount)-1]/@BorderFill]/BOTTOMBORDER/@Type",
"value": "DoubleSlim",
"points": 2,
"category": "OneAnswer",
"item": "제목 셀 아래선/① 이중실선"
},
"40": {
"path": "//BORDERFILL[@Id=//TABLE/ROW[1]/CELL/@BorderFill]/BOTTOMBORDER/@Width",
"path2": "//BORDERFILL[@Id=//CELLZONE[@StartRowAddr='0' and @EndRowAddr='0' and @StartColAddr='0' and @EndColAddr=(ancestor::TABLE[1]/@ColCount)-1]/@BorderFill]/BOTTOMBORDER/@Width",
"value": "0.5mm",
"points": 2,
"category": "OneAnswer",
"item": "제목 셀 아래선/② 0.5mm"
},
"41": {
"path": "//TABLE//TEXT/@CharShape",
"path2": "//FONTFACE[@Lang='Hangul']/FONT[@Id=//CHARSHAPE[@Id=//TABLE/ROW/descendant::TEXT/@CharShape]/FONTID/@Hangul]/@Name",
"value": "중고딕",
"points": 1,
"category": "TableFontName",
"category_tmp": "FontName",
"item": "글자모양/① 글씨체 (중고딕)",
"desc": "테이블 폰트명 문항은 테이블의 모든 셀이 정답폰트와 일치해야 함, 하나만 일치해도 정답으로 채점할 경우 category값을 FontName으로 변경"
},
"42": {
"path": "//CHARSHAPE[@Id=//TABLE//TEXT/@CharShape]/@Height",
"value": "1000",
"points": 1,
"category": "OneAnswer",
"item": "글자모양/② 크기 (10pt)"
},
"43": {
"path": "//PARASHAPE[@Id=//TABLE/ROW//P/@ParaShape]/@Align",
"value": "Center",
"points": 1,
"category": "OneAnswer",
"item": "글자모양/③ 정렬 (가운데 정렬)"
},
"44": {
"path": "boolean(//TABLE[1]/ROW[last()]/CELL[position()=last() or position()=last()-1]//FIELDBEGIN[starts-with(@Command, '={option}')])",
"option": "SUM",
"value": true,
"points": 4,
"category": "Boolean",
"item": "블록 계산식/합계",
"desc": "option값에 합계는 SUM / 평균은 AVG"
},
"45": {
"path": "",
"chart_type": "묶은세로막대형",
"value": true,
"points": 2,
"category": "chart_type",
"item": "① 종류 (묶은 세로 막대형)",
"desc": "chart_type을 입력받아 차트타입에 맞는 xml요소가 있는지 내부적으로 검사, chart_type만 한글로 입력해주면 된다."
},
"61": {}
}
}

View File

@@ -1 +1 @@
[{"kind":1,"language":"markdown","value":"# XPath Notebook\nDate: 2025-01-22     Time: 16:12:58"},{"kind":1,"language":"markdown","value":"* mm > pt 변환비율 = 2.83465 \r\n* 283.465"},{"kind":1,"language":"markdown","value":"- 색상 demical 코드 [1-2] [1-10] [2-8] [2-37]"},{"kind":2,"language":"xpath","value":"//TEXTART[@Text='클라우드컴퓨팅컨퍼런스']/descendant::WINDOWBRUSH/@FaceColor"},{"kind":2,"language":"xpath","value":"//RECTANGLE[.//CHAR[text()='전']]//WINDOWBRUSH/@FaceColor"},{"kind":2,"language":"xpath","value":"//RECTANGLE//CHAR[text()='클라우드 컴퓨팅']/ancestor::RECTANGLE/descendant::WINDOWBRUSH/@FaceColor"},{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//TABLE/ROW[1]/CELL/@BorderFill]/FILLBRUSH/WINDOWBRUSH/@FaceColor"},{"kind":1,"language":"markdown","value":"- [1-10] ① ●, ② ●, ③ ※"},{"kind":2,"language":"xpath","value":"\"path\": \"count(//CHAR[contains(text(),'●')]) + count(//CHAR[contains(text(),'※')])\",\r\n \"path2\": \"string-length(//CHAR[contains(text(),'●')]) - string-length(translate(//CHAR[contains(text(),'●')], '●', '')) + string-length(//CHAR[contains(text(),'※')]) - string-length(translate(//CHAR[contains(text(),'※')], '※', ''))\","},{"kind":1,"language":"markdown","value":"- [1-28] [2-28] @FormatType 종류\r\n - HangulSyllable : 가나다\r\n - Digit : 123\r\n - DecagonCircle : 갑을병정\r\n - LatinCapital : ABC\r\n - CircledDigit : ①,②,③\r\n - Ideograph : 一,二,三\r\n - CircledHangulJamo : ㉠,㉡,㉢\r\n - CircledLatinSmall : ⓐ,ⓑ,ⓒ\r\n - RomanSmall : i,ii,iii"},{"kind":2,"language":"xpath","value":"//SECTION[1]//PAGENUM/@FormatType"},{"kind":2,"language":"xpath","value":"//P[TEXT[CHAR[contains(text(), '눈으로 읽는 대신 귀로 들을 수 있게 책의 내용(문자)을 음성으로 녹음하여 기록한 것을 의미함')]]]//AUTONUMFORMAT/@Type"},{"kind":1,"language":"markdown","value":"- [2-30] ① 저감(低減), ② 화석(化石), ③ 투자(投資), ④ 달성(達成), ⑤ 세금(稅金)"},{"kind":2,"language":"xpath","value":"(count(//CHAR[contains(text(),'저감')][contains(text(),'低減')])+count(//CHAR[contains(text(),'화석')][contains(text(),'化石')])+count(//CHAR[contains(text(),'투자')][contains(text(),'投資')])+count(//CHAR[contains(text(),'달성')][contains(text(),'達成')])+count(//CHAR[contains(text(),'세금')][contains(text(),'稅金')]))*2"},{"kind":1,"language":"markdown","value":"- [2-37] [2-39] [2-40] @EndColAddr 속성값 \r\n - 표의 열 갯수-1\r\n - 4개=3 / 3개=2 / 2개=1"},{"kind":2,"language":"xpath","value":"@EndColAddr='2'"},{"kind":1,"language":"markdown","value":"- [2-45]\r\n - 꺾은선형 //c:lineChart/c:grouping/@val='standard'\r\n - 가로막대형 boolean(//c:barChart/c:barDir[@val='bar'])\r\n - 묶은로막대형 boolean(//c:barChart[c:barDir[@val='bar'] and c:grouping[@val='clustered']])\r\n - 세로막대형 boolean(//c:barChart/c:barDir[@val='col'])\r\n - 묶은세로막대형 boolean(//c:barChart[c:barDir[@val='col'] and c:grouping[@val='clustered']])"},{"kind":2,"language":"xpath","value":"boolean(//c:barChart[c:barDir[@val='col'] and c:grouping[@val='clustered']])"},{"kind":2,"language":"xpath","value":"//c:valAx/c:majorTickMark/@val"}]
[{"kind":1,"language":"markdown","value":"# XPath Notebook\nDate: 2025-01-22     Time: 16:12:58"},{"kind":1,"language":"markdown","value":"* mm > pt 변환비율 = 2.83465 \r\n* 283.465"},{"kind":1,"language":"markdown","value":"- 색상 demical 코드 [1-2] [1-10] [2-8] [2-37]"},{"kind":2,"language":"xpath","value":"//TEXTART[@Text='클라우드컴퓨팅컨퍼런스']/descendant::WINDOWBRUSH/@FaceColor"},{"kind":2,"language":"xpath","value":"//RECTANGLE[.//CHAR[text()='전']]//WINDOWBRUSH/@FaceColor"},{"kind":2,"language":"xpath","value":"//RECTANGLE//CHAR[text()='클라우드 컴퓨팅']/ancestor::RECTANGLE/descendant::WINDOWBRUSH/@FaceColor"},{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//TABLE/ROW[1]/CELL/@BorderFill]/FILLBRUSH/WINDOWBRUSH/@FaceColor"},{"kind":1,"language":"markdown","value":"- [1-10] ① ●, ② ●, ③ ※"},{"kind":2,"language":"xpath","value":"\"path\": \"count(//CHAR[contains(text(),'●')]) + count(//CHAR[contains(text(),'※')])\",\r\n \"path2\": \"string-length(//CHAR[contains(text(),'●')]) - string-length(translate(//CHAR[contains(text(),'●')], '●', '')) + string-length(//CHAR[contains(text(),'※')]) - string-length(translate(//CHAR[contains(text(),'※')], '※', ''))\","},{"kind":1,"language":"markdown","value":"- [1-28] [2-28] @FormatType 종류\r\n - HangulSyllable : 가나다\r\n - Digit : 123\r\n - DecagonCircle : 갑을병정\r\n - LatinCapital : ABC\r\n - CircledDigit : ①,②,③\r\n - Ideograph : 一,二,三\r\n - CircledHangulJamo : ㉠,㉡,㉢\r\n - CircledLatinSmall : ⓐ,ⓑ,ⓒ\r\n - RomanSmall : i,ii,iii"},{"kind":2,"language":"xpath","value":"//SECTION[1]//PAGENUM/@FormatType"},{"kind":2,"language":"xpath","value":"//P[TEXT[CHAR[contains(text(), '눈으로 읽는 대신 귀로 들을 수 있게 책의 내용(문자)을 음성으로 녹음하여 기록한 것을 의미함')]]]//AUTONUMFORMAT/@Type"},{"kind":1,"language":"markdown","value":"- [2-30] ① 저감(低減), ② 화석(化石), ③ 투자(投資), ④ 달성(達成), ⑤ 세금(稅金)"},{"kind":2,"language":"xpath","value":"(count(//CHAR[contains(text(),'저감')][contains(text(),'低減')])+count(//CHAR[contains(text(),'화석')][contains(text(),'化石')])+count(//CHAR[contains(text(),'투자')][contains(text(),'投資')])+count(//CHAR[contains(text(),'달성')][contains(text(),'達成')])+count(//CHAR[contains(text(),'세금')][contains(text(),'稅金')]))*2"},{"kind":1,"language":"markdown","value":"- [2-37] [2-39] [2-40] @EndColAddr 속성값 \r\n - 표의 열 갯수-1\r\n - 4개=3 / 3개=2 / 2개=1"},{"kind":2,"language":"xpath","value":"@EndColAddr='2'"},{"kind":1,"language":"markdown","value":"- [2-45]\r\n - 꺾은선형 //c:lineChart\r\n - 묶은가로막대형 //c:barChart[c:barDir[@val='bar']]\r\n - 묶은로막대형 //c:barChart[c:barDir[@val='col']]\r\n - 원형 //c:pieChart\r\n - 분산형 //c:scatterChart"},{"kind":1,"language":"markdown","value":"//c:{chart_type}Chart/"},{"kind":2,"language":"xpath","value":"boolean(//c:barChart[c:barDir[@val='col'] and c:grouping[@val='clustered']])"},{"kind":2,"language":"xpath","value":"//c:valAx/c:majorTickMark/@val"}]

View File

@@ -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가 있는 경우
@@ -212,6 +215,10 @@ class XMLScorer:
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,13 +385,13 @@ 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")
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]
@@ -398,8 +403,42 @@ class XMLScorer:
self.evaluate_answer(scoring, user_answer, right_answer, points, method="equal")
if scoring['points'] > 0:
break
# 테이블 폰트명
# 테이블 내부 모든 셀의 폰트가 정답과 일치해야 함
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")
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', [])
@@ -517,8 +557,26 @@ class XMLScorer:
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

View File

@@ -1 +1 @@
[{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//PAGEBORDERFILL[@Type='Both' or @Type='Even']/@BorferFill]/*[contains(local-name(), 'BORDER')]/@Type"},{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//SECTION[2]//PAGEBORDERFILL[@Type='Both' or @Type='Even']/@BorferFill]"},{"kind":2,"language":"xpath","value":"//RECTANGLE//CHAR[text()='클라우드 컴퓨팅']/ancestor::RECTANGLE/descendant::LINESHAPE"},{"kind":2,"language":"xpath","value":"//RECTANGLE[.//CHAR[text()='클라우드 컴퓨팅']]//LINESHAPE"},{"kind":2,"language":"xpath","value":"//RECTANGLE[.//CHAR[text()='클라우드 컴퓨팅']]/SHAPEOBJECT/POSITION/@TreatAsChar"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//RECTANGLE//CHAR[text()='{searchValue}']/ancestor::P[last()]/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//CHARSHAPE[@Id=//RECTANGLE//CHAR[text()='클라우드 컴퓨팅']/parent::TEXT/@CharShape]/@Height"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//RECTANGLE//P[.//CHAR[text()='{searchValue}']]/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]/preceding-sibling::SHAPEOBJECT/SIZE/@Width"},{"kind":2,"language":"xpath","value":"//CHAR[text()='{searchValue}']/parent::TEXT/@CharShape"},{"kind":2,"language":"xpath","value":"//TEXT[CHAR[text()='{searchValue}']]/@CharShape"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//P[.//TEXTART[@Text='클라우드컴퓨팅컨퍼런스']]/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//CHARSHAPE[@Id=//TEXT[CHAR[contains(text(),'클라우드 보안(단위: 백만 달러)')]]/@CharShape]/@Height"},{"kind":2,"language":"xpath","value":"//TEXT[CHAR[contains(text(),'클라우드')]]/FOOTNOTE[CHAR[contains(text(),'인터넷을 통해 액세스할 수 있는 가상화된 서버에서 실행되는 프로그램과 데이터베이스를 제공하는 환경')]]"},{"kind":2,"language":"xpath","value":"//TEXT[CHAR[contains(text(),'클라우드')]]/FOOTNOTE[.//CHAR[contains(text(),'인터넷을 통해 액세스할 수 있는 가상화된 서버에서 실행되는 프로그램과 데이터베이스를 제공하는 환경')]]"},{"kind":2,"language":"xpath","value":"//TEXT[CHAR[contains(text(),'클라우드')]]/FOOTNOTE"},{"kind":2,"language":"xpath","value":"//CHARSHAPE[@Id=//TEXT[CHAR[text()='클라우드 보안(단위: 백만 달러)']]/@CharShape]"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//P[.//CHAR[text()='클라우드 보안(단위: 백만 달러)']]/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//CHAR[contains(text(),'클라우드 보안(단위: 백만 달러)')]/ancestor::P/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//P[.//CHAR[text()='클라우드 보안(단위: 백만 달러)']]"}]
[{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//PAGEBORDERFILL[@Type='Both' or @Type='Even']/@BorferFill]/*[contains(local-name(), 'BORDER')]/@Type"},{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//SECTION[2]//PAGEBORDERFILL[@Type='Both' or @Type='Even']/@BorferFill]"},{"kind":2,"language":"xpath","value":"//RECTANGLE//CHAR[text()='클라우드 컴퓨팅']/ancestor::RECTANGLE/descendant::LINESHAPE"},{"kind":2,"language":"xpath","value":"//RECTANGLE[.//CHAR[text()='클라우드 컴퓨팅']]//LINESHAPE"},{"kind":2,"language":"xpath","value":"//RECTANGLE[.//CHAR[text()='클라우드 컴퓨팅']]/SHAPEOBJECT/POSITION/@TreatAsChar"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//RECTANGLE//CHAR[text()='{searchValue}']/ancestor::P[last()]/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//CHARSHAPE[@Id=//RECTANGLE//CHAR[text()='클라우드 컴퓨팅']/parent::TEXT/@CharShape]/@Height"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//RECTANGLE//P[.//CHAR[text()='{searchValue}']]/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//IMAGE[@BinItem=//BINITEM[@Format='JPG']/@BinData]/preceding-sibling::SHAPEOBJECT/SIZE/@Width"},{"kind":2,"language":"xpath","value":"//CHAR[text()='{searchValue}']/parent::TEXT/@CharShape"},{"kind":2,"language":"xpath","value":"//TEXT[CHAR[text()='{searchValue}']]/@CharShape"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//P[.//TEXTART[@Text='클라우드컴퓨팅컨퍼런스']]/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//CHARSHAPE[@Id=//TEXT[CHAR[contains(text(),'클라우드 보안(단위: 백만 달러)')]]/@CharShape]/@Height"},{"kind":2,"language":"xpath","value":"//TEXT[CHAR[contains(text(),'클라우드')]]/FOOTNOTE[CHAR[contains(text(),'인터넷을 통해 액세스할 수 있는 가상화된 서버에서 실행되는 프로그램과 데이터베이스를 제공하는 환경')]]"},{"kind":2,"language":"xpath","value":"//TEXT[CHAR[contains(text(),'클라우드')]]/FOOTNOTE[.//CHAR[contains(text(),'인터넷을 통해 액세스할 수 있는 가상화된 서버에서 실행되는 프로그램과 데이터베이스를 제공하는 환경')]]"},{"kind":2,"language":"xpath","value":"//TEXT[CHAR[contains(text(),'클라우드')]]/FOOTNOTE"},{"kind":2,"language":"xpath","value":"//CHARSHAPE[@Id=//TEXT[CHAR[text()='클라우드 보안(단위: 백만 달러)']]/@CharShape]"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//P[.//CHAR[text()='클라우드 보안(단위: 백만 달러)']]/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//CHAR[contains(text(),'클라우드 보안(단위: 백만 달러)')]/ancestor::P/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//CELLZONE[@StartRowAddr='0' and @EndRowAddr='0' and @StartColAddr='0' and @EndColAddr=(ancestor::TABLE[1]/@ColCount)-1]/@BorderFill]/FILLBRUSH/WINDOWBRUSH/@FaceColor"},{"kind":2,"language":"xpath","value":"//BORDERFILL[@Id=//CELLZONE[@EndColAddr=../../@ColCount]]"},{"kind":2,"language":"xpath","value":"//CHARSHAPE[@Id=//TABLE//TEXT/@CharShape]/@Height"},{"kind":2,"language":"xpath","value":"//PARASHAPE[@Id=//TABLE/ROW//P/@ParaShape]/@Align"},{"kind":2,"language":"xpath","value":"//TABLE[1]/ROW[last()]/CELL[last()-1]//FIELDBEGIN[starts-with(@Command, '=SUM')]"},{"kind":2,"language":"xpath","value":"//TABLE[1]/ROW[last()]/CELL[position() = last() or position() = last() - 1]//FIELDBEGIN[starts-with(@Command, '=SUM')]\r\n"}]

View File

@@ -18,7 +18,7 @@
글맵시 있는데 오답처리
000076 박다은 >> 정상채점
000285 문예슬 >> 글맵시 텍스트에 개행이 들어가 있음 "서울국제도서박람회␍␊"
001345 조수빈 >> 서울국제도시박람회
000203 이지운 >> 서울국제도섭가람회
@@ -29,11 +29,11 @@
문구 (◆ 행사안내 ◆) - 궁서/가운데정렬 맞는데 오답처리(띄어쓰기 때문인듯)
>> "◆ 행사안내 ◆" 기준으로 검색할 때는 "◆ 행사_안내 ◆" (공백 하나)는 유사도가 높아 찾을 수 있지만
>> 특수문자를 제외하고 "행사안내" 로만 검색 할 때는 "행사_안내"는 유사도가 낮아 해당 구문을 찾을 수 없음
>> 특수문자를 제외하고 "행사안내" 로만 검색 할 때는 "행사 안내"는 유사도가 낮아 해당 구문을 찾을 수 없음
001473 노이솜
문제1 줄간격 180% 맞는데 오답처리(마지막 엔터값 때문인듯)
>> 1페이지의 문단 속성들의 줄간격이 180% 가 아닌 문단이 있으면 오답으로 처리중
>> 마지막 엔터값 줄간격 160%를 예외 처리할 기준이 모호함
>> 마지막 엔터값 줄간격 160%를 예외 처리할 기준이 아직 모호함