diff --git a/.gitignore b/.gitignore
index 7623fba..e91977e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,8 @@ output
회차별채점자료/*/정답파일
회차별채점자료/*/정답
+medias
+
# 열려있는 xlsx파일
~*.xlsx
psdExport_3.js
diff --git a/01_copy_files.py b/01_copy_files.py
new file mode 100644
index 0000000..a8fc961
--- /dev/null
+++ b/01_copy_files.py
@@ -0,0 +1,82 @@
+# 분류된 "과목별" 폴더에서 시험 파일을 복사하는 스크립트
+
+import os
+import shutil
+import re
+
+def copy_exam_files(exam_round, exam_codes, source_dir):
+ """
+ 시험 파일을 지정된 출력 폴더로 복사합니다.
+
+ Args:
+ exam_round (str): 시험 회차 (예: "2507")
+ exam_codes (list): 시험 코드 리스트 (예: ["DIC", "DPI"])
+ source_dir (str): 기본 소스 디렉토리 경로
+ """
+
+ created_test_folders = set() # TEST 폴더 중복 생성을 막기 위한 집합
+
+ for exam_code in exam_codes:
+ code_dir = os.path.join(source_dir, exam_code)
+
+ if not os.path.exists(code_dir):
+ print(f"⚠️ {exam_code} 디렉토리가 존재하지 않습니다.")
+ continue
+
+ # 폴더 이름이 A, B, C...로 시작하는 폴더만 인식
+ exam_types = []
+ for item in os.listdir(code_dir):
+ match = re.match(r"^([A-Z])", item)
+ if match:
+ exam_types.append((match.group(1), item)) # ("A", "A형" 또는 "A_정답")
+
+ if not exam_types:
+ print(f"⚠️ 시험 유형 디렉토리가 없습니다: {exam_code}")
+ continue
+
+ for exam_type, real_folder in exam_types:
+ source_folder = os.path.join(code_dir, real_folder)
+ target_path = os.path.join(".", "output", exam_round, exam_type, exam_code)
+
+ if not os.path.exists(source_folder):
+ print(f"⚠️ 건너뜀: {source_folder} 경로가 존재하지 않습니다.")
+ continue
+
+ os.makedirs(target_path, exist_ok=True)
+
+ # ✅ TEST 폴더 생성: input/회차/유형/TEST
+ test_folder = os.path.join("output", exam_round, exam_type, "TEST")
+ if test_folder not in created_test_folders:
+ os.makedirs(test_folder, exist_ok=True)
+ created_test_folders.add(test_folder)
+
+ print(f"\n🔄 복사 시작: {exam_code} - 유형: {exam_type} (폴더명: {real_folder})")
+ print(f"📂 원본 경로: {source_folder}")
+ print(f"📂 대상 경로: {target_path}")
+ print("-" * 60)
+
+ try:
+ for item in os.listdir(source_folder):
+ source_item = os.path.join(source_folder, item)
+ target_item = os.path.join(target_path, item)
+
+ if os.path.isdir(source_item):
+ shutil.copytree(source_item, target_item, dirs_exist_ok=True)
+ print(f"📁 폴더 복사: {source_item} ➡️ {target_item}")
+ else:
+ shutil.copy2(source_item, target_item)
+ print(f"📄 파일 복사: {source_item} ➡️ {target_item}")
+
+ print("-" * 60)
+ print(f"✅ 복사 완료: {exam_code} - {exam_type}")
+ except Exception as e:
+ print("-" * 60)
+ print(f"❌ 오류 발생: {exam_code} - {exam_type} - {e}")
+
+# 사용 예시
+if __name__ == "__main__":
+ exam_round = "2508"
+ exam_codes = ["DIC", "DPI"]
+ source_dir = r"D:\project\GOM\DIC\회차별채점자료\2508"
+
+ copy_exam_files(exam_round, exam_codes, source_dir)
diff --git a/00_DIC_2506A_TEST.xlsx b/250827_DIC_2508A_채점결과.xlsx
similarity index 62%
rename from 00_DIC_2506A_TEST.xlsx
rename to 250827_DIC_2508A_채점결과.xlsx
index 51a6104..19d93f2 100644
Binary files a/00_DIC_2506A_TEST.xlsx and b/250827_DIC_2508A_채점결과.xlsx differ
diff --git a/00_DIC_2506C_TEST.xlsx b/250827_DIC_2508C_채점결과.xlsx
similarity index 62%
rename from 00_DIC_2506C_TEST.xlsx
rename to 250827_DIC_2508C_채점결과.xlsx
index 84a7055..a44bb60 100644
Binary files a/00_DIC_2506C_TEST.xlsx and b/250827_DIC_2508C_채점결과.xlsx differ
diff --git a/00_DPI_2506C_TEST.xlsx b/250827_DPI_2508B_채점결과.xlsx
similarity index 71%
rename from 00_DPI_2506C_TEST.xlsx
rename to 250827_DPI_2508B_채점결과.xlsx
index 83e384d..c91fcf3 100644
Binary files a/00_DPI_2506C_TEST.xlsx and b/250827_DPI_2508B_채점결과.xlsx differ
diff --git a/250827_DPI_2508C_채점결과.xlsx b/250827_DPI_2508C_채점결과.xlsx
new file mode 100644
index 0000000..66ffa8e
Binary files /dev/null and b/250827_DPI_2508C_채점결과.xlsx differ
diff --git a/DIC_2507A.json b/DIC_2508A.json
similarity index 86%
rename from DIC_2507A.json
rename to DIC_2508A.json
index 587f9ce..95d8df9 100644
--- a/DIC_2507A.json
+++ b/DIC_2508A.json
@@ -57,8 +57,8 @@
"point": 0
},
"4": {
- "ele": "$.children[?(@.name=='계곡')].name",
- "value": "계곡",
+ "ele": "$.children[?(@.name=='전시실')].name",
+ "value": "전시실",
"point": 4
},
"5": {
@@ -66,30 +66,30 @@
"point": 0
},
"6": {
- "ele": "$.children[?(@.name=='In the Valley')].name",
- "value": "In the Valley",
+ "ele": "$.children[?(@.name=='Cartoon Museum')].name",
+ "value": "Cartoon Museum",
"point": 4
},
"7": {
- "ele": "$.children[?(@.name=='In the Valley')].text.font.names[0]",
+ "ele": "$.children[?(@.name=='Cartoon Museum')].text.font.names[0]",
"type": "font",
"value": "Arial",
"point": 2
},
"8": {
- "ele": "$.children[?(@.name=='In the Valley')].text.font.names[0]",
+ "ele": "$.children[?(@.name=='Cartoon Museum')].text.font.names[0]",
"value": "Arial-BoldItalicMT",
"point": 2
},
"9": {
- "ele": "$.children[?(@.name=='In the Valley')].text.font.sizes[0]",
+ "ele": "$.children[?(@.name=='Cartoon Museum')].text.font.sizes[0]",
"value": 48,
"point": 2
},
"10": {
- "ele": "$.children[?(@.name=='In the Valley')].text.font.colors[0]",
+ "ele": "$.children[?(@.name=='Cartoon Museum')].text.font.colors[0]",
"type": "color",
- "value": "fffc09",
+ "value": "3538cc",
"point": 2
},
"11": {
@@ -105,14 +105,14 @@
"point": 0
},
"14": {
- "ele": "$.children[?(@.name=='산속 계곡에서')].name",
- "value": "산속 계곡에서",
+ "ele": "$.children[?(@.name=='만화 박물관')].name",
+ "value": "만화 박물관",
"point": 4
},
"15": {
- "ele": "$.children[?(@.name=='산속 계곡에서')].text.font.names[0]",
+ "ele": "$.children[?(@.name=='만화 박물관')].text.font.names[0]",
"type": "font",
- "value": "GulimChe",
+ "value": "GungsuhChe",
"point": 2,
"desc": {
"돋움체": "DotumChe",
@@ -122,14 +122,14 @@
}
},
"16": {
- "ele": "$.children[?(@.name=='산속 계곡에서')].text.font.sizes[0]",
+ "ele": "$.children[?(@.name=='만화 박물관')].text.font.sizes[0]",
"value": 36,
"point": 2
},
"17": {
- "ele": "$.children[?(@.name=='산속 계곡에서')].text.font.colors[0]",
+ "ele": "$.children[?(@.name=='만화 박물관')].text.font.colors[0]",
"type": "color",
- "value": "05aa20",
+ "value": "35b1cc",
"point": 2
},
"18": {
@@ -149,8 +149,8 @@
"point": 0
},
"22": {
- "ele": "$.children[?(@.name=='노란꽃')].name",
- "value": "노란꽃",
+ "ele": "$.children[?(@.name=='뱀 캐릭터')].name",
+ "value": "뱀 캐릭터",
"point": 4
},
"23": {
@@ -184,7 +184,7 @@
"1": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex",
"type": "mediaOrder",
- "value": ["동영상.mp4", "이미지2.jpg", "이미지3.jpg", "이미지1.jpg"],
+ "value": ["동영상.mp4", "이미지3.jpg", "이미지2.jpg", "이미지1.jpg"],
"point": 4,
"desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다."
},
@@ -213,63 +213,63 @@
"type": "effect",
"media": "동영상.mp4",
"value": {
- "ID": "168",
- "VID100": "0.80000001",
- "VID102": "8"
+ "ID": "43",
+ "VID100": "9",
+ "VID103": "0.69999999"
},
"point": 3,
"desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요"
},
"5": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
- "search": "집을 드나드는 토끼",
+ "search": "만화 전시관",
"type": "video.Text",
- "value": "집을 드나드는 토끼",
+ "value": "만화 전시관",
"point": 3
},
"6": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
- "search": "집을 드나드는 토끼",
+ "search": "만화 전시관",
"type": "video.Text",
- "value": "궁서체",
+ "value": "굴림체",
"point": 2
},
"7": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
- "search": "집을 드나드는 토끼",
+ "search": "만화 전시관",
"type": "video.Text",
- "value": "98",
+ "value": "100",
"point": 2
},
"8": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
- "search": "집을 드나드는 토끼",
+ "search": "만화 전시관",
"type": "video.Text.Color",
- "value": "682f00",
+ "value": "ffeb3b",
"point": 2,
"desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
},
"9": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']",
- "search": "집을 드나드는 토끼",
+ "search": "만화 전시관",
"type": "video.Location",
- "value": ["0.33229166", "0.93703705"],
+ "value": ["0.39375001", "0.93333334"],
"point": 2,
"desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다"
},
"10": {
"ele": "",
- "search": "집을 드나드는 토끼",
+ "search": "만화 전시관",
"type": "video.StartTime",
- "value": 150,
+ "value": 160,
"point": 2,
"desc": "내부적으로 자막의 시작시간과 길이를 계산"
},
"11": {
"ele": "",
- "search": "집을 드나드는 토끼",
+ "search": "만화 전시관",
"type": "video.Length",
- "value": 120,
+ "value": 150,
"point": 2,
"desc": "내부적으로 자막의 시작시간과 길이를 계산"
},
@@ -283,17 +283,17 @@
"13": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
- "media": "이미지2.jpg",
+ "media": "이미지3.jpg",
"value": 180,
"point": 2
},
"14": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "imageOverlay",
- "media": "이미지2.jpg",
+ "media": "이미지3.jpg",
"value": {
- "ID": "103",
- "VID102": "8"
+ "ID": "94",
+ "VID101": "8"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -301,9 +301,9 @@
"15": {
"ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
"type": "clipTransition",
- "media": "이미지2.jpg",
+ "media": "이미지3.jpg",
"value": {
- "ID": "13",
+ "ID": "15",
"Range": "500:560",
"Type": "2"
},
@@ -313,17 +313,17 @@
"16": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
- "media": "이미지3.jpg",
- "value": 210,
+ "media": "이미지2.jpg",
+ "value": 150,
"point": 2
},
"17": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "imageOverlay",
- "media": "이미지3.jpg",
+ "media": "이미지2.jpg",
"value": {
- "ID": "128",
- "VID100": "3"
+ "ID": "104",
+ "VID100": "10"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -331,10 +331,10 @@
"18": {
"ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
"type": "clipTransition",
- "media": "이미지3.jpg",
+ "media": "이미지2.jpg",
"value": {
- "ID": "20",
- "Range": "710:770",
+ "ID": "35",
+ "Range": "680:710",
"Type": "2"
},
"point": 2,
@@ -344,7 +344,7 @@
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
"media": "이미지1.jpg",
- "value": 180,
+ "value": 150,
"point": 2
},
"20": {
@@ -352,8 +352,8 @@
"type": "imageOverlay",
"media": "이미지1.jpg",
"value": {
- "ID": "67",
- "VID101": "4"
+ "ID": "102",
+ "VID102": "10"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -363,8 +363,8 @@
"type": "clipTransition",
"media": "이미지1.jpg",
"value": {
- "ID": "10",
- "Range": "920:950",
+ "ID": "17",
+ "Range": "800:860",
"Type": "2"
},
"point": 2,
@@ -372,50 +372,50 @@
},
"22": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
- "search": "동물들의 생활 (Animal Life)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text",
- "value": "동물들의 생활 (Animal Life)",
+ "value": "만화 세상 (Cartoon World)",
"point": 3
},
"23": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
- "search": "동물들의 생활 (Animal Life)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text",
- "value": "휴먼옛체",
+ "value": "바탕체",
"point": 2
},
"24": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
- "search": "동물들의 생활 (Animal Life)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text",
- "value": "140",
+ "value": "120",
"point": 2
},
"25": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
- "search": "동물들의 생활 (Animal Life)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text.Color",
- "value": "d0f29c",
+ "value": "0cc762",
"point": 2,
"desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
},
"26": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']",
- "search": "동물들의 생활 (Animal Life)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text.Outline",
"value": {
"width": "20",
- "color": "1f5617"
+ "color": "ffe500"
},
"point": 2,
"desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성"
},
"27": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr",
- "search": "동물들의 생활 (Animal Life)",
+ "search": "만화 세상 (Cartoon World)",
"type": "opening.Text.FadeInEffect",
"value": {
- "VID505": "4",
+ "VID505": "5",
"VID507": "2"
},
"point": 3,
@@ -423,7 +423,7 @@
},
"28": {
"ele": "",
- "search": "동물들의 생활 (Animal Life)",
+ "search": "만화 세상 (Cartoon World)",
"type": "opening.StartTime",
"value": 0,
"point": 2,
@@ -431,7 +431,7 @@
},
"29": {
"ele": "",
- "search": "동물들의 생활 (Animal Life)",
+ "search": "만화 세상 (Cartoon World)",
"type": "opening.Length",
"value": 120,
"point": 2
@@ -447,7 +447,7 @@
"ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']",
"type": "audio.EndTime",
"media": "음악.mp3",
- "value": 890,
+ "value": 840,
"point": 2
},
"32": {
@@ -456,7 +456,7 @@
"media": "음악.mp3",
"value": {
"ID": "1",
- "Duration": "60"
+ "Duration": "90"
},
"point": 2,
"desc": "ID속성-페이드인:0 / 페이드아웃: 1"
@@ -504,8 +504,8 @@
"밝기/대비": ["밝기", "대비"],
"노출": "노출",
"색조/채도": ["색조", "채도", "명도"],
- "감마":["리프트","감마","게인"],
- "세피아":["U","V"],
+ "감마": ["리프트", "감마", "게인"],
+ "세피아": ["U", "V"],
"생동감": "생동감"
}
},
diff --git a/DPI_2507B.json b/DIC_2508C.json
similarity index 78%
rename from DPI_2507B.json
rename to DIC_2508C.json
index 85ba1e9..e37e08e 100644
--- a/DPI_2507B.json
+++ b/DIC_2508C.json
@@ -57,39 +57,40 @@
"point": 0
},
"4": {
+ "ele": "$.children[?(@.name=='하천')].name",
+ "value": "하천",
+ "point": 4
+ },
+ "5": {
"ele": "none",
"point": 0
},
- "5": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].name",
- "value": "My Friend Parrot",
+ "6": {
+ "ele": "$.children[?(@.name=='River Ecosystem')].name",
+ "value": "River Ecosystem",
"point": 4
},
- "6": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].text.font.names[0]",
+ "7": {
+ "ele": "$.children[?(@.name=='River Ecosystem')].text.font.names[0]",
"type": "font",
"value": "Arial",
"point": 2
},
- "7": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].text.font.names[0]",
+ "8": {
+ "ele": "$.children[?(@.name=='River Ecosystem')].text.font.names[0]",
"value": "Arial-BoldItalicMT",
"point": 2
},
- "8": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].text.font.sizes[0]",
+ "9": {
+ "ele": "$.children[?(@.name=='River Ecosystem')].text.font.sizes[0]",
"value": 48,
"point": 2
},
- "9": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].text.font.colors[0]",
- "type": "color",
- "value": "1bc553",
- "point": 2
- },
"10": {
- "ele": "none",
- "point": 0
+ "ele": "$.children[?(@.name=='River Ecosystem')].text.font.colors[0]",
+ "type": "color",
+ "value": "439bff",
+ "point": 2
},
"11": {
"ele": "none",
@@ -100,36 +101,37 @@
"point": 0
},
"13": {
- "ele": "$.children[?(@.name=='내 친구 앵무새')].name",
- "value": "내 친구 앵무새",
- "point": 4
+ "ele": "none",
+ "point": 0
},
"14": {
- "ele": "$.children[?(@.name=='내 친구 앵무새')].text.font.names[0]",
+ "ele": "$.children[?(@.name=='하천 생태계')].name",
+ "value": "하천 생태계",
+ "point": 4
+ },
+ "15": {
+ "ele": "$.children[?(@.name=='하천 생태계')].text.font.names[0]",
"type": "font",
- "value": "GungsuhChe",
+ "value": "Batang",
"point": 2,
"desc": {
"돋움체": "DotumChe",
"궁서체": "GungsuhChe",
"굴림체": "GulimChe",
+ "바탕체": "Batang",
"휴먼옛체": "YetR"
}
},
- "15": {
- "ele": "$.children[?(@.name=='내 친구 앵무새')].text.font.sizes[0]",
- "value": 36,
- "point": 2
- },
"16": {
- "ele": "$.children[?(@.name=='내 친구 앵무새')].text.font.colors[0]",
- "type": "color",
- "value": "ffea00",
+ "ele": "$.children[?(@.name=='하천 생태계')].text.font.sizes[0]",
+ "value": 30,
"point": 2
},
"17": {
- "ele": "none",
- "point": 0
+ "ele": "$.children[?(@.name=='하천 생태계')].text.font.colors[0]",
+ "type": "color",
+ "value": "ffd543",
+ "point": 2
},
"18": {
"ele": "none",
@@ -148,8 +150,9 @@
"point": 0
},
"22": {
- "ele": "none",
- "point": 0
+ "ele": "$.children[?(@.name=='물고기')].name",
+ "value": "물고기",
+ "point": 4
},
"23": {
"ele": "none",
@@ -164,19 +167,15 @@
"point": 0
},
"26": {
- "ele": "none",
- "point": 0
- },
- "27": {
- "ele": "$[?(@.width == 65 && @.height == 45)]",
+ "ele": "$[?(@.width == 65 && @.height == 35)]",
"type": "size",
"value": {
"width": 65,
- "height": 45
+ "height": 35
},
- "point": 4
+ "point": 5
},
- "28": {
+ "27": {
"ele": "none",
"point": 0,
"desc": "파일명 확인"
@@ -186,15 +185,15 @@
"1": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex",
"type": "mediaOrder",
- "value": ["동영상.mp4", "이미지3.jpg", "이미지1.jpg", "이미지2.jpg"],
+ "value": ["동영상.mp4", "이미지2.jpg", "이미지1.jpg", "이미지3.jpg"],
"point": 4,
- "desc": "클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다."
+ "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다."
},
"2": {
"ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed",
"type": "oneAnswer",
"value": {
- "speed": "120"
+ "speed": "150"
},
"point": 2,
"desc": "100당 1배속 / 130 = 1.3배속"
@@ -205,73 +204,73 @@
"media": "동영상.mp4",
"value": {
"start": "0",
- "end": "350"
+ "end": "380"
},
"point": 2,
- "desc": "start: 시작시간 / end: 재생시간( 12.20 = 12*30 + 20 = 380 )"
+ "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다."
},
"4": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "effect",
"media": "동영상.mp4",
"value": {
- "ID": "43",
- "VID100": "10",
- "VID103": "1.2"
+ "ID": "40",
+ "VID100": "30",
+ "VID103": "0.89999998"
},
"point": 3,
"desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요"
},
"5": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
- "search": "재미있는 테마공원",
+ "search": "하천에 사는 물고기",
"type": "video.Text",
- "value": "재미있는 테마공원",
+ "value": "하천에 사는 물고기",
"point": 3
},
"6": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
- "search": "재미있는 테마공원",
+ "search": "하천에 사는 물고기",
"type": "video.Text",
- "value": "바탕체",
+ "value": "궁서체",
"point": 2
},
"7": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
- "search": "재미있는 테마공원",
+ "search": "하천에 사는 물고기",
"type": "video.Text",
- "value": "110",
+ "value": "90",
"point": 2
},
"8": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
- "search": "재미있는 테마공원",
+ "search": "하천에 사는 물고기",
"type": "video.Text.Color",
- "value": "8c3030",
+ "value": "f116f2",
"point": 2,
"desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
},
"9": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']",
- "search": "재미있는 테마공원",
+ "search": "하천에 사는 물고기",
"type": "video.Location",
- "value": ["0.32291669", "0.92962962"],
+ "value": ["0.34583333", "0.94074076"],
"point": 2,
"desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다"
},
"10": {
"ele": "",
- "search": "재미있는 테마공원",
+ "search": "하천에 사는 물고기",
"type": "video.StartTime",
- "value": 160,
+ "value": 170,
"point": 2,
"desc": "내부적으로 자막의 시작시간과 길이를 계산"
},
"11": {
"ele": "",
- "search": "재미있는 테마공원",
+ "search": "하천에 사는 물고기",
"type": "video.Length",
- "value": 150,
+ "value": 180,
"point": 2,
"desc": "내부적으로 자막의 시작시간과 길이를 계산"
},
@@ -285,17 +284,17 @@
"13": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
- "media": "이미지3.jpg",
- "value": 180,
+ "media": "이미지2.jpg",
+ "value": 150,
"point": 2
},
"14": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "imageOverlay",
- "media": "이미지3.jpg",
+ "media": "이미지2.jpg",
"value": {
- "ID": "94",
- "VID101": "7"
+ "ID": "104",
+ "VID101": "5"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -303,9 +302,9 @@
"15": {
"ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
"type": "clipTransition",
- "media": "이미지3.jpg",
+ "media": "이미지2.jpg",
"value": {
- "ID": "32",
+ "ID": "14",
"Range": "470:530",
"Type": "2"
},
@@ -324,8 +323,8 @@
"type": "imageOverlay",
"media": "이미지1.jpg",
"value": {
- "ID": "99",
- "VID100": "70"
+ "ID": "94",
+ "VID101": "8"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -335,7 +334,7 @@
"type": "clipTransition",
"media": "이미지1.jpg",
"value": {
- "ID": "13",
+ "ID": "95",
"Range": "650:680",
"Type": "2"
},
@@ -345,17 +344,17 @@
"19": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
- "media": "이미지2.jpg",
- "value": 210,
+ "media": "이미지3.jpg",
+ "value": 180,
"point": 2
},
"20": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "imageOverlay",
- "media": "이미지2.jpg",
+ "media": "이미지3.jpg",
"value": {
- "ID": "102",
- "VID102": "10"
+ "ID": "96",
+ "VID101": "11"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -363,10 +362,10 @@
"21": {
"ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
"type": "clipTransition",
- "media": "이미지2.jpg",
+ "media": "이미지3.jpg",
"value": {
- "ID": "19",
- "Range": "830:890",
+ "ID": "9",
+ "Range": "800:860",
"Type": "2"
},
"point": 2,
@@ -374,50 +373,50 @@
},
"22": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
- "search": "스카이밸리 도깨비골 (Sky Valley)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text",
- "value": "스카이밸리 도깨비골 (Sky Valley)",
+ "value": "우리나라 하천의 물고기들 (Korean river fish)",
"point": 3
},
"23": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
- "search": "스카이밸리 도깨비골 (Sky Valley)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text",
- "value": "굴림체",
+ "value": "돋움체",
"point": 2
},
"24": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
- "search": "스카이밸리 도깨비골 (Sky Valley)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text",
- "value": "150",
+ "value": "140",
"point": 2
},
"25": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
- "search": "스카이밸리 도깨비골 (Sky Valley)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text.Color",
- "value": "31b45e",
+ "value": "ecd000",
"point": 2,
"desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
},
"26": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']",
- "search": "스카이밸리 도깨비골 (Sky Valley)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text.Outline",
"value": {
- "width": "35",
- "color": "ffffff"
+ "width": "10",
+ "color": "3c0000"
},
"point": 2,
"desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성"
},
"27": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr",
- "search": "스카이밸리 도깨비골 (Sky Valley)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "opening.Text.FadeInEffect",
"value": {
- "VID505": "3",
+ "VID505": "14",
"VID507": "2"
},
"point": 3,
@@ -425,7 +424,7 @@
},
"28": {
"ele": "",
- "search": "스카이밸리 도깨비골 (Sky Valley)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "opening.StartTime",
"value": 0,
"point": 2,
@@ -433,9 +432,9 @@
},
"29": {
"ele": "",
- "search": "스카이밸리 도깨비골 (Sky Valley)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "opening.Length",
- "value": 120,
+ "value": 150,
"point": 2
},
"30": {
@@ -449,7 +448,7 @@
"ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']",
"type": "audio.EndTime",
"media": "음악.mp3",
- "value": 870,
+ "value": 850,
"point": 2
},
"32": {
@@ -486,19 +485,18 @@
"3": {
"type": "layer.exists",
"ele": "//Layer/Name/@value",
- "value": "Valley",
+ "value": "Flower",
"point": 5,
- "desc": "Valley 레이어가 있는지 여부 체크"
+ "desc": "Flower 레이어가 있는지 여부 체크"
},
"4": {
"type": "layer.Effects",
- "ele": "//Layer/Effects/Item",
- "ele_temp": "//Layer[Name[@value='{search}']]/Effects/Item",
- "search": "Valley",
+ "ele": "//Layer[Name[@value='{search}']]/Effects/Item",
+ "search": "Flower",
"value": {
- "name": "선명하게",
+ "name": "생동감",
"option": {
- "양": "7"
+ "생동감": "40"
}
},
"point": 5,
@@ -509,11 +507,7 @@
"색조/채도": ["색조", "채도", "명도"],
"감마": ["리프트", "감마", "게인"],
"세피아": ["U", "V"],
- "생동감": "생동감",
- "흐리게": "반경",
- "글로우": ["반경", "밝기", "대비"],
- "픽셀효과": "셀크기",
- "선명하게": "양"
+ "생동감": "생동감"
}
},
"5": {
@@ -532,20 +526,16 @@
"7": {
"type": "exists",
"ele": "//Layer/Shapes/Shape/shape_type/@value",
- "value": "RECTANGLE",
+ "value": "ELLIPSE",
"point": 3,
- "desc": {
- "모서리가 둥근 사각형": "ROUNDED_RECTANGLE",
- "사각형": "RECTANGLE",
- "타원": "ELLIPSE"
- }
+ "desc": "레이어 쉐이프 타입이 타원인지 체크"
},
"8": {
"type": "shape.size",
"ele": "//Layer//op_points",
"value": {
- "width": 335,
- "height": 35
+ "width": 120,
+ "height": 120
},
"point": 3,
"desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
@@ -553,7 +543,7 @@
"9": {
"type": "shape.color",
"ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value",
- "value": "46A64A",
+ "value": "7097BB",
"point": 6,
"desc": ""
},
@@ -561,7 +551,7 @@
"type": "layer.blend.opacity",
"ele": "//Layer",
"value": {
- "BlendOp": "중첩",
+ "BlendOp": "반사",
"Opacity": "80"
},
"point": 6
@@ -610,15 +600,14 @@
"type": "exists",
"ele": "//Layer//shape_type/@value",
"value": "ROUNDED_RECTANGLE",
- "point": 3,
- "desc": "모서리가 둥근 사각형 : ROUNDED_RECTANGLE / 사각형 : RECTANGLE"
+ "point": 3
},
"6": {
"type": "shape.size",
"ele": "//Layer//op_points",
"value": {
"width": 400,
- "height": 50
+ "height": 60
},
"point": 3,
"desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
@@ -629,21 +618,21 @@
"startColor": "gradient_start_color/@value",
"endColor": "gradient_end_color/@value",
"value": {
- "startColor": "3CB241",
- "endColor": "931FAD"
+ "startColor": "ffe000",
+ "endColor": "34A159"
},
"point": 6
},
"8": {
"type": "text.exists",
"ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value",
- "value": "도깨비골 스카이밸리",
+ "value": "흰 꽃 사이 노란 꽃",
"point": 5
},
"9": {
"type": "exists",
"ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value",
- "value": "돋움",
+ "value": "맑은 고딕",
"point": 3
},
"10": {
@@ -656,25 +645,25 @@
"11": {
"type": "exists",
"ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value",
- "value": "24",
+ "value": "30",
"point": 3
},
"12": {
"type": "text.color",
"ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value",
- "value": "AA2318",
+ "value": "b46Ef8",
"point": 3
},
"13": {
"type": "exists",
"ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value",
- "value": "5",
+ "value": "7",
"point": 3
},
"14": {
"type": "text.color",
"ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value",
- "value": "FFFFFF",
+ "value": "ffffff",
"point": 3
},
"15": {
@@ -687,21 +676,19 @@
"16": {
"type": "exists",
"ele": "//Layer/Shapes/Shape/shape_type/@value",
- "value": "ELLIPSE",
+ "value": "RECTANGLE",
"point": 3,
"desc": {
- "사각형": "RECTANGLE",
- "원형/타원형": "ELLIPSE",
- "17~20 문항 option값 변경":""
+ "사각형": "RECTANGLE"
}
},
"17": {
"type": "clipping.size",
"ele": "//Layer//Shape[shape_type/@value='{option}']//op_points",
- "option": "ELLIPSE",
+ "option": "RECTANGLE",
"value": {
- "width": 170,
- "height": 170
+ "width": 150,
+ "height": 150
},
"point": 3,
"desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
@@ -709,26 +696,26 @@
"18": {
"type": "exists",
"ele": "//Layer//Shape[shape_type/@value='{option}']/outline_peninfo/Width/@value",
- "option": "ELLIPSE",
- "value": "3",
+ "option": "RECTANGLE",
+ "value": "7",
"point": 3
},
"19": {
"type": "clipping.color",
"ele": "//Layer//Shape[shape_type/@value='{option}' and contains(draw_type/@value, 'Outline')]/primary_color/@value",
- "option": "ELLIPSE",
- "value": "4B7E5C",
+ "option": "RECTANGLE",
+ "value": "e8e88e",
"point": 3,
"desc": "채우기:secondary_color, 외곽선:primary_color"
},
"20": {
"type": "shadow",
"ele": "//Layer//Shape[shape_type/@value='{option}']",
- "option": "ELLIPSE",
+ "option": "RECTANGLE",
"value": {
"shadow": true,
- "width": "5",
- "distance": "2",
+ "width": "3",
+ "distance": "5",
"blur": "1",
"angle": "320"
},
diff --git a/DPI_2508B.json b/DPI_2508B.json
new file mode 100644
index 0000000..6beaa76
--- /dev/null
+++ b/DPI_2508B.json
@@ -0,0 +1,737 @@
+{
+ "0": {
+ "1": {
+ "ele": "none",
+ "point": 0
+ },
+ "2": {
+ "ele": "none",
+ "point": 0
+ },
+ "3": {
+ "ele": "none",
+ "point": 0
+ },
+ "4": {
+ "ele": "none",
+ "point": 0
+ },
+ "5": {
+ "ele": "none",
+ "point": 0
+ },
+ "6": {
+ "ele": "none",
+ "point": 0
+ },
+ "7": {
+ "ele": "none",
+ "point": 0
+ },
+ "8": {
+ "ele": "$[?(@.width == 65 && @.height == 45)]",
+ "type": "size",
+ "value": {
+ "width": 65,
+ "height": 45
+ },
+ "point": 4
+ },
+ "9": {
+ "ele": "none",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ },
+ "1": {
+ "1": {
+ "ele": "none",
+ "point": 0
+ },
+ "2": {
+ "ele": "none",
+ "point": 0
+ },
+ "3": {
+ "ele": "none",
+ "point": 0
+ },
+ "4": {
+ "ele": "$.children[?(@.name=='산책길')].name",
+ "value": "산책길",
+ "point": 4
+ },
+ "5": {
+ "ele": "none",
+ "point": 0
+ },
+ "6": {
+ "ele": "$.children[?(@.name=='Healing Forest')].name",
+ "value": "Healing Forest",
+ "point": 4
+ },
+ "7": {
+ "ele": "$.children[?(@.name=='Healing Forest')].text.font.names[0]",
+ "type": "font",
+ "value": "Arial",
+ "point": 2
+ },
+ "8": {
+ "ele": "$.children[?(@.name=='Healing Forest')].text.font.names[0]",
+ "value": "Arial-BoldItalicMT",
+ "point": 2
+ },
+ "9": {
+ "ele": "$.children[?(@.name=='Healing Forest')].text.font.sizes[0]",
+ "value": 48,
+ "point": 2
+ },
+ "10": {
+ "ele": "$.children[?(@.name=='Healing Forest')].text.font.colors[0]",
+ "type": "color",
+ "value": "d93009",
+ "point": 2
+ },
+ "11": {
+ "ele": "none",
+ "point": 0
+ },
+ "12": {
+ "ele": "none",
+ "point": 0
+ },
+ "13": {
+ "ele": "none",
+ "point": 0
+ },
+ "14": {
+ "ele": "$.children[?(@.name=='치유의 숲')].name",
+ "value": "치유의 숲",
+ "point": 4
+ },
+ "15": {
+ "ele": "$.children[?(@.name=='치유의 숲')].text.font.names[0]",
+ "type": "font",
+ "value": "GungsuhChe",
+ "point": 2,
+ "desc": {
+ "돋움체": "DotumChe",
+ "궁서체": "GungsuhChe",
+ "굴림체": "GulimChe",
+ "휴먼옛체": "YetR"
+ }
+ },
+ "16": {
+ "ele": "$.children[?(@.name=='치유의 숲')].text.font.sizes[0]",
+ "value": 36,
+ "point": 2
+ },
+ "17": {
+ "ele": "$.children[?(@.name=='치유의 숲')].text.font.colors[0]",
+ "type": "color",
+ "value": "19ea4a",
+ "point": 2
+ },
+ "18": {
+ "ele": "none",
+ "point": 0
+ },
+ "19": {
+ "ele": "none",
+ "point": 0
+ },
+ "20": {
+ "ele": "none",
+ "point": 0
+ },
+ "21": {
+ "ele": "none",
+ "point": 0
+ },
+ "22": {
+ "ele": "$.children[?(@.name=='조각상')].name",
+ "value": "조각상",
+ "point": 4
+ },
+ "23": {
+ "ele": "none",
+ "point": 0
+ },
+ "24": {
+ "ele": "none",
+ "point": 0
+ },
+ "25": {
+ "ele": "none",
+ "point": 0
+ },
+ "26": {
+ "ele": "$[?(@.width == 65 && @.height == 35)]",
+ "type": "size",
+ "value": {
+ "width": 65,
+ "height": 35
+ },
+ "point": 5
+ },
+ "27": {
+ "ele": "none",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ },
+ "2": {
+ "1": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex",
+ "type": "mediaOrder",
+ "value": ["동영상.mp4", "이미지3.jpg", "이미지2.jpg", "이미지1.jpg"],
+ "point": 4,
+ "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다."
+ },
+ "2": {
+ "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed",
+ "type": "oneAnswer",
+ "value": {
+ "speed": "140"
+ },
+ "point": 2,
+ "desc": "100당 1배속 / 130 = 1.3배속"
+ },
+ "3": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']",
+ "type": "startEnd",
+ "media": "동영상.mp4",
+ "value": {
+ "start": "0",
+ "end": "370"
+ },
+ "point": 2,
+ "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다."
+ },
+ "4": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "effect",
+ "media": "동영상.mp4",
+ "value": {
+ "ID": "40",
+ "VID100": "30",
+ "VID103": "1.2"
+ },
+ "point": 3,
+ "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요"
+ },
+ "5": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
+ "search": "공룡시대",
+ "type": "video.Text",
+ "value": "공룡시대",
+ "point": 3
+ },
+ "6": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
+ "search": "공룡시대",
+ "type": "video.Text",
+ "value": "돋움체",
+ "point": 2
+ },
+ "7": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
+ "search": "공룡시대",
+ "type": "video.Text",
+ "value": "90",
+ "point": 2
+ },
+ "8": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
+ "search": "공룡시대",
+ "type": "video.Text.Color",
+ "value": "0cea00",
+ "point": 2,
+ "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
+ },
+ "9": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']",
+ "search": "공룡시대",
+ "type": "video.Location",
+ "value": ["0.42812499", "0.94074076"],
+ "point": 2,
+ "desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다"
+ },
+ "10": {
+ "ele": "",
+ "search": "공룡시대",
+ "type": "video.StartTime",
+ "value": 170,
+ "point": 2,
+ "desc": "내부적으로 자막의 시작시간과 길이를 계산"
+ },
+ "11": {
+ "ele": "",
+ "search": "공룡시대",
+ "type": "video.Length",
+ "value": 150,
+ "point": 2,
+ "desc": "내부적으로 자막의 시작시간과 길이를 계산"
+ },
+ "12": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Mute",
+ "type": "Mute",
+ "media": "동영상.mp4",
+ "value": "1",
+ "point": 2
+ },
+ "13": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
+ "type": "imageLength",
+ "media": "이미지3.jpg",
+ "value": 180,
+ "point": 2
+ },
+ "14": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "imageOverlay",
+ "media": "이미지3.jpg",
+ "value": {
+ "ID": "103",
+ "VID102": "10"
+ },
+ "point": 2,
+ "desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
+ },
+ "15": {
+ "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
+ "type": "clipTransition",
+ "media": "이미지3.jpg",
+ "value": {
+ "ID": "11",
+ "Range": "520:550",
+ "Type": "2"
+ },
+ "point": 2,
+ "desc": "오버랩일 경우 Type속성값 16으로 변경"
+ },
+ "16": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
+ "type": "imageLength",
+ "media": "이미지2.jpg",
+ "value": 180,
+ "point": 2
+ },
+ "17": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "imageOverlay",
+ "media": "이미지2.jpg",
+ "value": {
+ "ID": "102",
+ "VID101": "4"
+ },
+ "point": 2,
+ "desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
+ },
+ "18": {
+ "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
+ "type": "clipTransition",
+ "media": "이미지2.jpg",
+ "value": {
+ "ID": "13",
+ "Range": "700:730",
+ "Type": "2"
+ },
+ "point": 2,
+ "desc": "오버랩일 경우 Type속성값 16으로 변경"
+ },
+ "19": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
+ "type": "imageLength",
+ "media": "이미지1.jpg",
+ "value": 150,
+ "point": 2
+ },
+ "20": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "imageOverlay",
+ "media": "이미지1.jpg",
+ "value": {
+ "ID": "67",
+ "VID103": "6"
+ },
+ "point": 2,
+ "desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
+ },
+ "21": {
+ "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
+ "type": "clipTransition",
+ "media": "이미지1.jpg",
+ "value": {
+ "ID": "19",
+ "Range": "850:880",
+ "Type": "2"
+ },
+ "point": 2,
+ "desc": "오버랩일 경우 Type속성값 16으로 변경"
+ },
+ "22": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
+ "search": "공룡 탐험 (Dinosaur Exploration)",
+ "type": "video.Text",
+ "value": "공룡 탐험 (Dinosaur Exploration)",
+ "point": 3
+ },
+ "23": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
+ "search": "공룡 탐험 (Dinosaur Exploration)",
+ "type": "video.Text",
+ "value": "바탕체",
+ "point": 2
+ },
+ "24": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
+ "search": "공룡 탐험 (Dinosaur Exploration)",
+ "type": "video.Text",
+ "value": "140",
+ "point": 2
+ },
+ "25": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
+ "search": "공룡 탐험 (Dinosaur Exploration)",
+ "type": "video.Text.Color",
+ "value": "ff2c2c",
+ "point": 2,
+ "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
+ },
+ "26": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']",
+ "search": "공룡 탐험 (Dinosaur Exploration)",
+ "type": "video.Text.Outline",
+ "value": {
+ "width": "20",
+ "color": "0c0b53"
+ },
+ "point": 2,
+ "desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성"
+ },
+ "27": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr",
+ "search": "공룡 탐험 (Dinosaur Exploration)",
+ "type": "opening.Text.FadeInEffect",
+ "value": {
+ "VID505": "16",
+ "VID507": "2"
+ },
+ "point": 3,
+ "desc": "오프닝자막의 나타나기 효과를 확인하는 문항. id속성은 VID505, playtime속성은 VID507으로 XML 내부에 표기되어 있다."
+ },
+ "28": {
+ "ele": "",
+ "search": "공룡 탐험 (Dinosaur Exploration)",
+ "type": "opening.StartTime",
+ "value": 0,
+ "point": 2,
+ "desc": "오프닝자막의 시작시간 value 속성만 수정"
+ },
+ "29": {
+ "ele": "",
+ "search": "공룡 탐험 (Dinosaur Exploration)",
+ "type": "opening.Length",
+ "value": 150,
+ "point": 2
+ },
+ "30": {
+ "ele": "",
+ "type": "audio.StartTime",
+ "media": "음악.mp3",
+ "value": 0,
+ "point": 2
+ },
+ "31": {
+ "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']",
+ "type": "audio.EndTime",
+ "media": "음악.mp3",
+ "value": 870,
+ "point": 2
+ },
+ "32": {
+ "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "audio.Effect",
+ "media": "음악.mp3",
+ "value": {
+ "ID": "1",
+ "Duration": "90"
+ },
+ "point": 2,
+ "desc": "ID속성-페이드인:0 / 페이드아웃: 1"
+ },
+ "33": {
+ "ele": "none",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ },
+ "4": {
+ "1": {
+ "type": "canvas.Size",
+ "ele": "//Document/Width/@value | //Document/Height/@value",
+ "value": ["650", "350"],
+ "point": 5,
+ "desc": "캔버스 사이즈 650*350"
+ },
+ "2": {
+ "type": "none",
+ "ele": "",
+ "point": 5,
+ "desc": "자유 변형 문항은 채점 불가"
+ },
+ "3": {
+ "type": "layer.exists",
+ "ele": "//Layer/Name/@value",
+ "value": "Dinosaur",
+ "point": 5,
+ "desc": "Dinosaur 레이어가 있는지 여부 체크"
+ },
+ "4": {
+ "type": "layer.Effects",
+ "ele": "//Layer[Name[@value='{search}']]/Effects/Item",
+ "search": "Dinosaur",
+ "value": {
+ "name": "밝기/대비",
+ "option": {
+ "밝기": "20"
+ }
+ },
+ "point": 5,
+ "desc": {
+ "흑백": "강도",
+ "밝기/대비": ["밝기", "대비"],
+ "노출": "노출",
+ "색조/채도": ["색조", "채도", "명도"],
+ "감마":["리프트","감마","게인"],
+ "세피아":["U","V"],
+ "생동감": "생동감"
+ }
+ },
+ "5": {
+ "type": "none",
+ "ele": "",
+ "point": 6,
+ "desc": "올가미 도구/이미지 문항은 채점 불가"
+ },
+ "6": {
+ "type": "exists",
+ "ele": "//Layer/Effects/Item/Name/@value",
+ "value": "색조/채도",
+ "point": 6,
+ "desc": "색조/채도 효과가 있는지 여부 체크"
+ },
+ "7": {
+ "type": "exists",
+ "ele": "//Layer/Shapes/Shape/shape_type/@value",
+ "value": "ELLIPSE",
+ "point": 3,
+ "desc": "레이어 쉐이프 타입이 타원인지 체크"
+ },
+ "8": {
+ "type": "shape.size",
+ "ele": "//Layer//op_points",
+ "value": {
+ "width": 110,
+ "height": 90
+ },
+ "point": 3,
+ "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
+ },
+ "9": {
+ "type": "shape.color",
+ "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value",
+ "value": "FF0000",
+ "point": 6,
+ "desc": ""
+ },
+ "10": {
+ "type": "layer.blend.opacity",
+ "ele": "//Layer",
+ "value": {
+ "BlendOp": "색 굽기",
+ "Opacity": "70"
+ },
+ "point": 6
+ },
+ "11": {
+ "type": "none",
+ "ele": "",
+ "point": 0,
+ "desc": "기본설정"
+ },
+ "12": {
+ "type": "none",
+ "ele": "",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ },
+ "5": {
+ "1": {
+ "type": "canvas.Size",
+ "ele": "//Document/Width/@value | //Document/Height/@value",
+ "value": ["650", "450"],
+ "point": 5,
+ "desc": "캔버스 사이즈 650*450"
+ },
+ "2": {
+ "type": "none",
+ "ele": "",
+ "point": 5,
+ "desc": "배경색 문항은 채점 불가"
+ },
+ "3": {
+ "type": "exists",
+ "ele": "//Layer/MaskOpType/@value",
+ "value": "Layering",
+ "point": 6,
+ "desc": "레이어 마스크 설정 확인"
+ },
+ "4": {
+ "type": "none",
+ "ele": "",
+ "point": 6,
+ "desc": "가로방향 흐릿하게 문항은 채점 불가"
+ },
+ "5": {
+ "type": "exists",
+ "ele": "//Layer//shape_type/@value",
+ "value": "ROUNDED_RECTANGLE",
+ "point": 3
+ },
+ "6": {
+ "type": "shape.size",
+ "ele": "//Layer//op_points",
+ "value": {
+ "width": 360,
+ "height": 70
+ },
+ "point": 3,
+ "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
+ },
+ "7": {
+ "type": "gradient.color",
+ "ele": "//Layer/Shapes/Shape",
+ "startColor": "gradient_start_color/@value",
+ "endColor": "gradient_end_color/@value",
+ "value": {
+ "startColor": "E24A19",
+ "endColor": "ECEC2F"
+ },
+ "point": 6
+ },
+ "8": {
+ "type": "text.exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value",
+ "value": "공룡의 세계",
+ "point": 5
+ },
+ "9": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value",
+ "value": "돋움체",
+ "point": 3
+ },
+ "10": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/{style}/@value",
+ "style": "Bold",
+ "value": "True",
+ "point": 3
+ },
+ "11": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value",
+ "value": "40",
+ "point": 3
+ },
+ "12": {
+ "type": "text.color",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value",
+ "value": "8200DC",
+ "point": 3
+ },
+ "13": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value",
+ "value": "4",
+ "point": 3
+ },
+ "14": {
+ "type": "text.color",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value",
+ "value": "ffff8B",
+ "point": 3
+ },
+ "15": {
+ "type": "exists",
+ "ele": "//Layer/MaskOpType/@value",
+ "value": "Clipping",
+ "point": 6,
+ "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함"
+ },
+ "16": {
+ "type": "exists",
+ "ele": "//Layer/Shapes/Shape/shape_type/@value",
+ "value": "RECTANGLE",
+ "point": 3,
+ "desc": {
+ "사각형": "RECTANGLE"
+ }
+ },
+ "17": {
+ "type": "clipping.size",
+ "ele": "//Layer//Shape[shape_type/@value='{option}']//op_points",
+ "option": "RECTANGLE",
+ "value": {
+ "width": 160,
+ "height": 160
+ },
+ "point": 3,
+ "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
+ },
+ "18": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='{option}']/outline_peninfo/Width/@value",
+ "option": "RECTANGLE",
+ "value": "5",
+ "point": 3
+ },
+ "19": {
+ "type": "clipping.color",
+ "ele": "//Layer//Shape[shape_type/@value='{option}' and contains(draw_type/@value, 'Outline')]/primary_color/@value",
+ "option": "RECTANGLE",
+ "value": "8344FF",
+ "point": 3,
+ "desc": "채우기:secondary_color, 외곽선:primary_color"
+ },
+ "20": {
+ "type": "shadow",
+ "ele": "//Layer//Shape[shape_type/@value='{option}']",
+ "option": "RECTANGLE",
+ "value": {
+ "shadow": true,
+ "width": "7",
+ "distance": "3",
+ "blur": "2",
+ "angle": "320"
+ },
+ "point": 5,
+ "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점"
+ },
+ "21": {
+ "type": "none",
+ "ele": "",
+ "point": 0,
+ "desc": "기본설정"
+ },
+ "22": {
+ "type": "none",
+ "ele": "",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ }
+}
diff --git a/DPI_2508C.json b/DPI_2508C.json
new file mode 100644
index 0000000..6190da3
--- /dev/null
+++ b/DPI_2508C.json
@@ -0,0 +1,742 @@
+{
+ "0": {
+ "1": {
+ "ele": "none",
+ "point": 0
+ },
+ "2": {
+ "ele": "none",
+ "point": 0
+ },
+ "3": {
+ "ele": "none",
+ "point": 0
+ },
+ "4": {
+ "ele": "none",
+ "point": 0
+ },
+ "5": {
+ "ele": "none",
+ "point": 0
+ },
+ "6": {
+ "ele": "none",
+ "point": 0
+ },
+ "7": {
+ "ele": "none",
+ "point": 0
+ },
+ "8": {
+ "ele": "$[?(@.width == 65 && @.height == 45)]",
+ "type": "size",
+ "value": {
+ "width": 65,
+ "height": 45
+ },
+ "point": 4
+ },
+ "9": {
+ "ele": "none",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ },
+ "1": {
+ "1": {
+ "ele": "none",
+ "point": 0
+ },
+ "2": {
+ "ele": "none",
+ "point": 0
+ },
+ "3": {
+ "ele": "none",
+ "point": 0
+ },
+ "4": {
+ "ele": "$.children[?(@.name=='산책길')].name",
+ "value": "산책길",
+ "point": 4
+ },
+ "5": {
+ "ele": "none",
+ "point": 0
+ },
+ "6": {
+ "ele": "$.children[?(@.name=='Healing Forest')].name",
+ "value": "Healing Forest",
+ "point": 4
+ },
+ "7": {
+ "ele": "$.children[?(@.name=='Healing Forest')].text.font.names[0]",
+ "type": "font",
+ "value": "Arial",
+ "point": 2
+ },
+ "8": {
+ "ele": "$.children[?(@.name=='Healing Forest')].text.font.names[0]",
+ "value": "Arial-BoldItalicMT",
+ "point": 2
+ },
+ "9": {
+ "ele": "$.children[?(@.name=='Healing Forest')].text.font.sizes[0]",
+ "value": 48,
+ "point": 2
+ },
+ "10": {
+ "ele": "$.children[?(@.name=='Healing Forest')].text.font.colors[0]",
+ "type": "color",
+ "value": "d93009",
+ "point": 2
+ },
+ "11": {
+ "ele": "none",
+ "point": 0
+ },
+ "12": {
+ "ele": "none",
+ "point": 0
+ },
+ "13": {
+ "ele": "none",
+ "point": 0
+ },
+ "14": {
+ "ele": "$.children[?(@.name=='치유의 숲')].name",
+ "value": "치유의 숲",
+ "point": 4
+ },
+ "15": {
+ "ele": "$.children[?(@.name=='치유의 숲')].text.font.names[0]",
+ "type": "font",
+ "value": "GungsuhChe",
+ "point": 2,
+ "desc": {
+ "돋움체": "DotumChe",
+ "궁서체": "GungsuhChe",
+ "굴림체": "GulimChe",
+ "휴먼옛체": "YetR"
+ }
+ },
+ "16": {
+ "ele": "$.children[?(@.name=='치유의 숲')].text.font.sizes[0]",
+ "value": 36,
+ "point": 2
+ },
+ "17": {
+ "ele": "$.children[?(@.name=='치유의 숲')].text.font.colors[0]",
+ "type": "color",
+ "value": "19ea4a",
+ "point": 2
+ },
+ "18": {
+ "ele": "none",
+ "point": 0
+ },
+ "19": {
+ "ele": "none",
+ "point": 0
+ },
+ "20": {
+ "ele": "none",
+ "point": 0
+ },
+ "21": {
+ "ele": "none",
+ "point": 0
+ },
+ "22": {
+ "ele": "$.children[?(@.name=='조각상')].name",
+ "value": "조각상",
+ "point": 4
+ },
+ "23": {
+ "ele": "none",
+ "point": 0
+ },
+ "24": {
+ "ele": "none",
+ "point": 0
+ },
+ "25": {
+ "ele": "none",
+ "point": 0
+ },
+ "26": {
+ "ele": "$[?(@.width == 65 && @.height == 35)]",
+ "type": "size",
+ "value": {
+ "width": 65,
+ "height": 35
+ },
+ "point": 5
+ },
+ "27": {
+ "ele": "none",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ },
+ "2": {
+ "1": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex",
+ "type": "mediaOrder",
+ "value": ["동영상.mp4", "이미지2.jpg", "이미지1.jpg", "이미지3.jpg"],
+ "point": 4,
+ "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다."
+ },
+ "2": {
+ "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed",
+ "type": "oneAnswer",
+ "value": {
+ "speed": "150"
+ },
+ "point": 2,
+ "desc": "100당 1배속 / 130 = 1.3배속"
+ },
+ "3": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']",
+ "type": "startEnd",
+ "media": "동영상.mp4",
+ "value": {
+ "start": "0",
+ "end": "380"
+ },
+ "point": 2,
+ "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다."
+ },
+ "4": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "effect",
+ "media": "동영상.mp4",
+ "value": {
+ "ID": "40",
+ "VID100": "30",
+ "VID103": "0.89999998"
+ },
+ "point": 3,
+ "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요"
+ },
+ "5": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
+ "search": "하천에 사는 물고기",
+ "type": "video.Text",
+ "value": "하천에 사는 물고기",
+ "point": 3
+ },
+ "6": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
+ "search": "하천에 사는 물고기",
+ "type": "video.Text",
+ "value": "궁서체",
+ "point": 2
+ },
+ "7": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
+ "search": "하천에 사는 물고기",
+ "type": "video.Text",
+ "value": "90",
+ "point": 2
+ },
+ "8": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
+ "search": "하천에 사는 물고기",
+ "type": "video.Text.Color",
+ "value": "f116f2",
+ "point": 2,
+ "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
+ },
+ "9": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']",
+ "search": "하천에 사는 물고기",
+ "type": "video.Location",
+ "value": ["0.34583333", "0.94074076"],
+ "point": 2,
+ "desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다"
+ },
+ "10": {
+ "ele": "",
+ "search": "하천에 사는 물고기",
+ "type": "video.StartTime",
+ "value": 170,
+ "point": 2,
+ "desc": "내부적으로 자막의 시작시간과 길이를 계산"
+ },
+ "11": {
+ "ele": "",
+ "search": "하천에 사는 물고기",
+ "type": "video.Length",
+ "value": 180,
+ "point": 2,
+ "desc": "내부적으로 자막의 시작시간과 길이를 계산"
+ },
+ "12": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Mute",
+ "type": "Mute",
+ "media": "동영상.mp4",
+ "value": "1",
+ "point": 2
+ },
+ "13": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
+ "type": "imageLength",
+ "media": "이미지2.jpg",
+ "value": 150,
+ "point": 2
+ },
+ "14": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "imageOverlay",
+ "media": "이미지2.jpg",
+ "value": {
+ "ID": "104",
+ "VID102": "9"
+ },
+ "point": 2,
+ "desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
+ },
+ "15": {
+ "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
+ "type": "clipTransition",
+ "media": "이미지2.jpg",
+ "value": {
+ "ID": "14",
+ "Range": "470:530",
+ "Type": "2"
+ },
+ "point": 2,
+ "desc": "오버랩일 경우 Type속성값 16으로 변경"
+ },
+ "16": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
+ "type": "imageLength",
+ "media": "이미지1.jpg",
+ "value": 150,
+ "point": 2
+ },
+ "17": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "imageOverlay",
+ "media": "이미지1.jpg",
+ "value": {
+ "ID": "94",
+ "VID101": "8"
+ },
+ "point": 2,
+ "desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
+ },
+ "18": {
+ "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
+ "type": "clipTransition",
+ "media": "이미지1.jpg",
+ "value": {
+ "ID": "95",
+ "Range": "650:680",
+ "Type": "2"
+ },
+ "point": 2,
+ "desc": "오버랩일 경우 Type속성값 16으로 변경"
+ },
+ "19": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
+ "type": "imageLength",
+ "media": "이미지3.jpg",
+ "value": 180,
+ "point": 2
+ },
+ "20": {
+ "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "imageOverlay",
+ "media": "이미지3.jpg",
+ "value": {
+ "ID": "96",
+ "VID101": "11"
+ },
+ "point": 2,
+ "desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
+ },
+ "21": {
+ "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
+ "type": "clipTransition",
+ "media": "이미지3.jpg",
+ "value": {
+ "ID": "9",
+ "Range": "800:860",
+ "Type": "2"
+ },
+ "point": 2,
+ "desc": "오버랩일 경우 Type속성값 16으로 변경"
+ },
+ "22": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
+ "type": "video.Text",
+ "value": "우리나라 하천의 물고기들 (Korean river fish)",
+ "point": 3
+ },
+ "23": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
+ "type": "video.Text",
+ "value": "돋움체",
+ "point": 2
+ },
+ "24": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
+ "type": "video.Text",
+ "value": "140",
+ "point": 2
+ },
+ "25": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
+ "type": "video.Text.Color",
+ "value": "ecd000",
+ "point": 2,
+ "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
+ },
+ "26": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
+ "type": "video.Text.Outline",
+ "value": {
+ "width": "10",
+ "color": "3c0000"
+ },
+ "point": 2,
+ "desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성"
+ },
+ "27": {
+ "ele": "//CROwneUnit[{index}]/CRCUnitArr",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
+ "type": "opening.Text.FadeInEffect",
+ "value": {
+ "VID505": "14",
+ "VID507": "2"
+ },
+ "point": 3,
+ "desc": "오프닝자막의 나타나기 효과를 확인하는 문항. id속성은 VID505, playtime속성은 VID507으로 XML 내부에 표기되어 있다."
+ },
+ "28": {
+ "ele": "",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
+ "type": "opening.StartTime",
+ "value": 0,
+ "point": 2,
+ "desc": "오프닝자막의 시작시간 value 속성만 수정"
+ },
+ "29": {
+ "ele": "",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
+ "type": "opening.Length",
+ "value": 150,
+ "point": 2
+ },
+ "30": {
+ "ele": "",
+ "type": "audio.StartTime",
+ "media": "음악.mp3",
+ "value": 0,
+ "point": 2
+ },
+ "31": {
+ "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']",
+ "type": "audio.EndTime",
+ "media": "음악.mp3",
+ "value": 850,
+ "point": 2
+ },
+ "32": {
+ "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
+ "type": "audio.Effect",
+ "media": "음악.mp3",
+ "value": {
+ "ID": "1",
+ "Duration": "90"
+ },
+ "point": 2,
+ "desc": "ID속성-페이드인:0 / 페이드아웃: 1"
+ },
+ "33": {
+ "ele": "none",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ },
+ "4": {
+ "1": {
+ "type": "canvas.Size",
+ "ele": "//Document/Width/@value | //Document/Height/@value",
+ "value": ["650", "350"],
+ "point": 5,
+ "desc": "캔버스 사이즈 650*350"
+ },
+ "2": {
+ "type": "none",
+ "ele": "",
+ "point": 5,
+ "desc": "자유 변형 문항은 채점 불가"
+ },
+ "3": {
+ "type": "layer.exists",
+ "ele": "//Layer/Name/@value",
+ "value": "Vacation",
+ "point": 5,
+ "desc": "Vacation 레이어가 있는지 여부 체크"
+ },
+ "4": {
+ "type": "layer.Effects",
+ "ele": "//Layer[Name[@value='{search}']]/Effects/Item",
+ "search": "Vacation",
+ "value": {
+ "name": "밝기/대비",
+ "option": {
+ "대비": "24"
+ }
+ },
+ "point": 5,
+ "desc": {
+ "흑백": "강도",
+ "밝기/대비": ["밝기", "대비"],
+ "노출": "노출",
+ "색조/채도": ["색조", "채도", "명도"],
+ "감마": ["리프트", "감마", "게인"],
+ "세피아": ["U", "V"],
+ "생동감": "생동감"
+ }
+ },
+ "5": {
+ "type": "none",
+ "ele": "",
+ "point": 6,
+ "desc": "올가미 도구/이미지 문항은 채점 불가"
+ },
+ "6": {
+ "type": "exists",
+ "ele": "//Layer/Effects/Item/Name/@value",
+ "value": "세피아",
+ "point": 6,
+ "desc": "세피아 효과가 있는지 여부 체크"
+ },
+ "7": {
+ "type": "exists",
+ "ele": "//Layer/Shapes/Shape/shape_type/@value",
+ "value": "ELLIPSE",
+ "point": 3,
+ "desc": "레이어 쉐이프 타입이 타원인지 체크"
+ },
+ "8": {
+ "type": "shape.size",
+ "ele": "//Layer//op_points",
+ "value": {
+ "width": 100,
+ "height": 80
+ },
+ "point": 3,
+ "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
+ },
+ "9": {
+ "type": "shape.color",
+ "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value",
+ "value": "316CE4",
+ "point": 6,
+ "desc": ""
+ },
+ "10": {
+ "type": "layer.blend.opacity",
+ "ele": "//Layer",
+ "value": {
+ "BlendOp": "색 굽기",
+ "Opacity": "65"
+ },
+ "point": 6
+ },
+ "11": {
+ "type": "none",
+ "ele": "",
+ "point": 0,
+ "desc": "기본설정"
+ },
+ "12": {
+ "type": "none",
+ "ele": "",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ },
+ "5": {
+ "1": {
+ "type": "canvas.Size",
+ "ele": "//Document/Width/@value | //Document/Height/@value",
+ "value": ["650", "450"],
+ "point": 5,
+ "desc": "캔버스 사이즈 650*450"
+ },
+ "2": {
+ "type": "none",
+ "ele": "",
+ "point": 5,
+ "desc": "배경색 문항은 채점 불가"
+ },
+ "3": {
+ "type": "exists",
+ "ele": "//Layer/MaskOpType/@value",
+ "value": "Layering",
+ "point": 6,
+ "desc": "레이어 마스크 설정 확인"
+ },
+ "4": {
+ "type": "none",
+ "ele": "",
+ "point": 6,
+ "desc": "가로방향 흐릿하게 문항은 채점 불가"
+ },
+ "5": {
+ "type": "exists",
+ "ele": "//Layer//shape_type/@value",
+ "value": "RECTANGLE",
+ "point": 3,
+ "desc": {
+ "사각형": "RECTANGLE",
+ "모서리가 둥근 사각형": "ROUNDED_RECTANGLE"
+ }
+ },
+ "6": {
+ "type": "shape.size",
+ "ele": "//Layer//op_points",
+ "value": {
+ "width": 500,
+ "height": 60
+ },
+ "point": 3,
+ "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
+ },
+ "7": {
+ "type": "gradient.color",
+ "ele": "//Layer/Shapes/Shape",
+ "startColor": "gradient_start_color/@value",
+ "endColor": "gradient_end_color/@value",
+ "value": {
+ "startColor": "8BED53",
+ "endColor": "FFE52A"
+ },
+ "point": 6
+ },
+ "8": {
+ "type": "text.exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value",
+ "value": "하천의 먹이사슬 구조",
+ "point": 5
+ },
+ "9": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value",
+ "value": "맑은 고딕",
+ "point": 3
+ },
+ "10": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/{style}/@value",
+ "style": "Underline",
+ "value": "True",
+ "point": 3
+ },
+ "11": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value",
+ "value": "26",
+ "point": 3
+ },
+ "12": {
+ "type": "text.color",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value",
+ "value": "F04DA5",
+ "point": 3
+ },
+ "13": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value",
+ "value": "5",
+ "point": 3
+ },
+ "14": {
+ "type": "text.color",
+ "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value",
+ "value": "ffffff",
+ "point": 3
+ },
+ "15": {
+ "type": "exists",
+ "ele": "//Layer/MaskOpType/@value",
+ "value": "Clipping",
+ "point": 6,
+ "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함"
+ },
+ "16": {
+ "type": "exists",
+ "ele": "//Layer/Shapes/Shape/shape_type/@value",
+ "value": "ROUNDED_RECTANGLE",
+ "point": 3,
+ "desc": {
+ "사각형": "RECTANGLE",
+ "모서리가 둥근 사각형": "ROUNDED_RECTANGLE"
+ }
+ },
+ "17": {
+ "type": "clipping.size",
+ "ele": "//Layer//Shape[shape_type/@value='{option}']//op_points",
+ "option": "ROUNDED_RECTANGLE",
+ "value": {
+ "width": 160,
+ "height": 160
+ },
+ "point": 3,
+ "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
+ },
+ "18": {
+ "type": "exists",
+ "ele": "//Layer//Shape[shape_type/@value='{option}']/outline_peninfo/Width/@value",
+ "option": "ROUNDED_RECTANGLE",
+ "value": "4",
+ "point": 3
+ },
+ "19": {
+ "type": "clipping.color",
+ "ele": "//Layer//Shape[shape_type/@value='{option}' and contains(draw_type/@value, 'Outline')]/primary_color/@value",
+ "option": "ROUNDED_RECTANGLE",
+ "value": "92DAAA",
+ "point": 3,
+ "desc": "채우기:secondary_color, 외곽선:primary_color"
+ },
+ "20": {
+ "type": "shadow",
+ "ele": "//Layer//Shape[shape_type/@value='{option}']",
+ "option": "ROUNDED_RECTANGLE",
+ "value": {
+ "shadow": true,
+ "width": "5",
+ "distance": "20",
+ "blur": "1",
+ "angle": "320"
+ },
+ "point": 5,
+ "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점"
+ },
+ "21": {
+ "type": "none",
+ "ele": "",
+ "point": 0,
+ "desc": "기본설정"
+ },
+ "22": {
+ "type": "none",
+ "ele": "",
+ "point": 0,
+ "desc": "파일명 확인"
+ }
+ }
+}
diff --git a/01_copyFiles.py b/copyFiles.py
similarity index 95%
rename from 01_copyFiles.py
rename to copyFiles.py
index 29a4e21..9917580 100644
--- a/01_copyFiles.py
+++ b/copyFiles.py
@@ -38,8 +38,8 @@ def copy_dic_subdirs(source_root, target_root_a, target_root_b, target_root_c, t
print(f"Skipping {dir_name} under {parent_dir}, as it doesn't match '2교시' or '3교시'.")
# 사용법
-exam_round = "2507"
-source_directory = r"D:\project\GOM\DIC\회차별채점자료\2507\정답" # 원본 디렉토리 경로
+exam_round = "2508"
+source_directory = r"D:\project\data\제2507회 정기\답안파일\과목별" # 원본 디렉토리 경로
target_directory_a = f".\\output\\{exam_round}\\A" # '1교시'의 타겟 경로
target_directory_b = f".\\output\\{exam_round}\\B" # '2교시'의 타겟 경로
diff --git a/psdExport.js b/psdExport.js
deleted file mode 100644
index 6037ba0..0000000
--- a/psdExport.js
+++ /dev/null
@@ -1,405 +0,0 @@
-const jsonPath = require('jsonpath');
-const XLSX = require('xlsx');
-const psd = require('psd');
-const fs = require('fs');
-const path = require('path');
-const xpath = require('xpath');
-const { DOMParser } = require('xmldom');
-
-// 복사된 답안 파일 폴더
-const answerFilesDir = './output/B/DIC/';
-
-// 답안 폴더 내부에 디렉토리가 아닌 일반 파일이 있을 경우 디렉토리만 필터링 해서 불러옴
-const studentDirs = fs.readdirSync(answerFilesDir).filter(file => {
- const filePath = path.join(answerFilesDir, file);
- return fs.statSync(filePath).isDirectory();
-});
-
-//const students = fs.readdirSync(answerFilesDir);
-
-// 기준표 파일 읽기
-const scoring = require('./제2501회 정기 DIC B형_old.json');
-
-const psdData = [];
-// 채점 결과 리스트
-const gradingResults = [];
-
-studentDirs.forEach(student => {
- // 맥에서 한글 디렉토리 이름을 읽어서 엑셀에 저장 할 시 자소 분리가 되어 저장되는 문제 노말라이즈해서 해결
- const name = student.normalize('NFC');
- const studentDir = path.join(answerFilesDir, student);
- const psdFiles = fs.readdirSync(studentDir).filter(file => file.endsWith('.psd'));
- const gmepFile = fs.readdirSync(studentDir).filter(file => file.endsWith('.gmep'));
-
- // 학생 이름을 key로 하는 객체 생성
- const gradingResult = {
- 0: name
- };
-
- psdFiles.forEach((psdFile, index) => {
- const psdPath = path.join('./', studentDir, psdFile);
- console.log(`Reading ${psdPath}...`);
- psdData[index] = psd.fromFile(psdPath);
- psdData[index].parse();
- gradingResult[index + 1] = getScore(psdData, scoring, index);
- });
- gmepFile.forEach((gmep, index) => {
- const gmepPath = path.join('./', studentDir, gmep);
- console.log(`Reading ${gmepPath}...`);
- const xmlContent = fs.readFileSync(gmepPath, 'utf8');
- // XML 파싱
- const doc = new DOMParser().parseFromString(xmlContent, 'application/xml');
- // console.log('doc:', doc);
-
- gradingResult[3] = getGmepScore(doc, scoring, 2);
- });
- gradingResults.push(gradingResult);
-});
-
-// 엑셀 파일 생성
-
-// Flatten the resultData for better representation in Excel
-const flattenedData = gradingResults.map(student => {
- const name = student["0"]
- const flattened = { "학생": student["0"] };
- Object.keys(student).forEach(key => {
- if (key !== "0") {
- Object.keys(student[key]).forEach(subKey => {
- flattened[`${key}_${subKey}`] = student[key][subKey];
- });
- }
- });
- return flattened;
-});
-// console.log(flattenedData);
-
-const worksheet = XLSX.utils.json_to_sheet(flattenedData);
-const workbook = XLSX.utils.book_new();
-
-// Add the worksheet to the workbook
-XLSX.utils.book_append_sheet(workbook, worksheet, '채점 결과');
-
-// 엑셀 파일 저장
-XLSX.writeFile(workbook, 'output.xlsx');
-console.log('채점 결과가 output.xlsx 파일에 저장되었습니다.');
-
-
-// xml 형식의 gmep 파일을 읽어서 점수를 계산
-// scoring.json 파일 내에 있는 ele 요소는 xmlpath 형식으로 접근하여 요소를 탐색하고 나오는 값을 value와 비교하여 점수를 계산
-// scoring.json 파일 내에 있는 type은 비교할 값의 타입을 의미하며, boolean, array 등이 있음
-// scoring.json 파일 내에 있는 type에 따라 비교하는 방식이 달라짐
-// 채점 결과를 gradingResults 배열에 저장
-function getGmepScore(gmepData, scoring, index) {
- const doc = gmepData;
- const gradingResult = {};
-
- const scoringData = scoring[index];
- // console.log(scoringData);
-
- let totalScore = 0;
- for (const key in scoringData) {
- const ele = scoringData[key].ele;
- const value = scoringData[key].value;
- const point = scoringData[key].point;
- const type = scoringData[key].type;
- console.log(`example number: ${key}`);
- if (ele === 'none') {
- gradingResult[key] = "확인필요";
- continue;
- }
-
- if (type == "boolean") {
- gradingResult[key] = result.length > 0 ? point : 0;
- }
- else if (type == "array") {
- // result: Path="동영상.mp4", Path="음악.mp3", Path="이미지2.jpg", Path="이미지1.jpg"
- // value: 동영상.mp4,이미지1.jpg,이미지3.jpg,이미지2.jpg
- // result 와 value를 순서대로 비교하여 모두 같으면 점수 point 부여
-
- // XPath를 사용하여 CRTrackList Name="비디오1" 요소 찾기
- const trackListNode = xpath.select1('//CRVideoTrackArr/CRTrackList[@Name="비디오1"]', doc);
- const values = [];
- let isSame = true;
-
- if (trackListNode) {
- // CRTrackClip 요소의 ClipIndex를 참조하여 CRClip 요소의 Path와 Type 출력
- const clipIndexes = xpath.select('CRTrackClip/@ClipIndex', trackListNode);
- clipIndexes.forEach(indexNode => {
- const clipIndex = parseInt(indexNode.value, 10) + 1; // XPath는 1-based index를 사용
- console.log(`clipIndex: ${clipIndex}`);
- if (clipIndex === 0) {
- return;
- }
- const clipPathNode = xpath.select1(`//CRClipArr/CRClip[${clipIndex}]/@Path`, doc);
-
- if (clipPathNode === undefined) {
- console.log(`clipPathNode: undefined`);
- return;
- }
- console.log(`clipPathNode: ${clipPathNode.value}`);
- values.push(clipPathNode.value);
- });
- // values에 값이 있는지 확인
- if (values.length == 0) {
- console.log('values length 0');
- gradingResult[key] = 0;
- continue;
- }
- values.forEach((v, i) => {
- console.log(`values: ${v} value: ${value[i]}`);
- if (value[i] !== v) {
- isSame = false;
- }
- });
- totalScore += isSame ? point : 0;
- gradingResult[key] = isSame ? point : 0;
- } else {
- console.log('CRTrackList with Name="비디오1" not found.');
- gradingResult[key] = 0;
- }
- }
- else if (type == "startend") {
- console.log('type:', type);
- const start = scoringData[key].start;
- const end = scoringData[key].end;
- // XPath를 사용하여 CRClip 요소 중 Path가 '동영상.mp4'인 요소의 위치 찾기
- const clipIndexNode = xpath.select1(ele, doc);
- console.log(`clipIndexNode: ${clipIndexNode}`);
-
- // XPath를 사용하여 해당 ClipIndex를 사용하는 CRTrackClip 요소 찾기
- const trackClipNodes = xpath.select1(`//CRTrackClip[@ClipIndex='${clipIndexNode}']`, doc);
-
- if (!trackClipNodes) {
- gradingResult[key] = 0;
- continue;
- }
- const posNode = xpath.select1('@Pos', trackClipNodes);
- const lengthNode = xpath.select1('@Length', trackClipNodes);
- console.log(`Pos: ${posNode.value}, Length: ${lengthNode.value}`);
-
- gradingResult[key] = posNode.value === start && lengthNode.value === end ? point : 0;
- totalScore += posNode.value === start && lengthNode.value === end ? point : 0;
-
- }
- else if (type == "subtitle") {
- const result = xpath.select(ele, doc);
- const length = scoringData[key].length;
- // 결과는 배열로 나오는데 2개 일 경우가 있음
-
- if (result.length !== length) {
- gradingResult[key] = 0;
- continue;
- }
-
- gradingResult[key] = point;
- totalScore += point;
- }
- else if (type == "color") {
- const result = xpath.select(ele, doc);
-
- if (result.length == 0) {
- gradingResult[key] = 0;
- continue;
- }
-
- console.log(`value: ${value} result: ${result[0].value}`);
- // value와 result[0].value를 비교하여 같으면 점수 point 부여
- totalScore += result.length > 0 && value === result[0].value ? point : 0;
- gradingResult[key] = result.length > 0 && value === result[0].value ? point : 0;
-
- }
- else if (type == "multi") {
- try {
- const result = xpath.select(ele, doc);
- let isSame = true;
- // console.log(`ele: ${ele}, value: ${value} result: ${result}`);
-
- if (result.length == 0) {
- console.log('result length 0');
- gradingResult[key] = 0;
- continue;
- }
-
- result.forEach((v, i) => {
- // value[i] 값이 정수형인 경우에는 float로 변환하여 비교
- // 정수형 v값을 float 형으로 변환하고 소수점 3자리까지 버림
- let temp = v.value;
- let answer = value[i];
-
- if (Number.isFinite(value[i]) && !Number.isInteger(value[i])) {
- temp = parseFloat(v.value);
- answer = parseFloat(value[i]);
- // 소수점 3자리까지 버림
- temp = Math.floor(temp * 1000) / 1000;
- }
- // answer 문자열 중 : 가 포함되어 있다면 각각 분리하고 그 값의 차이를 구함
- if (typeof answer == "string" && answer.indexOf(':') > -1) {
- const [answerStart, answerEnd] = answer.split(':').map(Number);
- const [tempStart, tempEnd] = temp.split(':').map(Number);
- answer = answerEnd - answerStart;
- temp = tempEnd - tempStart;
- }
-
- console.log(`temp: ${temp} answer: ${answer}`);
- if (answer !== temp) {
- console.log(`answer !== temp`);
- isSame = false;
- }
- });
- totalScore += isSame ? point : 0;
- gradingResult[key] = isSame ? point : 0;
- } catch (e) {
- console.log('err :', e);
- gradingResult[key] = 0;
- }
- }
- else if (type == "searchIndex") {
- let existEle = scoringData[key].existEle;
- // XPath를 사용하여 ELE 요소가 존재하는지 확인
- const crcUnitArrNode = xpath.select1(existEle, doc);
-
- if (crcUnitArrNode) {
- // ELE 요소가 몇번째 요소인지 찾고 필요한 요소 확인
- const unitOrderNode = xpath.select1(ele, doc);
- console.log(`unitOrderNode: ${unitOrderNode}`);
- if (unitOrderNode === undefined) {
- gradingResult[key] = 0;
- continue;
- }
- if (unitOrderNode.value === value) {
- console.log(`unit: ${unitOrderNode.value} === ${value}`);
- gradingResult[key] = point;
- totalScore += point;
- }
- else if (unitOrderNode === value) {
- console.log(`unitValue: ${unitOrderNode} === ${value}`);
- gradingResult[key] = point;
- totalScore += point;
- }
- else {
- gradingResult[key] = 0;
- }
-
- } else {
- console.log(`not found. ${existEle} `);
- gradingResult[key] = 0;
- }
- }
- else {
- const ele2 = scoringData[key].ele2;
-
- console.log('Unknown type:', ele);
- let result = xpath.select(ele, doc);
- let result2 = null;
- let isCheck = false;
-
- if (result.length == 0) {
- isCheck = true;
- }
- if (isCheck && ele2) {
- result2 = xpath.select(ele2, doc);
-
- if (result2.length == 0) {
- gradingResult[key] = 0;
- continue;
- }
-
- result = result2;
- console.log(`1st isChecked: ${isCheck}, result: ${result}`)
- }
-
- // console.log(`result: ${result[0].value}`);
- // value와 result[0].value를 비교하여 같으면 점수 point 부여
- // console.log(`${(value === result[0].value)}, ${result.length > 0 && value === result[0].value} `)
- console.log(`2nd isChecked: ${isCheck}, result: ${result}`)
- totalScore += result.length > 0 ? point : 0;
- gradingResult[key] = result.length > 0 ? point : 0;
- }
- }
-
-
- gradingResult['총점'] = totalScore;
- return gradingResult;
-}
-
-
-// psdData를 scoring.json 파일 내에 있는 ele 요소의 jsonpath로 접근하여 요소를 탐색하고 나오는 값을 value와 비교하여 점수를 계산
-// 학생 별로 psdData는 2개씩 있으므로 PSD 파일 1번과 2번에 대해서 채점
-// scoring.json 파일에 있는 항목 수만큼 점수를 계산
-// scoring.json 파일의 1번째 배열은 PSD 파일 1번에 대한 점수 계산
-// scoring.json 파일의 2번째 배열은 PSD 파일 2번에 대한 점수 계산
-// 채점 결과를 gradingResults 배열에 저장
-function getScore(psdData, scoring, index) {
- const psdTree = psdData[index].tree().export();
- const jsonData = JSON.stringify(psdTree, null, 2);
- // console.log(jsonData);
- const gradingResult = {};
-
- const scoringData = scoring[index];
- let totalScore = 0;
- for (const key in scoringData) {
- const ele = scoringData[key].ele;
- const value = scoringData[key].value;
- const point = scoringData[key].point;
- const type = scoringData[key].type;
-
- if (ele === 'none') {
- gradingResult[key] = "확인필요";
- continue;
- }
-
- try {
- const result = jsonPath.query(psdTree, ele);
- console.log(`ele: ${ele}, value: ${value} result: ${result}`);
- if (result.length == 0) {
- gradingResult[key] = 0;
- continue;
- }
- if (type == "boolean") {
- // console.log(`result ${result.length}`);
-
- gradingResult[key] = result.length > 0 ? point : 0;
- }
- // value가 color code인 경우 R,G,B를 16진수로 변환하여 비교하고 같다면 점수 부여
- // value: "ffa200"
- // result: [255,162,0,255]
- // 255,162,0,255 -> ffa200
- else if (type == "color") {
- // console.log(`result ${result}`); // result 255,162,0,255
- const temp = result[0].slice(0, 3).join(','); // 255,162,0
- color = temp.split(',').map(v => parseInt(v).toString(16)).join(''); // ffa20
- // ffa20 -> ffa200
- if (color.length == 5) {
- color = color + '0';
- }
-
- // console.log(`color: ${color}`);
- gradingResult[key] = result.length > 0 && value === color ? point : 0;
- }
-
-
- // type이 font인 경우 font의 이름만 추출하여 비교
- // value: "Arial"
- // result: ["Arial-BoldItalicMT"]
- else if (type == "font") {
- // console.log(`result ${result}`);
- const font = result[0].split('-')[0];
- // console.log(`font: ${font}`);
- gradingResult[key] = result.length > 0 && value === font ? point : 0;
- }
-
- else if (result[0] === value) {
- gradingResult[key] = point;
- totalScore += point;
- } else {
- gradingResult[key] = 0;
- }
- } catch (error) {
- console.error(`Error processing JSONPath query for ele: ${ele}`, error);
- gradingResult[key] = 0;
- }
- }
-
- gradingResult['총점'] = totalScore;
- return gradingResult;
-}
\ No newline at end of file
diff --git a/psdExport_2.js b/psdExport_2.js
index 3340d59..cabf2be 100644
--- a/psdExport_2.js
+++ b/psdExport_2.js
@@ -11,14 +11,18 @@ const getGpdpScore = require('./gpdpScoring.js');
const getToday = require('./getToday.js');
const todayDate = getToday();
-const examRound = '2507';
+const examRound = '2508';
-const DICorDPI = 'DIC'
+const codeTypes = [
+ // 'DIC',
+ 'DPI',
+];
+// const DICorDPI = 'DIC'
// const DICorDPI = 'DPI'
const examTypes = [
// 'A',
- 'B',
- // 'C',
+ // 'B',
+ 'C',
// 'D'
];
@@ -27,133 +31,134 @@ const testMode = false;
// const testMode = true;
const outputExcelFiles = [];
-
-examTypes.forEach(type => {
- const jsonPath = `./${DICorDPI}_${examRound}${type}.json`
- if (!fs.existsSync(jsonPath)) return;
- const scoringJson = require(jsonPath);
- const answerFilesDir = `./output/${examRound}/${type}/${testMode ? 'TEST' : DICorDPI}`;
- let outputExcelFile = `./${todayDate}_${DICorDPI}_${examRound}${type}_채점결과.xlsx`;
- if (testMode) {
- outputExcelFile = `./00_${DICorDPI}_${examRound}${type}_TEST.xlsx`;
- }
-
- // 답안 폴더 내부에 디렉토리가 아닌 일반 파일이 있을 경우 디렉토리만 필터링 해서 불러옴
- const studentDirs = fs.readdirSync(answerFilesDir).filter(file => {
- const filePath = path.join(answerFilesDir, file);
- return fs.statSync(filePath).isDirectory();
- });
-
- // 채점 결과 리스트
- const scoringResultList = [];
- const psdData = [];
-
- studentDirs.forEach(student => {
- // 맥에서 한글 디렉토리 이름을 읽어서 엑셀에 저장 할 시 자소 분리가 되어 저장되는 문제 노말라이즈해서 해결
- const name = student.normalize('NFC');
- const studentDir = path.join(answerFilesDir, student);
- // const psdFiles = fs.readdirSync(studentDir).filter(file => file.endsWith('.psd'));
- const psdFiles = fs.readdirSync(studentDir).filter(file => file.toLowerCase().endsWith('.psd'));
-
- // DIAT시험 프로젝트로 생성시 gmep확장자로
- // 교육용 프로젝프로 생성시 gmdp확장자로 생성됨
- const gmepFile = fs.readdirSync(studentDir).filter(
- file => file.toLowerCase().endsWith('.gmep')
- // || file.toLowerCase().endsWith('.gmdp')
- );
-
- // 곰픽 파일 gpdp 파일 이거나 xml 파일
- const gpdpFiles = fs.readdirSync(studentDir).filter(
- file => file.toLowerCase().endsWith('.xml')
- || (file === null && (name + '.xml'))
- );
-
- // 학생 이름을 key로 하는 객체 생성
- // 채점결과
- const scoringResult = {
- 0: name
- };
-
- psdFiles.forEach((psdFile, index) => {
- const psdPath = path.join('./', studentDir, psdFile);
-
- console.log('');
- console.log(`➡️ Reading ${psdPath}...`);
- try {
- const psdFileData = psd.fromFile(psdPath);
- psdFileData.parse();
- psdData[index] = psdFileData;
- scoringResult[index + 1] = getScore(psdData, scoringJson, index);
- } catch (error) {
- console.error(`Error reading PSD file: ${psdPath}`, error);
- }
- });
- gpdpFiles.forEach((gpdpFile, index) => {
- const gpdpPath = path.join('./', studentDir, gpdpFile);
- console.log(`Reading ${gpdpPath}...`);
-
- const xmlString = fs.readFileSync(gpdpPath, 'utf8');
- // XML 문자열을 파싱하여 XML 문서 객체로 변환
- const xmlDocument = new DOMParser().parseFromString(xmlString, 'application/xml');
- // console.log('xmlDocument:', xmlDocument);
-
- scoringResult[index + 1] = getGpdpScore(xmlDocument, scoringJson, index + 4);
- });
- if (gmepFile.length === 0) {
- // 곰믹스 채점 항목 갯수
- const gmepItemCount = Object.keys(scoringJson[2]).length - 2;
- // console.log("🚀 ~ gmepItemCount:", gmepItemCount)
-
- scoringResult[3] = {};
- for (let i = 1; i <= gmepItemCount; i++) {
- scoringResult[3][i] = 0;
- }
- scoringResult[3]['총점'] = 0;
+codeTypes.forEach(codeType => {
+ examTypes.forEach(type => {
+ const jsonPath = `./${codeType}_${examRound}${type}.json`
+ if (!fs.existsSync(jsonPath)) return;
+ const scoringJson = require(jsonPath);
+ const answerFilesDir = `./output/${examRound}/${type}/${testMode ? 'TEST' : codeType}`;
+ let outputExcelFile = `./${todayDate}_${codeType}_${examRound}${type}_채점결과.xlsx`;
+ if (testMode) {
+ outputExcelFile = `./00_${codeType}_${examRound}${type}_TEST.xlsx`;
}
- else {
- gmepFile.forEach((gmep, index) => {
- const gmepPath = path.join('./', studentDir, gmep);
+
+ // 답안 폴더 내부에 디렉토리가 아닌 일반 파일이 있을 경우 디렉토리만 필터링 해서 불러옴
+ const studentDirs = fs.readdirSync(answerFilesDir).filter(file => {
+ const filePath = path.join(answerFilesDir, file);
+ return fs.statSync(filePath).isDirectory();
+ });
+
+ // 채점 결과 리스트
+ const scoringResultList = [];
+ const psdData = [];
+
+ studentDirs.forEach(student => {
+ // 맥에서 한글 디렉토리 이름을 읽어서 엑셀에 저장 할 시 자소 분리가 되어 저장되는 문제 노말라이즈해서 해결
+ const name = student.normalize('NFC');
+ const studentDir = path.join(answerFilesDir, student);
+ // const psdFiles = fs.readdirSync(studentDir).filter(file => file.endsWith('.psd'));
+ const psdFiles = fs.readdirSync(studentDir).filter(file => file.toLowerCase().endsWith('.psd'));
+
+ // DIAT시험 프로젝트로 생성시 gmep확장자로
+ // 교육용 프로젝프로 생성시 gmdp확장자로 생성됨
+ const gmepFile = fs.readdirSync(studentDir).filter(
+ file => file.toLowerCase().endsWith('.gmep')
+ // || file.toLowerCase().endsWith('.gmdp')
+ );
+
+ // 곰픽 파일 gpdp 파일 이거나 xml 파일
+ const gpdpFiles = fs.readdirSync(studentDir).filter(
+ file => file.toLowerCase().endsWith('.xml')
+ || (file === null && (name + '.xml'))
+ );
+
+ // 학생 이름을 key로 하는 객체 생성
+ // 채점결과
+ const scoringResult = {
+ 0: name
+ };
+
+ psdFiles.forEach((psdFile, index) => {
+ const psdPath = path.join('./', studentDir, psdFile);
console.log('');
- console.log(`➡️ Reading ${gmepPath}...`);
+ console.log(`➡️ Reading ${psdPath}...`);
+ try {
+ const psdFileData = psd.fromFile(psdPath);
+ psdFileData.parse();
+ psdData[index] = psdFileData;
+ scoringResult[index + 1] = getScore(psdData, scoringJson, index);
+ } catch (error) {
+ console.error(`Error reading PSD file: ${psdPath}`, error);
+ }
+ });
+ gpdpFiles.forEach((gpdpFile, index) => {
+ const gpdpPath = path.join('./', studentDir, gpdpFile);
+ console.log(`Reading ${gpdpPath}...`);
- const xmlString = fs.readFileSync(gmepPath, 'utf8');
+ const xmlString = fs.readFileSync(gpdpPath, 'utf8');
// XML 문자열을 파싱하여 XML 문서 객체로 변환
const xmlDocument = new DOMParser().parseFromString(xmlString, 'application/xml');
// console.log('xmlDocument:', xmlDocument);
- scoringResult[3] = getGmepScore(xmlDocument, scoringJson, 2);
+ scoringResult[index + 1] = getGpdpScore(xmlDocument, scoringJson, index + 4);
});
- }
- scoringResultList.push(scoringResult);
+ if (gmepFile.length === 0) {
+ // 곰믹스 채점 항목 갯수
+ const gmepItemCount = Object.keys(scoringJson[2]).length;
+ // console.log("🚀 ~ gmepItemCount:", gmepItemCount)
+
+ scoringResult[3] = {};
+ for (let i = 1; i <= gmepItemCount; i++) {
+ scoringResult[3][i] = 0;
+ }
+ scoringResult[3]['총점'] = 0;
+ }
+ else {
+ gmepFile.forEach((gmep, index) => {
+ const gmepPath = path.join('./', studentDir, gmep);
+
+ console.log('');
+ console.log(`➡️ Reading ${gmepPath}...`);
+
+ const xmlString = fs.readFileSync(gmepPath, 'utf8');
+ // XML 문자열을 파싱하여 XML 문서 객체로 변환
+ const xmlDocument = new DOMParser().parseFromString(xmlString, 'application/xml');
+ // console.log('xmlDocument:', xmlDocument);
+
+ scoringResult[3] = getGmepScore(xmlDocument, scoringJson, 2);
+ });
+ }
+ scoringResultList.push(scoringResult);
+ });
+
+ const flattenedData = prepareExcelData(scoringResultList);
+ const transposedData = transposeData(flattenedData);
+
+ // 엑셀 파일 생성
+ const worksheet = XLSX.utils.json_to_sheet(transposedData, { skipHeader: true });
+ const workbook = XLSX.utils.book_new();
+
+ // 열 너비 계산
+ const columnWidths = Object.keys(transposedData[0]).map(key => {
+ // 각 열의 최대 길이를 계산
+ const maxLength = Math.max(
+ // key.length, // 열 제목의 길이
+ // ...transposedData.map(row => (row[key] ? row[key].toString().length : 0)) // 각 셀의 데이터 길이
+ 4 // 고정 너비
+ );
+ return { wch: maxLength + 1 }; // 여유 공간 추가
+ });
+
+ // 열 너비 설정
+ worksheet['!cols'] = columnWidths;
+ // Add the worksheet to the workbook
+ XLSX.utils.book_append_sheet(workbook, worksheet, '채점 결과');
+
+ // 엑셀 파일 저장
+ XLSX.writeFile(workbook, outputExcelFile);
+ outputExcelFiles.push(outputExcelFile);
});
-
- const flattenedData = prepareExcelData(scoringResultList);
- const transposedData = transposeData(flattenedData);
-
- // 엑셀 파일 생성
- const worksheet = XLSX.utils.json_to_sheet(transposedData, { skipHeader: true });
- const workbook = XLSX.utils.book_new();
-
- // 열 너비 계산
- const columnWidths = Object.keys(transposedData[0]).map(key => {
- // 각 열의 최대 길이를 계산
- const maxLength = Math.max(
- // key.length, // 열 제목의 길이
- // ...transposedData.map(row => (row[key] ? row[key].toString().length : 0)) // 각 셀의 데이터 길이
- 4 // 고정 너비
- );
- return { wch: maxLength + 1 }; // 여유 공간 추가
- });
-
- // 열 너비 설정
- worksheet['!cols'] = columnWidths;
- // Add the worksheet to the workbook
- XLSX.utils.book_append_sheet(workbook, worksheet, '채점 결과');
-
- // 엑셀 파일 저장
- XLSX.writeFile(workbook, outputExcelFile);
- outputExcelFiles.push(outputExcelFile);
});
console.log('채점 결과');
diff --git a/250730_DIC_2507A_채점결과.xlsx b/회차별채점자료/2507/excel_채점결과/250730_DIC_2507A_채점결과.xlsx
similarity index 100%
rename from 250730_DIC_2507A_채점결과.xlsx
rename to 회차별채점자료/2507/excel_채점결과/250730_DIC_2507A_채점결과.xlsx
diff --git a/250730_DIC_2507B_채점결과.xlsx b/회차별채점자료/2507/excel_채점결과/250730_DIC_2507B_채점결과.xlsx
similarity index 100%
rename from 250730_DIC_2507B_채점결과.xlsx
rename to 회차별채점자료/2507/excel_채점결과/250730_DIC_2507B_채점결과.xlsx
diff --git a/250730_DIC_2507C_채점결과.xlsx b/회차별채점자료/2507/excel_채점결과/250730_DIC_2507C_채점결과.xlsx
similarity index 100%
rename from 250730_DIC_2507C_채점결과.xlsx
rename to 회차별채점자료/2507/excel_채점결과/250730_DIC_2507C_채점결과.xlsx
diff --git a/250730_DPI_2507B_채점결과.xlsx b/회차별채점자료/2507/excel_채점결과/250730_DPI_2507B_채점결과.xlsx
similarity index 100%
rename from 250730_DPI_2507B_채점결과.xlsx
rename to 회차별채점자료/2507/excel_채점결과/250730_DPI_2507B_채점결과.xlsx
diff --git a/회차별채점자료/2507/excel_채점결과/250801_DIC_2507A_채점결과.xlsx b/회차별채점자료/2507/excel_채점결과/250801_DIC_2507A_채점결과.xlsx
new file mode 100644
index 0000000..d54863f
Binary files /dev/null and b/회차별채점자료/2507/excel_채점결과/250801_DIC_2507A_채점결과.xlsx differ
diff --git a/회차별채점자료/2507/excel_채점결과/250801_DIC_2507B_채점결과.xlsx b/회차별채점자료/2507/excel_채점결과/250801_DIC_2507B_채점결과.xlsx
new file mode 100644
index 0000000..b1d3bab
Binary files /dev/null and b/회차별채점자료/2507/excel_채점결과/250801_DIC_2507B_채점결과.xlsx differ
diff --git a/회차별채점자료/2507/excel_채점결과/250801_DIC_2507C_채점결과.xlsx b/회차별채점자료/2507/excel_채점결과/250801_DIC_2507C_채점결과.xlsx
new file mode 100644
index 0000000..65aadd0
Binary files /dev/null and b/회차별채점자료/2507/excel_채점결과/250801_DIC_2507C_채점결과.xlsx differ
diff --git a/회차별채점자료/2507/excel_채점결과/250801_DPI_2507B_채점결과.xlsx b/회차별채점자료/2507/excel_채점결과/250801_DPI_2507B_채점결과.xlsx
new file mode 100644
index 0000000..4a941e2
Binary files /dev/null and b/회차별채점자료/2507/excel_채점결과/250801_DPI_2507B_채점결과.xlsx differ
diff --git a/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_01_123456_성명.jpg b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_01_123456_성명.jpg
new file mode 100644
index 0000000..ed573bd
Binary files /dev/null and b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_01_123456_성명.jpg differ
diff --git a/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_01_123456_성명.psd b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_01_123456_성명.psd
new file mode 100644
index 0000000..46330b6
Binary files /dev/null and b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_01_123456_성명.psd differ
diff --git a/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_02_123456_성명.jpg b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_02_123456_성명.jpg
new file mode 100644
index 0000000..dc7a703
Binary files /dev/null and b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_02_123456_성명.jpg differ
diff --git a/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_02_123456_성명.psd b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_02_123456_성명.psd
new file mode 100644
index 0000000..3a165a0
Binary files /dev/null and b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_02_123456_성명.psd differ
diff --git a/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_03_123456_성명.gmep b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_03_123456_성명.gmep
new file mode 100644
index 0000000..4a3772e
--- /dev/null
+++ b/회차별채점자료/2508/DIC/A/dic_03_123456_정답A/dic_03_123456_성명.gmep
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_01_123456_성명.jpg b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_01_123456_성명.jpg
new file mode 100644
index 0000000..aed0cc7
Binary files /dev/null and b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_01_123456_성명.jpg differ
diff --git a/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_01_123456_성명.psd b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_01_123456_성명.psd
new file mode 100644
index 0000000..d4b53ed
Binary files /dev/null and b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_01_123456_성명.psd differ
diff --git a/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_02_123456_성명.jpg b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_02_123456_성명.jpg
new file mode 100644
index 0000000..e503303
Binary files /dev/null and b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_02_123456_성명.jpg differ
diff --git a/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_02_123456_성명.psd b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_02_123456_성명.psd
new file mode 100644
index 0000000..f48cf48
Binary files /dev/null and b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_02_123456_성명.psd differ
diff --git a/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_03_123456_성명.gmep b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_03_123456_성명.gmep
new file mode 100644
index 0000000..82fc59d
--- /dev/null
+++ b/회차별채점자료/2508/DIC/C/dic_03_123456_정답C/dic_03_123456_성명.gmep
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DIC_2507C.json b/회차별채점자료/2508/DIC_2508A.json
similarity index 85%
rename from DIC_2507C.json
rename to 회차별채점자료/2508/DIC_2508A.json
index cfb75e2..beecca0 100644
--- a/DIC_2507C.json
+++ b/회차별채점자료/2508/DIC_2508A.json
@@ -57,39 +57,40 @@
"point": 0
},
"4": {
+ "ele": "$.children[?(@.name=='전시실')].name",
+ "value": "전시실",
+ "point": 4
+ },
+ "5": {
"ele": "none",
"point": 0
},
- "5": {
- "ele": "$.children[?(@.name=='Wooden Playground')].name",
- "value": "Wooden Playground",
+ "6": {
+ "ele": "$.children[?(@.name=='Cartoon Museum')].name",
+ "value": "Cartoon Museum",
"point": 4
},
- "6": {
- "ele": "$.children[?(@.name=='Wooden Playground')].text.font.names[0]",
+ "7": {
+ "ele": "$.children[?(@.name=='Cartoon Museum')].text.font.names[0]",
"type": "font",
"value": "Arial",
"point": 2
},
- "7": {
- "ele": "$.children[?(@.name=='Wooden Playground')].text.font.names[0]",
+ "8": {
+ "ele": "$.children[?(@.name=='Cartoon Museum')].text.font.names[0]",
"value": "Arial-BoldItalicMT",
"point": 2
},
- "8": {
- "ele": "$.children[?(@.name=='Wooden Playground')].text.font.sizes[0]",
+ "9": {
+ "ele": "$.children[?(@.name=='Cartoon Museum')].text.font.sizes[0]",
"value": 48,
"point": 2
},
- "9": {
- "ele": "$.children[?(@.name=='Wooden Playground')].text.font.colors[0]",
- "type": "color",
- "value": "084f0e",
- "point": 2
- },
"10": {
- "ele": "none",
- "point": 0
+ "ele": "$.children[?(@.name=='Cartoon Museum')].text.font.colors[0]",
+ "type": "color",
+ "value": "3538cc",
+ "point": 2
},
"11": {
"ele": "none",
@@ -100,12 +101,16 @@
"point": 0
},
"13": {
- "ele": "$.children[?(@.name=='나무로 만든 놀이터')].name",
- "value": "나무로 만든 놀이터",
- "point": 4
+ "ele": "none",
+ "point": 0
},
"14": {
- "ele": "$.children[?(@.name=='나무로 만든 놀이터')].text.font.names[0]",
+ "ele": "$.children[?(@.name=='만화 박물관')].name",
+ "value": "만화 박물관",
+ "point": 4
+ },
+ "15": {
+ "ele": "$.children[?(@.name=='만화 박물관')].text.font.names[0]",
"type": "font",
"value": "GungsuhChe",
"point": 2,
@@ -116,20 +121,16 @@
"휴먼옛체": "YetR"
}
},
- "15": {
- "ele": "$.children[?(@.name=='나무로 만든 놀이터')].text.font.sizes[0]",
+ "16": {
+ "ele": "$.children[?(@.name=='만화 박물관')].text.font.sizes[0]",
"value": 36,
"point": 2
},
- "16": {
- "ele": "$.children[?(@.name=='나무로 만든 놀이터')].text.font.colors[0]",
- "type": "color",
- "value": "f5e103",
- "point": 2
- },
"17": {
- "ele": "none",
- "point": 0
+ "ele": "$.children[?(@.name=='만화 박물관')].text.font.colors[0]",
+ "type": "color",
+ "value": "35b1cc",
+ "point": 2
},
"18": {
"ele": "none",
@@ -148,8 +149,9 @@
"point": 0
},
"22": {
- "ele": "none",
- "point": 0
+ "ele": "$.children[?(@.name=='뱀 캐릭터')].name",
+ "value": "뱀 캐릭터",
+ "point": 4
},
"23": {
"ele": "none",
@@ -164,19 +166,15 @@
"point": 0
},
"26": {
- "ele": "none",
- "point": 0
- },
- "27": {
- "ele": "$[?(@.width == 65 && @.height == 45)]",
+ "ele": "$[?(@.width == 65 && @.height == 35)]",
"type": "size",
"value": {
"width": 65,
- "height": 45
+ "height": 35
},
- "point": 4
+ "point": 5
},
- "28": {
+ "27": {
"ele": "none",
"point": 0,
"desc": "파일명 확인"
@@ -186,15 +184,15 @@
"1": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex",
"type": "mediaOrder",
- "value": ["동영상.mp4", "이미지3.jpg", "이미지1.jpg", "이미지2.jpg"],
+ "value": ["동영상.mp4", "이미지3.jpg", "이미지2.jpg", "이미지1.jpg"],
"point": 4,
- "desc": "클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다."
+ "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다."
},
"2": {
"ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed",
"type": "oneAnswer",
"value": {
- "speed": "110"
+ "speed": "150"
},
"point": 2,
"desc": "100당 1배속 / 130 = 1.3배속"
@@ -205,7 +203,7 @@
"media": "동영상.mp4",
"value": {
"start": "0",
- "end": "355"
+ "end": "380"
},
"point": 2,
"desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다."
@@ -215,37 +213,37 @@
"type": "effect",
"media": "동영상.mp4",
"value": {
- "ID": "90",
- "VID104": "5",
- "VID103": "2"
+ "ID": "43",
+ "VID100": "9",
+ "VID103": "0.69999999"
},
"point": 3,
"desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요"
},
"5": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
- "search": "다양한 연주 악기들",
+ "search": "만화 전시관",
"type": "video.Text",
- "value": "다양한 연주 악기들",
+ "value": "만화 전시관",
"point": 3
},
"6": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
- "search": "다양한 연주 악기들",
+ "search": "만화 전시관",
"type": "video.Text",
"value": "굴림체",
"point": 2
},
"7": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
- "search": "다양한 연주 악기들",
+ "search": "만화 전시관",
"type": "video.Text",
- "value": "110",
+ "value": "100",
"point": 2
},
"8": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
- "search": "다양한 연주 악기들",
+ "search": "만화 전시관",
"type": "video.Text.Color",
"value": "ffeb3b",
"point": 2,
@@ -253,15 +251,15 @@
},
"9": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']",
- "search": "다양한 연주 악기들",
+ "search": "만화 전시관",
"type": "video.Location",
- "value": ["0.3125", "0.92962962"],
+ "value": ["0.39375001", "0.93333334"],
"point": 2,
"desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다"
},
"10": {
"ele": "",
- "search": "다양한 연주 악기들",
+ "search": "만화 전시관",
"type": "video.StartTime",
"value": 160,
"point": 2,
@@ -269,9 +267,9 @@
},
"11": {
"ele": "",
- "search": "다양한 연주 악기들",
+ "search": "만화 전시관",
"type": "video.Length",
- "value": 180,
+ "value": 150,
"point": 2,
"desc": "내부적으로 자막의 시작시간과 길이를 계산"
},
@@ -294,8 +292,8 @@
"type": "imageOverlay",
"media": "이미지3.jpg",
"value": {
- "ID": "173",
- "VID105": "30"
+ "ID": "94",
+ "VID101": "8"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -305,8 +303,8 @@
"type": "clipTransition",
"media": "이미지3.jpg",
"value": {
- "ID": "8",
- "Range": "475:535",
+ "ID": "15",
+ "Range": "500:560",
"Type": "2"
},
"point": 2,
@@ -315,16 +313,16 @@
"16": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
- "media": "이미지1.jpg",
- "value": 180,
+ "media": "이미지2.jpg",
+ "value": 150,
"point": 2
},
"17": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "imageOverlay",
- "media": "이미지1.jpg",
+ "media": "이미지2.jpg",
"value": {
- "ID": "128",
+ "ID": "104",
"VID100": "10"
},
"point": 2,
@@ -333,10 +331,10 @@
"18": {
"ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
"type": "clipTransition",
- "media": "이미지1.jpg",
+ "media": "이미지2.jpg",
"value": {
- "ID": "10",
- "Range": "685:715",
+ "ID": "35",
+ "Range": "680:710",
"Type": "2"
},
"point": 2,
@@ -345,17 +343,17 @@
"19": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
- "media": "이미지2.jpg",
- "value": 120,
+ "media": "이미지1.jpg",
+ "value": 150,
"point": 2
},
"20": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "imageOverlay",
- "media": "이미지2.jpg",
+ "media": "이미지1.jpg",
"value": {
- "ID": "184",
- "VID100": "20"
+ "ID": "102",
+ "VID102": "10"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -363,10 +361,10 @@
"21": {
"ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
"type": "clipTransition",
- "media": "이미지2.jpg",
+ "media": "이미지1.jpg",
"value": {
- "ID": "19",
- "Range": "805:835",
+ "ID": "17",
+ "Range": "800:860",
"Type": "2"
},
"point": 2,
@@ -374,50 +372,50 @@
},
"22": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
- "search": "자연 소리 공원 (Natural Sound Park)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text",
- "value": "자연 소리 공원 (Natural Sound Park)",
+ "value": "만화 세상 (Cartoon World)",
"point": 3
},
"23": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
- "search": "자연 소리 공원 (Natural Sound Park)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text",
- "value": "돋움체",
+ "value": "바탕체",
"point": 2
},
"24": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
- "search": "자연 소리 공원 (Natural Sound Park)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text",
- "value": "140",
+ "value": "120",
"point": 2
},
"25": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
- "search": "자연 소리 공원 (Natural Sound Park)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text.Color",
- "value": "ff7419",
+ "value": "0cc762",
"point": 2,
"desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
},
"26": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']",
- "search": "자연 소리 공원 (Natural Sound Park)",
+ "search": "만화 세상 (Cartoon World)",
"type": "video.Text.Outline",
"value": {
- "width": "35",
- "color": "3d30cd"
+ "width": "20",
+ "color": "ffe500"
},
"point": 2,
"desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성"
},
"27": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr",
- "search": "자연 소리 공원 (Natural Sound Park)",
+ "search": "만화 세상 (Cartoon World)",
"type": "opening.Text.FadeInEffect",
"value": {
- "VID505": "13",
+ "VID505": "5",
"VID507": "2"
},
"point": 3,
@@ -425,7 +423,7 @@
},
"28": {
"ele": "",
- "search": "자연 소리 공원 (Natural Sound Park)",
+ "search": "만화 세상 (Cartoon World)",
"type": "opening.StartTime",
"value": 0,
"point": 2,
@@ -433,7 +431,7 @@
},
"29": {
"ele": "",
- "search": "자연 소리 공원 (Natural Sound Park)",
+ "search": "만화 세상 (Cartoon World)",
"type": "opening.Length",
"value": 120,
"point": 2
@@ -449,7 +447,7 @@
"ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']",
"type": "audio.EndTime",
"media": "음악.mp3",
- "value": 820,
+ "value": 840,
"point": 2
},
"32": {
diff --git a/회차별채점자료/2508/DIC_2508A.xlsx b/회차별채점자료/2508/DIC_2508A.xlsx
new file mode 100644
index 0000000..1b89fa2
Binary files /dev/null and b/회차별채점자료/2508/DIC_2508A.xlsx differ
diff --git a/회차별채점자료/2508/DIC_2508A_layer.hwp b/회차별채점자료/2508/DIC_2508A_layer.hwp
new file mode 100644
index 0000000..f04fe0c
Binary files /dev/null and b/회차별채점자료/2508/DIC_2508A_layer.hwp differ
diff --git a/DIC_2507B.json b/회차별채점자료/2508/DIC_2508C.json
similarity index 78%
rename from DIC_2507B.json
rename to 회차별채점자료/2508/DIC_2508C.json
index b96e817..e37e08e 100644
--- a/DIC_2507B.json
+++ b/회차별채점자료/2508/DIC_2508C.json
@@ -57,39 +57,40 @@
"point": 0
},
"4": {
+ "ele": "$.children[?(@.name=='하천')].name",
+ "value": "하천",
+ "point": 4
+ },
+ "5": {
"ele": "none",
"point": 0
},
- "5": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].name",
- "value": "My Friend Parrot",
+ "6": {
+ "ele": "$.children[?(@.name=='River Ecosystem')].name",
+ "value": "River Ecosystem",
"point": 4
},
- "6": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].text.font.names[0]",
+ "7": {
+ "ele": "$.children[?(@.name=='River Ecosystem')].text.font.names[0]",
"type": "font",
"value": "Arial",
"point": 2
},
- "7": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].text.font.names[0]",
+ "8": {
+ "ele": "$.children[?(@.name=='River Ecosystem')].text.font.names[0]",
"value": "Arial-BoldItalicMT",
"point": 2
},
- "8": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].text.font.sizes[0]",
+ "9": {
+ "ele": "$.children[?(@.name=='River Ecosystem')].text.font.sizes[0]",
"value": 48,
"point": 2
},
- "9": {
- "ele": "$.children[?(@.name=='My Friend Parrot')].text.font.colors[0]",
- "type": "color",
- "value": "1bc553",
- "point": 2
- },
"10": {
- "ele": "none",
- "point": 0
+ "ele": "$.children[?(@.name=='River Ecosystem')].text.font.colors[0]",
+ "type": "color",
+ "value": "439bff",
+ "point": 2
},
"11": {
"ele": "none",
@@ -100,36 +101,37 @@
"point": 0
},
"13": {
- "ele": "$.children[?(@.name=='내 친구 앵무새')].name",
- "value": "내 친구 앵무새",
- "point": 4
+ "ele": "none",
+ "point": 0
},
"14": {
- "ele": "$.children[?(@.name=='내 친구 앵무새')].text.font.names[0]",
+ "ele": "$.children[?(@.name=='하천 생태계')].name",
+ "value": "하천 생태계",
+ "point": 4
+ },
+ "15": {
+ "ele": "$.children[?(@.name=='하천 생태계')].text.font.names[0]",
"type": "font",
- "value": "GungsuhChe",
+ "value": "Batang",
"point": 2,
"desc": {
"돋움체": "DotumChe",
"궁서체": "GungsuhChe",
"굴림체": "GulimChe",
+ "바탕체": "Batang",
"휴먼옛체": "YetR"
}
},
- "15": {
- "ele": "$.children[?(@.name=='내 친구 앵무새')].text.font.sizes[0]",
- "value": 36,
- "point": 2
- },
"16": {
- "ele": "$.children[?(@.name=='내 친구 앵무새')].text.font.colors[0]",
- "type": "color",
- "value": "ffea00",
+ "ele": "$.children[?(@.name=='하천 생태계')].text.font.sizes[0]",
+ "value": 30,
"point": 2
},
"17": {
- "ele": "none",
- "point": 0
+ "ele": "$.children[?(@.name=='하천 생태계')].text.font.colors[0]",
+ "type": "color",
+ "value": "ffd543",
+ "point": 2
},
"18": {
"ele": "none",
@@ -148,8 +150,9 @@
"point": 0
},
"22": {
- "ele": "none",
- "point": 0
+ "ele": "$.children[?(@.name=='물고기')].name",
+ "value": "물고기",
+ "point": 4
},
"23": {
"ele": "none",
@@ -164,37 +167,33 @@
"point": 0
},
"26": {
- "ele": "none",
- "point": 0
- },
- "27": {
- "ele": "$[?(@.width == 65 && @.height == 45)]",
+ "ele": "$[?(@.width == 65 && @.height == 35)]",
"type": "size",
"value": {
"width": 65,
- "height": 45
+ "height": 35
},
- "point": 4
+ "point": 5
},
- "28": {
+ "27": {
"ele": "none",
"point": 0,
"desc": "파일명 확인"
}
},
-"2": {
+ "2": {
"1": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex",
"type": "mediaOrder",
- "value": ["동영상.mp4", "이미지1.jpg", "이미지3.jpg", "이미지2.jpg"],
+ "value": ["동영상.mp4", "이미지2.jpg", "이미지1.jpg", "이미지3.jpg"],
"point": 4,
- "desc": "클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다."
+ "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다."
},
"2": {
"ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed",
"type": "oneAnswer",
"value": {
- "speed": "130"
+ "speed": "150"
},
"point": 2,
"desc": "100당 1배속 / 130 = 1.3배속"
@@ -205,63 +204,63 @@
"media": "동영상.mp4",
"value": {
"start": "0",
- "end": "320"
+ "end": "380"
},
"point": 2,
- "desc": "start: 시작시간 / end: 재생시간( 12.20 = 12*30 + 20 = 380 )"
+ "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다."
},
"4": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "effect",
"media": "동영상.mp4",
"value": {
- "ID": "43",
- "VID100": "20",
- "VID103": "1.3"
+ "ID": "40",
+ "VID100": "30",
+ "VID103": "0.89999998"
},
"point": 3,
"desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요"
},
"5": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
- "search": "화려한 앵무새",
+ "search": "하천에 사는 물고기",
"type": "video.Text",
- "value": "화려한 앵무새",
+ "value": "하천에 사는 물고기",
"point": 3
},
"6": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
- "search": "화려한 앵무새",
+ "search": "하천에 사는 물고기",
"type": "video.Text",
- "value": "굴림체",
+ "value": "궁서체",
"point": 2
},
"7": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
- "search": "화려한 앵무새",
+ "search": "하천에 사는 물고기",
"type": "video.Text",
- "value": "110",
+ "value": "90",
"point": 2
},
"8": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
- "search": "화려한 앵무새",
+ "search": "하천에 사는 물고기",
"type": "video.Text.Color",
- "value": "23a23f",
+ "value": "f116f2",
"point": 2,
"desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
},
"9": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']",
- "search": "화려한 앵무새",
+ "search": "하천에 사는 물고기",
"type": "video.Location",
- "value": ["0.36354166", "0.92962962"],
+ "value": ["0.34583333", "0.94074076"],
"point": 2,
"desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다"
},
"10": {
"ele": "",
- "search": "화려한 앵무새",
+ "search": "하천에 사는 물고기",
"type": "video.StartTime",
"value": 170,
"point": 2,
@@ -269,9 +268,9 @@
},
"11": {
"ele": "",
- "search": "화려한 앵무새",
+ "search": "하천에 사는 물고기",
"type": "video.Length",
- "value": 120,
+ "value": 180,
"point": 2,
"desc": "내부적으로 자막의 시작시간과 길이를 계산"
},
@@ -285,17 +284,17 @@
"13": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
- "media": "이미지1.jpg",
+ "media": "이미지2.jpg",
"value": 150,
"point": 2
},
"14": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "imageOverlay",
- "media": "이미지1.jpg",
+ "media": "이미지2.jpg",
"value": {
- "ID": "99",
- "VID100": "60"
+ "ID": "104",
+ "VID101": "5"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -303,10 +302,10 @@
"15": {
"ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
"type": "clipTransition",
- "media": "이미지1.jpg",
+ "media": "이미지2.jpg",
"value": {
- "ID": "15",
- "Range": "440:470",
+ "ID": "14",
+ "Range": "470:530",
"Type": "2"
},
"point": 2,
@@ -315,17 +314,17 @@
"16": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
- "media": "이미지3.jpg",
- "value": 180,
+ "media": "이미지1.jpg",
+ "value": 150,
"point": 2
},
"17": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "imageOverlay",
- "media": "이미지3.jpg",
+ "media": "이미지1.jpg",
"value": {
- "ID": "173",
- "VID101": "250"
+ "ID": "94",
+ "VID101": "8"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -333,10 +332,10 @@
"18": {
"ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
"type": "clipTransition",
- "media": "이미지3.jpg",
+ "media": "이미지1.jpg",
"value": {
- "ID": "14",
- "Range": "590:650",
+ "ID": "95",
+ "Range": "650:680",
"Type": "2"
},
"point": 2,
@@ -345,17 +344,17 @@
"19": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length",
"type": "imageLength",
- "media": "이미지2.jpg",
+ "media": "이미지3.jpg",
"value": 180,
"point": 2
},
"20": {
"ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter",
"type": "imageOverlay",
- "media": "이미지2.jpg",
+ "media": "이미지3.jpg",
"value": {
- "ID": "102",
- "VID100": "4"
+ "ID": "96",
+ "VID101": "11"
},
"point": 2,
"desc": "오버레이 속성 키값(VID10X) 확인하고 변경"
@@ -363,10 +362,10 @@
"21": {
"ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']",
"type": "clipTransition",
- "media": "이미지2.jpg",
+ "media": "이미지3.jpg",
"value": {
"ID": "9",
- "Range": "800:830",
+ "Range": "800:860",
"Type": "2"
},
"point": 2,
@@ -374,58 +373,58 @@
},
"22": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name",
- "search": "앵무새를 찾아서 (Finding Parrot)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text",
- "value": "앵무새를 찾아서 (Finding Parrot)",
+ "value": "우리나라 하천의 물고기들 (Korean river fish)",
"point": 3
},
"23": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102",
- "search": "앵무새를 찾아서 (Finding Parrot)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text",
- "value": "휴먼옛체",
+ "value": "돋움체",
"point": 2
},
"24": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101",
- "search": "앵무새를 찾아서 (Finding Parrot)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text",
- "value": "150",
+ "value": "140",
"point": 2
},
"25": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100",
- "search": "앵무새를 찾아서 (Finding Parrot)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text.Color",
- "value": "aff32a",
+ "value": "ecd000",
"point": 2,
"desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)"
},
"26": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']",
- "search": "앵무새를 찾아서 (Finding Parrot)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "video.Text.Outline",
"value": {
- "width": "35",
- "color": "0b00ff"
+ "width": "10",
+ "color": "3c0000"
},
"point": 2,
"desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성"
},
"27": {
"ele": "//CROwneUnit[{index}]/CRCUnitArr",
- "search": "앵무새를 찾아서 (Finding Parrot)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "opening.Text.FadeInEffect",
"value": {
- "VID505": "1",
- "VID507": "3"
+ "VID505": "14",
+ "VID507": "2"
},
"point": 3,
"desc": "오프닝자막의 나타나기 효과를 확인하는 문항. id속성은 VID505, playtime속성은 VID507으로 XML 내부에 표기되어 있다."
},
"28": {
"ele": "",
- "search": "앵무새를 찾아서 (Finding Parrot)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "opening.StartTime",
"value": 0,
"point": 2,
@@ -433,9 +432,9 @@
},
"29": {
"ele": "",
- "search": "앵무새를 찾아서 (Finding Parrot)",
+ "search": "우리나라 하천의 물고기들 (Korean river fish)",
"type": "opening.Length",
- "value": 120,
+ "value": 150,
"point": 2
},
"30": {
@@ -449,7 +448,7 @@
"ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']",
"type": "audio.EndTime",
"media": "음악.mp3",
- "value": 820,
+ "value": 850,
"point": 2
},
"32": {
@@ -458,7 +457,7 @@
"media": "음악.mp3",
"value": {
"ID": "1",
- "Duration": "60"
+ "Duration": "90"
},
"point": 2,
"desc": "ID속성-페이드인:0 / 페이드아웃: 1"
@@ -486,19 +485,18 @@
"3": {
"type": "layer.exists",
"ele": "//Layer/Name/@value",
- "value": "Valley",
+ "value": "Flower",
"point": 5,
- "desc": "Valley 레이어가 있는지 여부 체크"
+ "desc": "Flower 레이어가 있는지 여부 체크"
},
"4": {
"type": "layer.Effects",
- "ele": "//Layer/Effects/Item",
- "ele_temp": "//Layer[Name[@value='{search}']]/Effects/Item",
- "search": "Valley",
+ "ele": "//Layer[Name[@value='{search}']]/Effects/Item",
+ "search": "Flower",
"value": {
- "name": "선명하게",
+ "name": "생동감",
"option": {
- "양": "7"
+ "생동감": "40"
}
},
"point": 5,
@@ -509,11 +507,7 @@
"색조/채도": ["색조", "채도", "명도"],
"감마": ["리프트", "감마", "게인"],
"세피아": ["U", "V"],
- "생동감": "생동감",
- "흐리게": "반경",
- "글로우": ["반경", "밝기", "대비"],
- "픽셀효과": "셀크기",
- "선명하게": "양"
+ "생동감": "생동감"
}
},
"5": {
@@ -532,20 +526,16 @@
"7": {
"type": "exists",
"ele": "//Layer/Shapes/Shape/shape_type/@value",
- "value": "RECTANGLE",
+ "value": "ELLIPSE",
"point": 3,
- "desc": {
- "모서리가 둥근 사각형": "ROUNDED_RECTANGLE",
- "사각형": "RECTANGLE",
- "타원": "ELLIPSE"
- }
+ "desc": "레이어 쉐이프 타입이 타원인지 체크"
},
"8": {
"type": "shape.size",
"ele": "//Layer//op_points",
"value": {
- "width": 335,
- "height": 35
+ "width": 120,
+ "height": 120
},
"point": 3,
"desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
@@ -553,7 +543,7 @@
"9": {
"type": "shape.color",
"ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value",
- "value": "46A64A",
+ "value": "7097BB",
"point": 6,
"desc": ""
},
@@ -561,7 +551,7 @@
"type": "layer.blend.opacity",
"ele": "//Layer",
"value": {
- "BlendOp": "중첩",
+ "BlendOp": "반사",
"Opacity": "80"
},
"point": 6
@@ -610,15 +600,14 @@
"type": "exists",
"ele": "//Layer//shape_type/@value",
"value": "ROUNDED_RECTANGLE",
- "point": 3,
- "desc": "모서리가 둥근 사각형 : ROUNDED_RECTANGLE / 사각형 : RECTANGLE"
+ "point": 3
},
"6": {
"type": "shape.size",
"ele": "//Layer//op_points",
"value": {
"width": 400,
- "height": 50
+ "height": 60
},
"point": 3,
"desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
@@ -629,21 +618,21 @@
"startColor": "gradient_start_color/@value",
"endColor": "gradient_end_color/@value",
"value": {
- "startColor": "3CB241",
- "endColor": "931FAD"
+ "startColor": "ffe000",
+ "endColor": "34A159"
},
"point": 6
},
"8": {
"type": "text.exists",
"ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value",
- "value": "도깨비골 스카이밸리",
+ "value": "흰 꽃 사이 노란 꽃",
"point": 5
},
"9": {
"type": "exists",
"ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value",
- "value": "돋움",
+ "value": "맑은 고딕",
"point": 3
},
"10": {
@@ -656,25 +645,25 @@
"11": {
"type": "exists",
"ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value",
- "value": "24",
+ "value": "30",
"point": 3
},
"12": {
"type": "text.color",
"ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value",
- "value": "AA2318",
+ "value": "b46Ef8",
"point": 3
},
"13": {
"type": "exists",
"ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value",
- "value": "5",
+ "value": "7",
"point": 3
},
"14": {
"type": "text.color",
"ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value",
- "value": "FFFFFF",
+ "value": "ffffff",
"point": 3
},
"15": {
@@ -687,21 +676,19 @@
"16": {
"type": "exists",
"ele": "//Layer/Shapes/Shape/shape_type/@value",
- "value": "ELLIPSE",
+ "value": "RECTANGLE",
"point": 3,
"desc": {
- "사각형": "RECTANGLE",
- "원형/타원형": "ELLIPSE",
- "17~20 문항 option값 변경":""
+ "사각형": "RECTANGLE"
}
},
"17": {
"type": "clipping.size",
"ele": "//Layer//Shape[shape_type/@value='{option}']//op_points",
- "option": "ELLIPSE",
+ "option": "RECTANGLE",
"value": {
- "width": 170,
- "height": 170
+ "width": 150,
+ "height": 150
},
"point": 3,
"desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점"
@@ -709,26 +696,26 @@
"18": {
"type": "exists",
"ele": "//Layer//Shape[shape_type/@value='{option}']/outline_peninfo/Width/@value",
- "option": "ELLIPSE",
- "value": "3",
+ "option": "RECTANGLE",
+ "value": "7",
"point": 3
},
"19": {
"type": "clipping.color",
"ele": "//Layer//Shape[shape_type/@value='{option}' and contains(draw_type/@value, 'Outline')]/primary_color/@value",
- "option": "ELLIPSE",
- "value": "4B7E5C",
+ "option": "RECTANGLE",
+ "value": "e8e88e",
"point": 3,
"desc": "채우기:secondary_color, 외곽선:primary_color"
},
"20": {
"type": "shadow",
"ele": "//Layer//Shape[shape_type/@value='{option}']",
- "option": "ELLIPSE",
+ "option": "RECTANGLE",
"value": {
"shadow": true,
- "width": "5",
- "distance": "2",
+ "width": "3",
+ "distance": "5",
"blur": "1",
"angle": "320"
},
diff --git a/회차별채점자료/2508/DIC_2508C.xlsx b/회차별채점자료/2508/DIC_2508C.xlsx
new file mode 100644
index 0000000..70b7755
Binary files /dev/null and b/회차별채점자료/2508/DIC_2508C.xlsx differ
diff --git a/회차별채점자료/2508/DIC_2508C_layer.hwp b/회차별채점자료/2508/DIC_2508C_layer.hwp
new file mode 100644
index 0000000..4a50550
Binary files /dev/null and b/회차별채점자료/2508/DIC_2508C_layer.hwp differ
diff --git a/회차별채점자료/2508/DPI/B/dpi_03_123456_정답B/dpi_01_123456_성명.gpdp b/회차별채점자료/2508/DPI/B/dpi_03_123456_정답B/dpi_01_123456_성명.gpdp
new file mode 100644
index 0000000..00cf5eb
--- /dev/null
+++ b/회차별채점자료/2508/DPI/B/dpi_03_123456_정답B/dpi_01_123456_성명.gpdp
@@ -0,0 +1,1023 @@
+GPX
P