2507회 채점자료 추가
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,6 +1,12 @@
|
|||||||
.venv/
|
.venv/
|
||||||
|
|
||||||
|
# 기본적으로 output 디렉토리 전체 무시
|
||||||
output/
|
output/
|
||||||
|
|
||||||
|
# 예외 처리: 2단계 하위 폴더의 .xlsx 파일은 추적
|
||||||
|
!output/*/
|
||||||
|
!output/*/*.xlsx
|
||||||
|
|
||||||
sample/
|
sample/
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ def copy_ent_files(source_root, target_root):
|
|||||||
print(f"Copied {source_file_path} to {target_file_path}")
|
print(f"Copied {source_file_path} to {target_file_path}")
|
||||||
|
|
||||||
# 사용법
|
# 사용법
|
||||||
source_directory = r"D:\project\data\CAS_제2506회 정기\답안파일\제2506회 코딩활용능력 2급 답안파일" # 원본 디렉토리 경로
|
source_directory = r"D:\project\data\CAT_제2507회 정기\채점의뢰" # 원본 디렉토리 경로
|
||||||
target_directory = r"./ent/2506_CAS_2_A"
|
target_directory = r"./ent/2507_CAT_3_A"
|
||||||
target_directory_a = r"./output/A" # '1교시'의 타겟 경로
|
target_directory_a = r"./output/A" # '1교시'의 타겟 경로
|
||||||
target_directory_b = r"./output/B" # '2교시'의 타겟 경로
|
target_directory_b = r"./output/B" # '2교시'의 타겟 경로
|
||||||
target_directory_c = r"./output/C" # '3교시'의 타겟 경로
|
target_directory_c = r"./output/C" # '3교시'의 타겟 경로
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ def process_ent_files(ent_dir, output_dir):
|
|||||||
|
|
||||||
# 실행 예
|
# 실행 예
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test_name = "2506_CAS_2_A"
|
test_name = "2507_CAT_3_A"
|
||||||
ent_dir = f".\\ent\\{test_name}"
|
ent_dir = f".\\ent\\{test_name}"
|
||||||
output_dir = f".\\output\\{test_name}"
|
output_dir = f".\\output\\{test_name}"
|
||||||
process_ent_files(ent_dir, output_dir)
|
process_ent_files(ent_dir, output_dir)
|
||||||
|
|||||||
BIN
__pycache__/logging_config.cpython-312.pyc
Normal file
BIN
__pycache__/logging_config.cpython-312.pyc
Normal file
Binary file not shown.
362
correct/2507_CAT_3_A.json
Normal file
362
correct/2507_CAT_3_A.json
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
{
|
||||||
|
"1-1": {
|
||||||
|
"type": "scene",
|
||||||
|
"ele": "$..objects[?(@.name=='실험실')]",
|
||||||
|
"points": 2,
|
||||||
|
"desc": "문제 1/교실 뒤(3)/[배경] 이름 설정/이름을 '실험실'으로 변경하기"
|
||||||
|
},
|
||||||
|
"1-2": {
|
||||||
|
"type": "scene",
|
||||||
|
"ele": "$..objects[?(@.name=='새로운 약')]",
|
||||||
|
"points": 2,
|
||||||
|
"desc": "문제 1/물약(빨강)/[개체] 이름 설정 1/이름을 '새로운 약'으로 변경하기"
|
||||||
|
},
|
||||||
|
"1-4": {
|
||||||
|
"type": "scene",
|
||||||
|
"ele": "$..objects[?(@.name=='불')]",
|
||||||
|
"points": 2,
|
||||||
|
"desc": "문제 1/불(2)/[개체] 이름 설정 2/이름을 '불'로 변경하기"
|
||||||
|
},
|
||||||
|
"1-5": {
|
||||||
|
"type": "scene",
|
||||||
|
"ele": "$..objects[?(@.name=='마법사')]",
|
||||||
|
"points": 2,
|
||||||
|
"desc": "문제 1/꼬마 마법사/[개체] 이름 설정 3/이름을 '마법사'로 변경하기"
|
||||||
|
},
|
||||||
|
"1-6": {
|
||||||
|
"type": "scene",
|
||||||
|
"ele": "$..objects[?(@.name=='마법의 약')]",
|
||||||
|
"points": 2,
|
||||||
|
"desc": "문제 1/마법의 약/[개체] 이름 설정 4/이름 변경 없음"
|
||||||
|
},
|
||||||
|
"2-0": {
|
||||||
|
"type": "script",
|
||||||
|
"ele": "$.objects[?(@.name=~'새로운 약|물약')].script",
|
||||||
|
"blocks": [
|
||||||
|
{
|
||||||
|
"ele": "$[0][0].type",
|
||||||
|
"answer": "when_run_button_click",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/새로운 약/시작/시작하기 버튼을 클릭했을 때"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][1].type",
|
||||||
|
"$[0][1].params[0].params[0]",
|
||||||
|
"$[0][1].params[1].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["locate_xy", "50", "5"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/새로운 약/[시작]의 세부 동작 1/x: '50' y: '5' 위치로 이동하기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][2].params[0].params[0]",
|
||||||
|
"answer": "60",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/새로운 약/[시작]의 세부 동작 2/크기를 '60' 으로 정하기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[1][0].type",
|
||||||
|
"answer": "when_object_click",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/새로운 약/오브젝트/오브젝트를 클릭했을 때"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": ["$[1][1].type", "$[1][1].params[0]"],
|
||||||
|
"answer": ["repeat_inf", null],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/새로운 약/반복/계속 반복하기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[1][1].statements[0][0].type",
|
||||||
|
"answer": "locate",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/새로운 약/[반복]의 세부 동작/'마우스 포인터' 위치로 이동하기"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3-0": {
|
||||||
|
"type": "script",
|
||||||
|
"ele": "$.objects[?(@.name=~'불')].script",
|
||||||
|
"blocks": [
|
||||||
|
{
|
||||||
|
"ele": "$[0][0].type",
|
||||||
|
"answer": "when_run_button_click",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/시작/시작하기 버튼을 클릭했을 때"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][1].type",
|
||||||
|
"$[0][1].params[0].params[0]",
|
||||||
|
"$[0][1].params[1].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["locate_xy", "-150", "-30"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[시작]의 세부 동작 1/x: '-150' y: '-30' 위치로 이동하기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][2].params[0].params[0]",
|
||||||
|
"answer": "90",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[시작]의 세부 동작 2/크기를 '90' 으로 정하기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": ["$[0][3].type", "$[0][3].params[0]"],
|
||||||
|
"answer": ["repeat_inf", null],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/반복/계속 반복하기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][0].type",
|
||||||
|
"$[0][3].statements[0][0].params[0].params[1].params[0]",
|
||||||
|
"$[0][3].statements[0][0].params[0].params[3].params[0]",
|
||||||
|
"$[0][3].statements[0][0].params[1].params[1].params[0]",
|
||||||
|
"$[0][3].statements[0][0].params[1].params[3].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["locate_xy", "-150", "0", "-10", "40"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[반복]의 세부 동작 1/x: '-150 부터 0 사이의 무작위 수' y: '-10 부터 40 사이의 무작위 수' 위치로 이동하기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][3].statements[0][1].type",
|
||||||
|
"answer": "hide",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[반복]의 세부 동작 2/모양 숨기기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][2].type",
|
||||||
|
"$[0][3].statements[0][2].params[0].type",
|
||||||
|
"$[0][3].statements[0][2].params[0].params[1].params[0]",
|
||||||
|
"$[0][3].statements[0][2].params[0].params[3].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["wait_second", "calc_rand", "1", "2"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[반복]의 세부 동작 3/'1 부터 2 사이의 무작위 수' 초 기다리기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][3].statements[0][3].type",
|
||||||
|
"answer": "show",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[반복]의 세부 동작 4/모양 보이기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][4].type",
|
||||||
|
"$[0][3].statements[0][4].params[0].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["wait_second", "0.5"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[반복]의 세부 동작 5/'0.5' 초 기다리기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][5].type",
|
||||||
|
"$[0][3].statements[0][5].params[0].type"
|
||||||
|
],
|
||||||
|
"answer": ["_if", "reach_something"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/만일/만일 '새로운 약' 에 닿았는가? 라면",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][3].statements[0][5].statements[0][0].params[0].params[0]",
|
||||||
|
"answer": "300",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[만일]의 세부 동작 1/크기를 '300' 으로 정하기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][5].statements[0][1].type",
|
||||||
|
"$[0][3].statements[0][5].statements[0][1].params[0].params[0]",
|
||||||
|
"$[0][3].statements[0][5].statements[0][1].params[1]"
|
||||||
|
],
|
||||||
|
"answer": ["dialog", "마법 실패", "speak"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[만일]의 세부 동작 2/'마법 실패' 를 '말하기'",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][5].statements[0][2].type",
|
||||||
|
"$[0][3].statements[0][5].statements[0][2].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["stop_object", "all"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/불/[만일]의 세부 동작 3/'모든' 코드 멈추기",
|
||||||
|
"type": "list"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4-0": {
|
||||||
|
"type": "script",
|
||||||
|
"ele": "$.objects[?(@.name=~'마법사')].script",
|
||||||
|
"blocks": [
|
||||||
|
{
|
||||||
|
"ele": "$[0][0].type",
|
||||||
|
"answer": "when_run_button_click",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법사/시작/시작하기 버튼을 클릭했을 때"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][1].type",
|
||||||
|
"$[0][1].params[0].params[0]",
|
||||||
|
"$[0][1].params[1].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["locate_xy", "135", "-20"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법사/[시작]의 세부 동작 1/x: '135' y: '-20' 위치로 이동하기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][2].params[0].params[0]",
|
||||||
|
"answer": "180",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법사/[시작]의 세부 동작 2/크기를 '180' 으로 정하기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][3].params[*].params",
|
||||||
|
"answer": ["마법 실험을 해봐야지!", "2"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법사/[시작]의 세부 동작 3/'마법 실험을 해봐야지!' 를 '2' 초 동안 '말하기'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"5-0": {
|
||||||
|
"type": "script",
|
||||||
|
"ele": "$.objects[?(@.name=~'마법의 약')].script",
|
||||||
|
"blocks": [
|
||||||
|
{
|
||||||
|
"ele": "$[0][0].type",
|
||||||
|
"answer": "when_run_button_click",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/시작/시작하기 버튼을 클릭했을 때"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][1].type",
|
||||||
|
"$[0][1].params[0].params[0]",
|
||||||
|
"$[0][1].params[1].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["locate_xy", "-40", "10"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[시작]의 세부 동작 1/x: '-40' y: '10' 위치로 이동하기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][2].params[0].params[0]",
|
||||||
|
"answer": "50",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[시작]의 세부 동작 2/크기를 '50' 으로 정하기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": ["$[0][3].type", "$[0][3].params[0]"],
|
||||||
|
"answer": ["repeat_inf", null],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/반복/계속 반복하기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][3].statements[0][0].type",
|
||||||
|
"answer": "hide",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[반복]의 세부 동작 1/모양 숨기기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][1].type",
|
||||||
|
"$[0][3].statements[0][1].params[0].params[1].params[0]",
|
||||||
|
"$[0][3].statements[0][1].params[0].params[3].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["locate_x", "-160", "60"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[반복]의 세부 동작 2/x: '-160 부터 60 사이의 무작위 수' 위치로 이동하기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][2].type",
|
||||||
|
"$[0][3].statements[0][2].params[0].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["wait_second", "2"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[반복]의 세부 동작 3/ '2' 초 기다리기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][3].statements[0][3].type",
|
||||||
|
"answer": "show",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[반복]의 세부 동작 4/모양 보이기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][4].type",
|
||||||
|
"$[0][3].statements[0][4].params[0].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["wait_second", "0.5"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[반복]의 세부 동작 5/'0.5' 초 기다리기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][5].type",
|
||||||
|
"$[0][3].statements[0][5].params[0].type"
|
||||||
|
],
|
||||||
|
"answer": ["_if", "reach_something"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/만일/만일 '새로운 약' 에 닿았는가? 라면",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": "$[0][3].statements[0][5].statements[0][0].params[0].params[0]",
|
||||||
|
"answer": "100",
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[만일]의 세부 동작 1/크기를 '100' 으로 정하기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][5].statements[0][1].type",
|
||||||
|
"$[0][3].statements[0][5].statements[0][1].params[0]",
|
||||||
|
"$[0][3].statements[0][5].statements[0][1].params[1].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["add_effect_amount", "color", "70"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[만일]의 세부 동작 2/'색깔' 효과를 '70' 만큼 주기",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][5].statements[0][2].type",
|
||||||
|
"$[0][3].statements[0][5].statements[0][2].params[0].params[0]",
|
||||||
|
"$[0][3].statements[0][5].statements[0][2].params[1]"
|
||||||
|
],
|
||||||
|
"answer": ["dialog", "마법 성공", "speak"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[만일]의 세부 동작 3/'마법 성공' 을 '말하기'",
|
||||||
|
"type": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ele": [
|
||||||
|
"$[0][3].statements[0][5].statements[0][3].type",
|
||||||
|
"$[0][3].statements[0][5].statements[0][3].params[0]"
|
||||||
|
],
|
||||||
|
"answer": ["stop_object", "all"],
|
||||||
|
"points": 2.43,
|
||||||
|
"desc": "문제 2/마법의 약/[만일]의 세부 동작 4/'모든' 코드 멈추기",
|
||||||
|
"type": "list"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
24
logging_config.py
Normal file
24
logging_config.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
def setup_logging():
|
||||||
|
log_dir = "logs"
|
||||||
|
os.makedirs(log_dir, exist_ok=True)
|
||||||
|
log_file = os.path.join(log_dir, "cat.log")
|
||||||
|
|
||||||
|
log_format = "[%(asctime)s] [%(levelname)s] [%(module)s:%(lineno)d] %(message)s"
|
||||||
|
date_format = "%Y-%m-%d %H:%M:%S"
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
console_handler = logging.StreamHandler()
|
||||||
|
console_handler.setLevel(logging.DEBUG)
|
||||||
|
console_handler.setFormatter(logging.Formatter(log_format, date_format))
|
||||||
|
|
||||||
|
file_handler = logging.FileHandler(log_file, encoding="utf-8")
|
||||||
|
file_handler.setLevel(logging.DEBUG)
|
||||||
|
file_handler.setFormatter(logging.Formatter(log_format, date_format))
|
||||||
|
|
||||||
|
logger.addHandler(console_handler)
|
||||||
|
logger.addHandler(file_handler)
|
||||||
12
logs/cat.log
Normal file
12
logs/cat.log
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[2025-07-31 15:50:20] [ERROR] [main:381] Error processing ./output/2507_CAT_3_A/2507회코딩활용능력3급A형정답\project.json: cannot access local variable 'student_id' where it is not associated with a value
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "D:\project\Entry\Entry-Scoring\main.py", line 375, in main
|
||||||
|
points.insert(0, student_id)
|
||||||
|
^^^^^^^^^^
|
||||||
|
UnboundLocalError: cannot access local variable 'student_id' where it is not associated with a value
|
||||||
|
[2025-07-31 15:52:50] [ERROR] [main:380] 🚫Error processing ./output/2507_CAT_3_A/2507회코딩활용능력3급A형정답\project.json: cannot access local variable 'student_id' where it is not associated with a value
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "D:\project\Entry\Entry-Scoring\main.py", line 375, in main
|
||||||
|
points.insert(0, student_id)
|
||||||
|
^^^^^^^^^^
|
||||||
|
UnboundLocalError: cannot access local variable 'student_id' where it is not associated with a value
|
||||||
37
main.py
37
main.py
@@ -6,6 +6,11 @@ import pandas as pd # 추가된 import
|
|||||||
import unicodedata # 상단에 import 추가
|
import unicodedata # 상단에 import 추가
|
||||||
import re # 상단에 추가
|
import re # 상단에 추가
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
from logging_config import setup_logging # logging 설정을 위한 import
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
setup_logging() # logging 설정 호출
|
||||||
|
|
||||||
# JSON 파일 읽기
|
# JSON 파일 읽기
|
||||||
def read_json(file_path):
|
def read_json(file_path):
|
||||||
@@ -262,14 +267,11 @@ def process_project(project_data, scoring_data):
|
|||||||
script_data_1 = json.loads(script_raw) if script_raw else None
|
script_data_1 = json.loads(script_raw) if script_raw else None
|
||||||
script_data = swap_script(script_data_1) if script_data_1 else None
|
script_data = swap_script(script_data_1) if script_data_1 else None
|
||||||
|
|
||||||
if script_data != script_data_1:
|
|
||||||
print(f"⬜ Script data 순서 변경 ")
|
|
||||||
|
|
||||||
block_index = 1
|
block_index = 1
|
||||||
for block in block_list:
|
for block in block_list:
|
||||||
block_type = block.get('type')
|
block_type = block.get('type')
|
||||||
block_path = block.get('ele')
|
block_path = block.get('ele')
|
||||||
block_expected_answer = block.get('answer', None)
|
block_answer = block.get('answer', None)
|
||||||
block_points = block.get('points')
|
block_points = block.get('points')
|
||||||
|
|
||||||
if script_data is None:
|
if script_data is None:
|
||||||
@@ -285,23 +287,23 @@ def process_project(project_data, scoring_data):
|
|||||||
block_elements = find_element(script_data, block_path)
|
block_elements = find_element(script_data, block_path)
|
||||||
|
|
||||||
# 결과값 정리
|
# 결과값 정리
|
||||||
if block_elements and isinstance(block_expected_answer, list):
|
if block_elements and isinstance(block_answer, list):
|
||||||
found_values = [convert_to_str(x) for x in chain.from_iterable(block_elements)]
|
found_values = [convert_to_str(x) for x in chain.from_iterable(block_elements)]
|
||||||
else:
|
else:
|
||||||
found_values = convert_to_str(block_elements[0]) if block_elements else None
|
found_values = convert_to_str(block_elements[0]) if block_elements else None
|
||||||
|
|
||||||
expected_str = convert_to_str(block_expected_answer) if block_expected_answer is not None else None
|
expected_str = convert_to_str(block_answer) if block_answer is not None else None
|
||||||
|
|
||||||
# 비교 및 점수 처리
|
# 비교 및 점수 처리
|
||||||
if block_elements:
|
if block_elements:
|
||||||
if block_expected_answer is not None and expected_str != found_values:
|
if block_answer is not None and expected_str != found_values:
|
||||||
print(f"{question_key}-{block_index}: ❌ {expected_str} != {found_values}")
|
print(f"{question_key}-{block_index}: ❌ {expected_str} != {found_values}")
|
||||||
score_list.append(0)
|
score_list.append(0)
|
||||||
elif block_expected_answer is not None and expected_str == found_values:
|
elif block_answer is not None and expected_str == found_values:
|
||||||
print(f"{question_key}-{block_index}: ✅ {expected_str} == {found_values}")
|
print(f"{question_key}-{block_index}: ✅ {expected_str} == {found_values}")
|
||||||
total_points += block_points
|
total_points += block_points
|
||||||
score_list.append(block_points)
|
score_list.append(block_points)
|
||||||
elif block_expected_answer is None:
|
elif block_answer is None:
|
||||||
total_points += block_points
|
total_points += block_points
|
||||||
score_list.append(block_points)
|
score_list.append(block_points)
|
||||||
print(f"{question_key}-{block_index}: Element Exists")
|
print(f"{question_key}-{block_index}: Element Exists")
|
||||||
@@ -311,6 +313,7 @@ def process_project(project_data, scoring_data):
|
|||||||
|
|
||||||
block_index += 1
|
block_index += 1
|
||||||
|
|
||||||
|
# total_points = round(total_points, ndigits=0) # 총점 반올림
|
||||||
score_list.append(total_points)
|
score_list.append(total_points)
|
||||||
return score_list
|
return score_list
|
||||||
|
|
||||||
@@ -321,9 +324,9 @@ def normalize_path(path):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
# 파일 경로 설정
|
# 파일 경로 설정
|
||||||
# project_json_path = './output/2506_CAS_2_A/'
|
project_json_path = './output/2507_CAT_3_A/'
|
||||||
project_json_path = './output/00_test/'
|
# project_json_path = './output/00_test/'
|
||||||
scoring_json_path = './correct/2506_CAS_2_A.json'
|
scoring_json_path = './correct/2507_CAT_3_A.json'
|
||||||
|
|
||||||
scoring_data = read_json(scoring_json_path)
|
scoring_data = read_json(scoring_json_path)
|
||||||
student_score_list = []
|
student_score_list = []
|
||||||
@@ -363,9 +366,14 @@ def main():
|
|||||||
# 디렉토리 패스 내에 학생 이름만 뽑아서 엑셀 컬럼 명으로 추가
|
# 디렉토리 패스 내에 학생 이름만 뽑아서 엑셀 컬럼 명으로 추가
|
||||||
# output/cas-000040-이지원/temp/project.json
|
# output/cas-000040-이지원/temp/project.json
|
||||||
# student_id = normalize_path(full_path.split('/')[3])
|
# student_id = normalize_path(full_path.split('/')[3])
|
||||||
match = re.search(r'(\d{6}-[^\\/]+)[\\/]', full_path)
|
match = re.search(r'(\d{6}[-_][^\\/]+)[\\/]', full_path)
|
||||||
if match:
|
if match:
|
||||||
student_id = match.group(1)
|
student_id = match.group(1)
|
||||||
|
else:
|
||||||
|
if '정답' in full_path:
|
||||||
|
student_id = '정답'
|
||||||
|
else:
|
||||||
|
student_id = '000000'
|
||||||
|
|
||||||
# project.json 파일 내용
|
# project.json 파일 내용
|
||||||
project_data = read_json(full_path)
|
project_data = read_json(full_path)
|
||||||
@@ -374,7 +382,8 @@ def main():
|
|||||||
student_score_list.append(points)
|
student_score_list.append(points)
|
||||||
print(f"Total Points for {points}")
|
print(f"Total Points for {points}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error processing {full_path}: {str(e)}")
|
# print(traceback.format_exc())
|
||||||
|
logging.exception(f"🚫Error processing {full_path}: {str(e)}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# DataFrame 생성 및 엑셀 저장
|
# DataFrame 생성 및 엑셀 저장
|
||||||
|
|||||||
BIN
시험자료/2507/2507회 코딩활용능력 3급 A형 문제.pdf
Normal file
BIN
시험자료/2507/2507회 코딩활용능력 3급 A형 문제.pdf
Normal file
Binary file not shown.
BIN
시험자료/2507/2507회 코딩활용능력 3급 A형 정답.ent
Normal file
BIN
시험자료/2507/2507회 코딩활용능력 3급 A형 정답.ent
Normal file
Binary file not shown.
BIN
시험자료/2507/2507회 코딩활용능력 3급 A형 채점기준표.xlsx
Normal file
BIN
시험자료/2507/2507회 코딩활용능력 3급 A형 채점기준표.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user