From 6f5d1c20f76ec962103d2c065532cbfbb6ac9530 Mon Sep 17 00:00:00 2001 From: dragdra Date: Fri, 20 Jun 2025 17:47:47 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=B0=ED=94=BD=20=EC=B1=84=EC=A0=90=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EB=B2=84=EC=A0=84=20=EC=A7=84=ED=96=89?= =?UTF-8?q?=EC=A4=91=20[1-6]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 00_DIC_2505B_TEST.xlsx | Bin 26555 -> 32656 bytes 01_copyFiles.py | 4 +- DIC_2504B.json | 732 ++++++++++++++++++ DIC_2505B copy.json | 729 +++++++++++++++++ DIC_2505B.json | 2 +- gpdpScoring.js | 224 +++++- psdExport_2.js | 71 +- z.xbook | 2 +- .../2504/excel_채점기준표/DIC_2504B.xlsx | Bin 18923 -> 18896 bytes .../2505/excel_채점기준표/DIC_2505B.xlsx | Bin 18916 -> 18886 bytes 10 files changed, 1695 insertions(+), 69 deletions(-) create mode 100644 DIC_2504B.json create mode 100644 DIC_2505B copy.json diff --git a/00_DIC_2505B_TEST.xlsx b/00_DIC_2505B_TEST.xlsx index fb415eb0dbe42e2fdf2e058cfa0e01a11091e34b..94fcbaa98d757c7030d024d7d505addaaf637a4a 100644 GIT binary patch delta 5316 zcmZ{oTZmm(8OL+Zfn3zn+~$&u9XpAQb|#rQXW!2;GpEU%``)=26j2Z{1`~@HG!65l z)VvEuJ{9^9XbAK{ur*dJ5{eC|n1GZ%NFZn-AoyUl$-B1x|KGPxcCw;*nBT0m*ZS{o zec$@8H9Obes$BY@@{1oH_|UI^|Cyhh?{3<3zWdsX2R2u#S@hbKPwc2k^WciyT-+t! zJh&+L7N_O-(#K?NX_tI&X;!|zv|E0;I4eH}|FXDu=P1~}aA9r#^B2zV@2qZgnt^Oy z%H+MJ?Q(T#zLLw0r4{+o!R_)sG;THOa`oVz-NACO+SurT$jc(a!LqXW+_d||ud86C1 zMO)+#Ydhp$(dJ4lHyShY;dpK;SZ;fxgC@mmUB^Oc@=qsodxPb7e|7oYmoE9U z0=@*Z0=cm^vn9}S+iN=M+*J5jO#`haCKwB)z2@^7C-`Lzw4j(^ER;6kd~0rZ_*i8F z7PZF)khA}bYrWLX5OXurxSgMBd$K?gNmZ~NJO#+(NQqE%ok_03P zNbX#Bk7`96!p8F-;pTLKM)Kzs26|;(MX%^sHlRr$P6DC?Lme$j~(_g7T3T5>)2Bw@76tV96F91$BsFODswnqT#tFVxb-CRUX$y2yRGYayUn$; zf%Onr4}tXr{mCONhkaNMfaN5bq|$eBD*q0!XK)6#@KSi}km6#ZI2Bkca?hq}BaFFw zwm zqESpSK+B1zFN(a(rKjeZQLrn>UOkk%F z2$?Rl20~^Zb|8R|=|Y5D+AwL!N1uhR{vpI1(}(=2vIJxaW&*%oA)re@m%wKceVCL! zOxlthfvnl83u-3Jh-lG>i5gKKF%f1&*UU-XE;M3V8Zm9k$)gKZKr4r2!jL^fpO~pw zV`vx|#)e!`D=?jTNJ}TCfjqYkUH8|rV-MWdm}WO`f`Q}EapX95%t0P@0PmW#bR>R# zbeD(zU&pCbj=`)1m!MuHCJn4dy=uUE=vAGB<(OB~(yM7CmwO9%z5|y5M1filo!p23 zHzHdwYYHF3tZ31!*2>Z1!IILf^|Ul=8q4c_WXZhOHEQ}-uwRf|U|?YW(PI7q=6_{| z6E#0($h0(M3Qr9ntcI+09eW_WjyQPd4bY<1-NTV`@-RnBrOlLSY05N}e+(h*Olf4y zm8Ql_AZ7wF6Ns5W%s?&23{_6`9#2b8rkUIxL0LVCpxxD&s^yRkHKhT{G^I9bV>crQ zRasrxNK04ZS8u!cUl*zSaxro_G$LL~U^xU{N?}*CIyNmGo3`cE9E)*| zb?kwd0H2p9$khzxU$Y^+(?3EnGhedgs$$;D0eDr*2L? z^k0v%_3Y=Wi_giI&mOM6^9{KSeD+&%=WJHJ`EA*KZnfHcUQV4`tN!MKTsn7P^9SGE Hgn$19r%k|j delta 2855 zcmZ9OU1(HC7>2WF(X6Q$-OV|hY$Hu05wbD5d(Lilvq@HTf6v)!5@QlmjmE~HEiLu0 z=}nDD>4i|K=|`a#dLdF;EY!aXFG``gD6~+lUI{Hy0=*C`NN7v1`t!asyBZbzp800x zy!+0aZ|3Cuf4;AO@?HC=W6c|0{bv`u>gxEvxlSIRipZ^w2Zocpd1>QXf5W4TA3plz z1N-5%3v#!!O>RUZ@=|oIFDCb+DcKPXN<7*sv(b=DMJ-=R%&so^G1@4DU2Q&Bj&^No znr=Hj(C)?C+fEL&pE!BEJ=;Hl+JdX&V9EzQzV4*F6O&%;ehhDXe5Qb6C3P8bgsY6C8kLzXO+*>S9|RjxxM z>jvd|g+3Vbh?Z&BLj;SK=|XzBBQN zoP8yP!Mke8T}VQUfEEEQ0$TGkrU5Nxt_H-A$*=K%%=U%lUx;1a5i;U7x7?otvFFv4 zda)r(XC{7ds!&au{4QoL>{2ta^_;@JziLP1o1OH=BE>=pm?I!Yz#PiDIs@Jo_9<^1 zf;V7QCGITS$tfoy_Xa7+vV|l8NtAiD4~p!=atTNhSS|rc0DG5E{?;WTvNRNufkeIh zJ<>?IB`gkANNly`>RsLQ=_{h1?6f=xr#2&K`MrAGZnBO)Uai1iiW1 z8$fTa>G$x!A_f8OT_zckjuE^HRsHf_G9Y6kYpbch!0sVT=BNUWKyA=PFJ1Vt428Sy*aak-rg%dLu9EKUO#i{pT~OyG}zKLTsTnb1S9m!>^g-IJDyQ7#fyE^qb( zq<*@QDoD9Z0x~!ldJ0w8hgA~TF`N{6zo%DDjD_TOPra0O!i=rX0`5^B3EZPZQ3Dq# zGhC!R1S;`+HV#(Cl7D(qa&A0?UR1yAPu0sks6mD`4jBS61Y`)v5V(&C+{g1Xmb{Zn z%jbJShFz_Da2T&wr_^EHtBkih>%KbE1zGn1>|pE|E{$TkMHVJ#>Uz?WlW{nH8{~mVHcqd6jZ3VaO4XW6A3TYV3m=tGjF`WH{5rB{KDp!drdf z$teoUmEIQlYcC~H#qy{(pvoVbENWOJAWA?KfM~KN%G5(j(d07G4Ve}cm@Qi~VHtPV z(i^H9qGxt1qey5Jpi$TKm1Pj;gf?0JHp}0Vxy(v@vKP}~xsYj*&ix_zKGUsKJY|g~ zU9@%C1HAe13+Qx_vFcT}s$!>>Su^`uBzFMsH_cC!KUZbG%0iXJDodI$xUJ8Ea9Vwi z&hd34~Be>s^*+VUZbE<)F>(V z%TA12?sq}n2ul!{e~kjX=^b^O<9S}{c%Ida=LtMdl=YaaGmn`SaNeWO#(p3-ON(eaiGR@I!M7}#jm$(t+HXAC{@q{f`k4(VB&4$;1Xli)+*R9+?HD>G{mgHQYv1(L~1ERihBbB{cj>o@l9m5rwdjNkUj%;}Dm(V05@`yYc@H}n7i diff --git a/01_copyFiles.py b/01_copyFiles.py index 9773dc7..c3a8002 100644 --- a/01_copyFiles.py +++ b/01_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 = "2505" -source_directory = r"C:\Users\dra\project\data\제2505회 정기\답안파일" # 원본 디렉토리 경로 +exam_round = "2504" +source_directory = r"C:\Users\dra\project\data\제2504회 정기\답안파일" # 원본 디렉토리 경로 target_directory_a = f".\\output\\{exam_round}\\A" # '1교시'의 타겟 경로 target_directory_b = f".\\output\\{exam_round}\\B" # '2교시'의 타겟 경로 diff --git a/DIC_2504B.json b/DIC_2504B.json new file mode 100644 index 0000000..a2c535e --- /dev/null +++ b/DIC_2504B.json @@ -0,0 +1,732 @@ +{ + "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=='Flower Rock')].name", + "value": "Flower Rock", + "point": 4 + }, + "7": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.names[0]", + "type": "font", + "value": "Arial", + "point": 2 + }, + "8": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.names[0]", + "value": "Arial-BoldItalicMT", + "point": 2 + }, + "9": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.sizes[0]", + "value": 48, + "point": 2 + }, + "10": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.colors[0]", + "type": "color", + "value": "d6f592", + "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": "0d17d5", + "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", + "이미지1.jpg", + "이미지2.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": "44", + "VID100": "8", + "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": "110", + "point": 2 + }, + "8": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "화단의 꽃들", + "type": "video.Text.Color", + "value": "ff531b", + "point": 2, + "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" + }, + "9": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']", + "search": "화단의 꽃들", + "type": "video.Location", + "value": [ + "0.38333333", + "0.92962962" + ], + "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": "67", + "VID102": "40" + }, + "point": 2 + }, + "15": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지3.jpg", + "value": { + "ID": "10", + "Range": "490:550", + "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": "184", + "VID102": "30" + }, + "point": 2 + }, + "18": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지1.jpg", + "value": { + "ID": "19", + "Range": "650:680", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "19": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", + "type": "imageLength", + "media": "이미지2.jpg", + "value": "180", + "point": 2 + }, + "20": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지2.jpg", + "value": { + "ID": "67", + "VID102": "30" + }, + "point": 2 + }, + "21": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지2.jpg", + "value": { + "ID": "10", + "Range": "800:860", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "22": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text", + "value": "아름다운 꽃 축제 (Happy Flower Festival)", + "point": 3 + }, + "23": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text", + "value": "궁서체", + "point": 2 + }, + "24": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text", + "value": "140", + "point": 2 + }, + "25": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text.Color", + "value": "fd5721", + "point": 2, + "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" + }, + "26": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text.Outline", + "value": { + "width": "30", + "color": "fff9c4" + }, + "point": 2, + "desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성" + }, + "27": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "opening.Text.FadeInEffect", + "value": { + "ID": "4", + "PlayTime": "2" + }, + "point": 3, + "desc": "오프닝자막의 나타나기 효과를 확인하는 문항. id속성은 VID505, playtime속성은 VID507으로 XML 내부에 표기되어 있다." + }, + "28": { + "ele": "{search}", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "opening.StartTime", + "value": 0, + "point": 2, + "desc": "오프닝자막의 시작시간 value 속성만 수정" + }, + "29": { + "ele": "{search}", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "opening.Length", + "value": 120, + "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": 810, + "point": 2 + }, + "32": { + "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "audio.Effect", + "media": "음악.mp3", + "value": { + "ID": "1", + "PlayTime": "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": "Flower", + "point": 5, + "desc": "Flower 레이어가 있는지 여부 체크" + }, + "4": { + "type": "layer.Effects", + "ele": "//Layer[Name[@value='{layer}']]/Effects/Item", + "layer": "Flower", + "value": { + "name": "세피아", + "option": { + "U":"75", + "V":"150" + } + }, + "point": 5, + "desc": "Flower 레이어의 효과 체크" + }, + "5": { + "ele": "none", + "point": 6, + "desc": "올가미 도구/이미지 문항은 채점 불가" + }, + "6": { + "type": "exists", + "ele": "//Layer/Effects/Item/Name/@value", + "value": "세피아", + "point": 6, + "desc": "세피아 효과가 있는지 여부 체크" + }, + "7": { + "type": "exact", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "ELLIPSE", + "point": 3, + "desc": "레이어 쉐이프 타입이 타원인지 체크" + }, + "8": { + "type": "size", + "ele": "//Layer//op_points", + "value": { + "width": 120, + "height": 120 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "9": { + "type": "color", + "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "7097bb", + "point": 6, + "desc": "색상 코드 비교 시 소문자로 입력할 것" + }, + "10": { + "type": "multiValue", + "ele": "//Layer/BlendOp/@value | //Layer/Opacity/@value", + "value": [ + "반사", + "80" + ], + "point": 6, + "desc": "혼합모드(색 회피율, 불투명도 : 80)" + }, + "11": { + "ele": "none", + "point": 0, + "desc": "기본설정" + }, + "12": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "5": { + "1": { + "type": "multi", + "ele": "//Document/Width/@value | //Document/Height/@value", + "value": [ + "650", + "450" + ], + "point": 5, + "desc": "캔버스 사이즈 650*450" + }, + "2": { + "ele": "none", + "point": 5, + "desc": "배경색 문항은 채점 불가" + }, + "3": { + "type": "exists", + "ele": "//Layer/MaskOpType/@value", + "value": "Layering", + "point": 6 + }, + "4": { + "ele": "none", + "point": 6, + "desc": "가로방향 흐릿하게 문항은 채점 불가" + }, + "5": { + "type": "exists", + "ele": "//Layer//shape_type/@value", + "value": "ROUNDED_RECTANGLE", + "point": 3 + }, + "6": { + "type": "size", + "ele": "//Layer//op_points", + "value": { + "width": 400, + "height": 60 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "7": { + "type": "gradient", + "ele": "//Layer/Shapes/Shape", + "startColor": "gradient_start_color/@value", + "endColor": "gradient_end_color/@value", + "value": { + "startColor": "ffe000", + "endColor": "34a159" + }, + "point": 6 + }, + "8": { + "type": "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": "Italic", + "value": "True", + "point": 3 + }, + "11": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value", + "value": "30", + "point": 3 + }, + "12": { + "type": "color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "b46ef8", + "point": 3, + "desc": "색상 코드 비교 시 소문자로 입력할 것" + }, + "13": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value", + "value": "7", + "point": 3 + }, + "14": { + "type": "color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value", + "value": "ffffff", + "point": 3, + "desc": "색상 코드 비교 시 소문자로 입력할 것" + }, + "15": { + "ele": "//Layer[MaskOpType/@value='Clipping'][last()]", + "point": 6, + "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함" + }, + "16": { + "type": "exists", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "RECTANGLE", + "point": 3 + }, + "17": { + "type": "size", + "ele": "//Layer//op_points", + "value": { + "width": 150, + "height": 150 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "18": { + "type": "exists", + "ele": "//Layer//outline_peninfo/Width/@value", + "value": "7", + "point": 3 + }, + "19": { + "type": "color", + "ele": "//Layer//Shape[contains(draw_type/@value, 'Outline')]/primary_color/@value", + "value": "e8e88e", + "point": 3, + "desc": "색상 코드 비교 시 소문자로 입력할 것(채우기:secondary_color, 외곽선:primary_color)" + }, + "20": { + "type": "shadow", + "ele": { + "shadow": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]", + "width": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_width/@value", + "distance": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_distance/@value", + "blur": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_blur/@value", + "angle": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_angle/@value" + }, + "value": { + "width": "3", + "distance": "5", + "blur": "1", + "angle": "320" + }, + "point": 5, + "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점" + }, + "21": { + "ele": "none", + "point": 0, + "desc": "기본설정" + }, + "22": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + } +} \ No newline at end of file diff --git a/DIC_2505B copy.json b/DIC_2505B copy.json new file mode 100644 index 0000000..9095736 --- /dev/null +++ b/DIC_2505B copy.json @@ -0,0 +1,729 @@ +{ + "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=='Traditional Park')].name", + "value": "Traditional Park", + "point": 4 + }, + "7": { + "ele": "$.children[?(@.name=='Traditional Park')].text.font.names[0]", + "type": "font", + "value": "Arial", + "point": 2 + }, + "8": { + "ele": "$.children[?(@.name=='Traditional Park')].text.font.names[0]", + "value": "Arial-BoldItalicMT", + "point": 2 + }, + "9": { + "ele": "$.children[?(@.name=='Traditional Park')].text.font.sizes[0]", + "value": 48, + "point": 2 + }, + "10": { + "ele": "$.children[?(@.name=='Traditional Park')].text.font.colors[0]", + "type": "color", + "value": "017e86", + "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": "ffeeca", + "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", + "이미지3.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": "120" + }, + "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": "70", + "VID100": "30", + "VID101": "20" + }, + "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": "120", + "point": 2 + }, + "8": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "청량하고 시원한 폭포", + "type": "video.Text.Color", + "value": "1db0f1", + "point": 2, + "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" + }, + "9": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']", + "search": "청량하고 시원한 폭포", + "type": "video.Location", + "value": [ + "0.27395833", + "0.9222222" + ], + "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": "이미지2.jpg", + "value": "150", + "point": 2 + }, + "14": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지2.jpg", + "value": { + "ID": "103", + "VID102": "7" + }, + "point": 2 + }, + "15": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지2.jpg", + "value": { + "ID": "11", + "Range": "500:530", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "16": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", + "type": "imageLength", + "media": "이미지3.jpg", + "value": "150", + "point": 2 + }, + "17": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지3.jpg", + "value": { + "ID": "184", + "VID102": "30" + }, + "point": 2 + }, + "18": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지3.jpg", + "value": { + "ID": "19", + "Range": "650:680", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "19": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", + "type": "imageLength", + "media": "이미지1.jpg", + "value": "180", + "point": 2 + }, + "20": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지1.jpg", + "value": { + "ID": "67", + "VID102": "30" + }, + "point": 2 + }, + "21": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지1.jpg", + "value": { + "ID": "10", + "Range": "800:860", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "22": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", + "search": "전통 공원 (Traditional Park)", + "type": "video.Text", + "value": "전통 공원 (Traditional Park)", + "point": 3 + }, + "23": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", + "search": "전통 공원 (Traditional Park)", + "type": "video.Text", + "value": "궁서체", + "point": 2 + }, + "24": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", + "search": "전통 공원 (Traditional Park)", + "type": "video.Text", + "value": "140", + "point": 2 + }, + "25": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "전통 공원 (Traditional Park)", + "type": "video.Text.Color", + "value": "fd5721", + "point": 2, + "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" + }, + "26": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']", + "search": "전통 공원 (Traditional Park)", + "type": "video.Text.Outline", + "value": { + "width": "30", + "color": "fff9c4" + }, + "point": 2, + "desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성" + }, + "27": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr", + "search": "전통 공원 (Traditional Park)", + "type": "opening.Text.FadeInEffect", + "value": { + "ID": "4", + "PlayTime": "2" + }, + "point": 3, + "desc": "오프닝자막의 나타나기 효과를 확인하는 문항. id속성은 VID505, playtime속성은 VID507으로 XML 내부에 표기되어 있다." + }, + "28": { + "ele": "", + "search": "전통 공원 (Traditional Park)", + "type": "opening.StartTime", + "value": 0, + "point": 2, + "desc": "오프닝자막의 시작시간 value 속성만 수정" + }, + "29": { + "ele": "", + "search": "전통 공원 (Traditional Park)", + "type": "opening.Length", + "value": 120, + "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": 810, + "point": 2 + }, + "32": { + "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "audio.Effect", + "media": "음악.mp3", + "value": { + "ID": "1", + "PlayTime": "90" + }, + "point": 2, + "desc": "ID속성-페이드인:0 / 페이드아웃:1" + }, + "33": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "4": { + "1": { + "type": "multi", + "ele": "//Document/Width/@value | //Document/Height/@value", + "value": [ + "650", + "350" + ], + "point": 5, + "desc": "캔버스 사이즈 650*350" + }, + "2": { + "ele": "none", + "point": 5, + "desc": "자유 변형 문항은 채점 불가" + }, + "3": { + "type": "isExist", + "ele": "//Layer/Name/@value", + "value": "Flower", + "point": 5, + "desc": "Flower 레이어가 있는지 여부 체크" + }, + "4": { + "type": "multiValue", + "ele": "//Layer[Name[@value='{layer}']]/Effects/Item[EffectData/{option}]/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value", + "layer": "Flower", + "option": "VibranceValue", + "value": [ + "39", + "생동감" + ], + "point": 5, + "desc": "Flower 레이어의 효과 체크" + }, + "5": { + "ele": "none", + "point": 6, + "desc": "올가미 도구/이미지 문항은 채점 불가" + }, + "6": { + "type": "exists", + "ele": "//Layer/Effects/Item/Name/@value", + "value": "세피아", + "point": 6, + "desc": "세피아 효과가 있는지 여부 체크" + }, + "7": { + "type": "exact", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "ELLIPSE", + "point": 3, + "desc": "레이어 쉐이프 타입이 타원인지 체크" + }, + "8": { + "type": "size", + "ele": "//Layer//op_points", + "value": { + "width": 120, + "height": 120 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "9": { + "type": "color", + "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "7097bb", + "point": 6, + "desc": "색상 코드 비교 시 소문자로 입력할 것" + }, + "10": { + "type": "multiValue", + "ele": "//Layer/BlendOp/@value | //Layer/Opacity/@value", + "value": [ + "반사", + "80" + ], + "point": 6, + "desc": "혼합모드(색 회피율, 불투명도 : 80)" + }, + "11": { + "ele": "none", + "point": 0, + "desc": "기본설정" + }, + "12": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "5": { + "1": { + "type": "multi", + "ele": "//Document/Width/@value | //Document/Height/@value", + "value": [ + "650", + "450" + ], + "point": 5, + "desc": "캔버스 사이즈 650*450" + }, + "2": { + "ele": "none", + "point": 5, + "desc": "배경색 문항은 채점 불가" + }, + "3": { + "type": "exists", + "ele": "//Layer/MaskOpType/@value", + "value": "Layering", + "point": 6 + }, + "4": { + "ele": "none", + "point": 6, + "desc": "가로방향 흐릿하게 문항은 채점 불가" + }, + "5": { + "type": "exists", + "ele": "//Layer//shape_type/@value", + "value": "ROUNDED_RECTANGLE", + "point": 3 + }, + "6": { + "type": "size", + "ele": "//Layer//op_points", + "value": { + "width": 400, + "height": 60 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "7": { + "type": "gradient", + "ele": "//Layer/Shapes/Shape", + "startColor": "gradient_start_color/@value", + "endColor": "gradient_end_color/@value", + "value": { + "startColor": "ffe000", + "endColor": "34a159" + }, + "point": 6 + }, + "8": { + "type": "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": "Italic", + "value": "True", + "point": 3 + }, + "11": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value", + "value": "30", + "point": 3 + }, + "12": { + "type": "color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "b46ef8", + "point": 3, + "desc": "색상 코드 비교 시 소문자로 입력할 것" + }, + "13": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value", + "value": "7", + "point": 3 + }, + "14": { + "type": "color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value", + "value": "ffffff", + "point": 3, + "desc": "색상 코드 비교 시 소문자로 입력할 것" + }, + "15": { + "ele": "//Layer[MaskOpType/@value='Clipping'][last()]", + "point": 6, + "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함" + }, + "16": { + "type": "exists", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "RECTANGLE", + "point": 3 + }, + "17": { + "type": "size", + "ele": "//Layer//op_points", + "value": { + "width": 150, + "height": 150 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "18": { + "type": "exists", + "ele": "//Layer//outline_peninfo/Width/@value", + "value": "7", + "point": 3 + }, + "19": { + "type": "color", + "ele": "//Layer//Shape[contains(draw_type/@value, 'Outline')]/primary_color/@value", + "value": "e8e88e", + "point": 3, + "desc": "색상 코드 비교 시 소문자로 입력할 것(채우기:secondary_color, 외곽선:primary_color)" + }, + "20": { + "type": "shadow", + "ele": { + "shadow": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]", + "width": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_width/@value", + "distance": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_distance/@value", + "blur": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_blur/@value", + "angle": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_angle/@value" + }, + "value": { + "width": "3", + "distance": "5", + "blur": "1", + "angle": "320" + }, + "point": 5, + "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점" + }, + "21": { + "ele": "none", + "point": 0, + "desc": "기본설정" + }, + "22": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + } +} \ No newline at end of file diff --git a/DIC_2505B.json b/DIC_2505B.json index 73c20d1..b457875 100644 --- a/DIC_2505B.json +++ b/DIC_2505B.json @@ -464,7 +464,7 @@ "PlayTime": "90" }, "point": 2, - "desc": "ID속성-페이드인[0]/페이드아웃[1]" + "desc": "ID속성-페이드인:0 / 페이드아웃: 1" }, "33": { "ele": "none", diff --git a/gpdpScoring.js b/gpdpScoring.js index 9ff6ac0..0981e66 100644 --- a/gpdpScoring.js +++ b/gpdpScoring.js @@ -42,6 +42,54 @@ module.exports = getGpdpScore; // scoring.json 파일 내에 있는 type에 따라 비교하는 방식이 달라짐 // 채점 결과를 scoringResultList 배열에 저장 function getGpdpScore(gpdpData, scoringJson, index) { + function compareAndScore(user, right, point, key, scoringResult, options = {}) { + let score = 0; + let isEqual = false; + + const { + tolerance = 0, // 숫자 비교 시 허용 오차 + type = 'auto', // 'auto' | 'number[]' | 'string[]' | 'object' | 'primitive' + } = options; + + if (type === 'force-correct') { + isEqual = true; + } + else if (Array.isArray(right) && Array.isArray(user)) { + if (right.length === user.length) { + if + (type === 'number[]' || + (type === 'auto' && typeof right[0] === 'number')) { + isEqual = right.every((val, idx) => Math.abs(val - user[idx]) <= tolerance); + } + else if + (type === 'string[]' || + (type === 'auto' && typeof right[0] === 'string')) { + isEqual = right.every((val, idx) => val === user[idx]); + } + } + } + else if + (type === 'object' || + (type === 'auto' && typeof right === 'object' && typeof user === 'object')) { + isEqual = JSON.stringify(user) === JSON.stringify(right); + } + else { + isEqual = user == right; // primitive 비교 + } + + if (isEqual) { + score = point; + console.log('작성답안: ', user); + console.log('>⭕ 정답: ', right); + } else { + console.log('작성답안: ', user); + console.log('>❌ 오답: ', right); + } + + scoringResult[key] = score; + // totalScore += score; + return score; + } const gpdpXmlDoc = gpdpData; const scoringResult = {}; @@ -64,11 +112,13 @@ function getGpdpScore(gpdpData, scoringJson, index) { let ele = scoringData[key].ele; let ele2 = scoringData[key].ele2; let existEle = scoringData[key].existEle; - let rightAnswer = scoringData[key].value; - let point = scoringData[key].point; - let type = scoringData[key].type; + const rightAnswer = scoringData[key].value; + const point = scoringData[key].point; + const type = scoringData[key].type; let search = scoringData[key].search; + let userAnswer = null; + const layer = scoringData[key].layer; const option = scoringData[key].option; const style = scoringData[key].style; @@ -88,33 +138,151 @@ function getGpdpScore(gpdpData, scoringJson, index) { existEle = existEle.replace(/{search}/g, result); } } - console.log(`example number: ${key}`) - console.log("🚀 ~ getGpdpScore ~ ele:", ele) - // if (type == "effects") { - // // Layer/Effects/Item요소를 가져옴 - // const items = xpath.select(ele, gpdpXmlDoc); + console.log(`❔문제번호 : [4-${key}]`) - // // let isRight = false; - // // 각 Item 요소별 이름과 속성값을 구하고 정답과 비교 - // items.forEach((item) => { - // const name = xpath.select1('Name/@value', item)?.value; - // const value = xpath.select1(`EffectData/${option?.replace(/"/g, '')}/@value`, item)?.value; - // const resultArray = [name, value]; - // // if (isRight) return; - // if (JSON.stringify(resultArray) === JSON.stringify(rightAnswer)) { - // totalScore += point; - // scoringResult[key] = point; - // console.log("🚀 ~ 정답 일치:", rightAnswer); - // // isRight = true; - // return; - // } else { - // scoringResult[key] = 0; - // console.log("🚀 ~ 오답:", rightAnswer); - // } - // }); - // } - if (type == "boolean") { + if (type === "none") { + console.log("❌ 채점하지 않음"); + scoringResult[key] = "확인필요"; + continue; + } + + else if (type === "canvas.Size") { + const result = xpath.select(ele, gpdpXmlDoc); + const width = result[0].value; + const height = result[1].value; + + userAnswer = [width, height]; + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult, { type: 'number[]' }); + + continue; + } + + // [] + else if (type === "layer.Exists") { + const layerNameList = xpath.select(ele, gpdpXmlDoc); + const layerNames = layerNameList.map(layer => layer.value); + console.log("🚀 ~ getGpdpScore ~ layerNames:", layerNames); + + // userAnswer = layerNames.find(name => name === rightAnswer); + for (const layerName of layerNames) { + if (layerName.trim().toLowerCase() === rightAnswer.trim().toLowerCase()) { + userAnswer = layerName; + break; + } + } + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); + continue; + } + + // [1-4] 사진1 > 조정 + else if (type === "layer.Effects") { + const effects = xpath.select(ele, gpdpXmlDoc); + + let isMatched = false; + for (const item of effects) { + const name = xpath.select1('Name/@value', item)?.value; + const effectData = xpath.select1(`EffectData`, item); + + // 동일한 이펙트 요소만 검사 + if (rightAnswer['name'] !== name) { + continue; + } + + userAnswer = { + name: name, + option: {}, + } + if (name === '흑백') { + const Intensity = xpath.select1('Intensity/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('강도')) userAnswer['option']['강도'] = Intensity; + } + else if (name === '밝기/대비') { + const brightness = xpath.select1('brightness/@value', effectData)?.value; + const contrast = xpath.select1('contrast/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('밝기')) userAnswer['option']['밝기'] = brightness; + if (optionKeys.includes('대비')) userAnswer['option']['대비'] = contrast; + } + else if (name === '노출') { + const ExposureValue = xpath.select1('ExposureValue/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('노출')) userAnswer['option']['노출'] = ExposureValue; + } + else if (name === '색조/채도') { + const hue = xpath.select1('hue/@value', effectData)?.value; + const saturation = xpath.select1('saturation/@value', effectData)?.value; + const lightness = xpath.select1('lightness/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('색조')) userAnswer['option']['색조'] = hue; + if (optionKeys.includes('채도')) userAnswer['option']['채도'] = saturation; + if (optionKeys.includes('명도')) userAnswer['option']['명도'] = lightness; + } + else if (name === '감마') { + const lift = xpath.select1('Lift/@value', effectData)?.value; + const gamma = xpath.select1('Gamma/@value', effectData)?.value; + const gain = xpath.select1('Gain/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('리프트')) userAnswer['option']['리프트'] = lift; + if (optionKeys.includes('감마')) userAnswer['option']['감마'] = gamma; + if (optionKeys.includes('게인')) userAnswer['option']['게인'] = gain; + } + else if (name === '세피아') { + const u = xpath.select1('U/@value', effectData)?.value; + const v = xpath.select1('V/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']).map(key => key.toUpperCase()); + if (optionKeys.includes('U')) userAnswer['option']['U'] = u; + if (optionKeys.includes('V')) userAnswer['option']['V'] = v; + } + else if (name === '생동감') { + const vibranceValue = xpath.select1('VibranceValue/@value', effectData)?.value; + // 생동감 옵션값이 프로그램에서 적용한 값에 오차가 발생하는 경우가 있음 + // 곰픽>XML / 30>29 / 40>39 + // 설정한 값 그대로 적용되는 경우도 있어서 오차범위를 설정 + const userValue = parseInt(vibranceValue, 10); + const rightValue = parseInt(rightAnswer.option['생동감'], 10); + + if (Math.abs(rightValue - userValue) <= 2) { + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('생동감')) { + userAnswer['option']['생동감'] = rightValue.toString(); + } + } + } + + for (const key in rightAnswer.option) { + // 속성값이 정답과 다른 경우가 있으면 오답처리 + if (rightAnswer.option[key] !== userAnswer.option[key]) { + isMatched = false; + break; + } + else { + isMatched = true; + } + } + + // 속성값이 하나라도 일치하지 않으면 오답 + if (isMatched === false) { + break; + } + } + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); + continue; + } + + + // [1-6] 세피아 + else if (type === "sepia.Exists") { + + } + else if (type == "boolean") { const items = xpath.select(ele, gpdpXmlDoc); // xpath 결과값을 반환하는 요소가 없을 경우 diff --git a/psdExport_2.js b/psdExport_2.js index 997574e..d98594c 100644 --- a/psdExport_2.js +++ b/psdExport_2.js @@ -13,9 +13,9 @@ const { userInfo } = require('os'); const { get } = require('http'); const todayDate = getToday(); -const examRound = '2505'; -const dic_or_dpi = 'DIC' -// const dic_or_dpi = 'DPI' +const examRound = '2504'; +// const dic_or_dpi = 'DIC' +const dic_or_dpi = 'DPI' const examTypes = [ // 'A', 'B', @@ -24,8 +24,8 @@ const examTypes = [ ]; // testMode가 true일 경우 TEST 폴더에 있는 답안 파일을 읽어옴 -// const testMode = false; -const testMode = true; +const testMode = false; +// const testMode = true; const outputExcelFiles = []; @@ -188,15 +188,24 @@ function getGmepScore(gmepData, scoringJson, index) { } else if (Array.isArray(right) && Array.isArray(user)) { if (right.length === user.length) { - if (type === 'number[]' || (type === 'auto' && typeof right[0] === 'number')) { + if + (type === 'number[]' || + (type === 'auto' && typeof right[0] === 'number')) { isEqual = right.every((val, idx) => Math.abs(val - user[idx]) <= tolerance); - } else if (type === 'string[]' || (type === 'auto' && typeof right[0] === 'string')) { + } + else if + (type === 'string[]' || + (type === 'auto' && typeof right[0] === 'string')) { isEqual = right.every((val, idx) => val === user[idx]); } } - } else if (type === 'object' || (type === 'auto' && typeof right === 'object' && typeof user === 'object')) { + } + else if + (type === 'object' || + (type === 'auto' && typeof right === 'object' && typeof user === 'object')) { isEqual = JSON.stringify(user) === JSON.stringify(right); - } else { + } + else { isEqual = user == right; // primitive 비교 } @@ -210,6 +219,7 @@ function getGmepScore(gmepData, scoringJson, index) { } scoringResult[key] = score; + // totalScore += score; return score; } @@ -246,6 +256,8 @@ function getGmepScore(gmepData, scoringJson, index) { // 채점기준표 문항별 분류 for (const key in scoringData) { + + // XML 요소의 index값을 구함 function getCRClipIndex(mediaName) { // CRClipArr/CRClip 요소의 Path속성 리스트를 구함 // 모션 클립 이미지도 고려해 처리 @@ -371,9 +383,6 @@ function getGmepScore(gmepData, scoringJson, index) { } let ele = scoringData[key].ele; - let ele2 = scoringData[key].ele2; - let ele3 = scoringData[key].ele3; - let existEle = scoringData[key].existEle; const rightAnswer = scoringData[key].value; const point = scoringData[key].point; const type = scoringData[key].type ? scoringData[key].type : ''; @@ -389,23 +398,7 @@ function getGmepScore(gmepData, scoringJson, index) { console.log(`example number: ${key}`) - // xpath 전처리 - const trackClipNode = getTrackClipNode(gmepXmlDoc, type, videoStartTime, openingStartTime); - const subtitleIndex = trackClipNode ? parseInt(trackClipNode.getAttribute('ClipIndex'), 10) + 1 : null; - const textClipIndex = getTextClipIndex(gmepXmlDoc, search); const subtitleOrder = type.includes('opening') ? 1 : type.includes('video') ? 2 : null; - const startTime = type === 'video' ? videoStartTime : type === 'opening' ? openingStartTime : null; - - let xpathList = [ele, ele2, ele3, existEle]; - xpathList = xpathList.map(e => e ? e - .replace(/{subtitleIndex}/g, subtitleIndex) - .replace(/{subtitleOrder}/g, subtitleOrder) - .replace(/{startTime}/g, startTime) - .replace(/{textClipIndex}/g, textClipIndex) - .replace(/{image}/g, image) - : e - ); - [ele, ele2, ele3, existEle] = xpathList; // search 값이 undefined 아니면 ele의 {search}부분을 search로 치환 /** @@ -420,9 +413,10 @@ function getGmepScore(gmepData, scoringJson, index) { if (result !== null) { result = result.replace(/"/g, "'"); search = result; - [ele, ele2, ele3, existEle] = [ele, ele2, ele3, existEle].map(e => e?.replace(/{search}/g, search)); - } else { - [ele, ele2, ele3] = [ele, ele2, ele3].map(e => e?.includes('{search}') ? null : e); + ele = ele?.replace(/{search}/g, search); + } + else { + ele = ele?.includes('{search}') ? null : ele; } } @@ -432,11 +426,7 @@ function getGmepScore(gmepData, scoringJson, index) { continue; } - if (type == "boolean") { - scoringResult[key] = result.length > 0 ? point : 0; - } - - else if (type == "oneAnswer") { + if (type == "oneAnswer") { const result = xpath.select1(ele, gmepXmlDoc); // userAnswer = {}; @@ -668,7 +658,7 @@ function getGmepScore(gmepData, scoringJson, index) { const fadeoutEffect = xpath.select1(xpathQuery, gmepXmlDoc); if (!fadeoutEffect) { userAnswer = null; - } + } else { const attributes = fadeoutEffect.attributes; const id = attributes.getNamedItem('ID').value; @@ -697,6 +687,12 @@ function getGmepScore(gmepData, scoringJson, index) { const indexByStartTime = getCilpIndexByStartTime(time); // 1, 2, 3순으로 자막을 찾음 + + + // 권수혁 김재은 27, 28, 29 문제 오답 0점 채점 안되는 부분 처리 + // 06.18(목) 시작 + + const index = indexByText ?? indexByOrder ?? indexByStartTime; if (index != null) { // 자막 시작시간 [2-10] [2-28] @@ -780,6 +776,7 @@ function getGmepScore(gmepData, scoringJson, index) { } else { userAnswer = null; + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); } } diff --git a/z.xbook b/z.xbook index a6c5450..9010b61 100644 --- a/z.xbook +++ b/z.xbook @@ -1 +1 @@ -[{"kind":2,"language":"xpath","value":"//Layer[Name[@value='Tracking']]/Effects/Item/Name/@value"},{"kind":2,"language":"xpath","value":"sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[@ClipIndex=0]/preceding-sibling::CRTrackClip/@Length)"},{"kind":2,"language":"xpath","value":"//CROwneUnit/CRCUnitArr[@Name=\"아름다운 꽃 축제 (Happy Flower Festival)\"]/@Name"},{"kind":2,"language":"xpath","value":"//Layer[Name[@value='{layer}']]/Effects/Item[EffectData/{option}]/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value"},{"kind":2,"language":"xpath","value":"//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='3']/@Length"},{"kind":2,"language":"xpath","value":"//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='이미지3.jpg']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='이미지3.jpg']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']"},{"kind":2,"language":"xpath","value":"//CROwneUnit[1]/CRCUnitArr/@*[name()='VID600' or name()='VID601']"},{"kind":2,"language":"xpath","value":"//CRClipArr/CRClip[@Type='11']/CRCUnitArr/@Path | //CRClipArr/CRClip[not(@Type='11')]/@Path"}] \ No newline at end of file +[{"kind":2,"language":"xpath","value":"//Layer[Name[@value='Tracking']]/Effects/Item/Name/@value"},{"kind":2,"language":"xpath","value":"sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[@ClipIndex=0]/preceding-sibling::CRTrackClip/@Length)"},{"kind":2,"language":"xpath","value":"//CROwneUnit/CRCUnitArr[@Name=\"아름다운 꽃 축제 (Happy Flower Festival)\"]/@Name"},{"kind":2,"language":"xpath","value":"//Layer[Name[@value='{layer}']]/Effects/Item[EffectData/{option}]/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value"},{"kind":2,"language":"xpath","value":"//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='3']/@Length"},{"kind":2,"language":"xpath","value":"//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='이미지3.jpg']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='이미지3.jpg']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']"},{"kind":2,"language":"xpath","value":"//Document/Width/@value | //Document/Height/@value"},{"kind":2,"language":"xpath","value":"//Layer[Name[@value='Flower']]/Effects/Item[EffectData/VibranceValue]/(Name/@value | EffectData/VibranceValue/@value)"},{"kind":2,"language":"xpath","value":"//Layer[Name[@value='Flower']]/Effects/Item[EffectData/VibranceValue]/Name/@value | //Layer[Name[@value='Flower']]/Effects/Item/EffectData/VibranceValue/@value"}] \ No newline at end of file diff --git a/회차별채점자료/2504/excel_채점기준표/DIC_2504B.xlsx b/회차별채점자료/2504/excel_채점기준표/DIC_2504B.xlsx index 172bc18cff86d6cd68d8c6b0f25fdcd4d2283c22..b6cded62a18f638b6202a9ee8006466364986554 100644 GIT binary patch delta 12039 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 diff --git a/회차별채점자료/2505/excel_채점기준표/DIC_2505B.xlsx b/회차별채점자료/2505/excel_채점기준표/DIC_2505B.xlsx index d9966dd08a5ec7bb267c81f2c60943aa8307f437..479d726d07ac1483b7c077bbcab01698a8f5231a 100644 GIT binary patch delta 9232 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�n%lCU?ao0VrQCkl!fL&(I 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 i9bo`~I9LDx`~Ncktwte6@**%skZ