2508회 채점자료 업데이트
This commit is contained in:
256
main.py
256
main.py
@@ -10,6 +10,8 @@ import logging
|
||||
from logging_config import setup_logging # logging 설정을 위한 import
|
||||
import traceback
|
||||
|
||||
from script_utils import extract_and_format_scripts # 스크립트 추출 함수 import
|
||||
|
||||
setup_logging() # logging 설정 호출
|
||||
|
||||
# JSON 파일 읽기
|
||||
@@ -90,7 +92,7 @@ def swap_script(origin):
|
||||
elif block_type == "when_some_key_pressed":
|
||||
# params[1]에서 키 값 확인 (49, 50, 51) 아스키코드 값이므로 필요하면 추가 가능
|
||||
key_value = block[0].get("params")[1]
|
||||
if key_value in ["49", "50", "51"]:
|
||||
if key_value in ["32","49","50","51"]:
|
||||
key_press_blocks.append((key_value, block))
|
||||
elif block_type == "when_clone_start":
|
||||
clone_start_block = block
|
||||
@@ -135,100 +137,6 @@ def convert_to_str(value):
|
||||
return [convert_to_str(v) for v in value]
|
||||
return str(value)
|
||||
|
||||
# def process_project(project_data, scoring_data):
|
||||
total_points = 0
|
||||
point_list = []
|
||||
|
||||
for key, question_info in scoring_data.items():
|
||||
element_path = question_info.get('ele')
|
||||
type = question_info.get('type')
|
||||
block_list = question_info.get('blocks')
|
||||
answer = question_info.get('answer')
|
||||
points = question_info.get('points')
|
||||
|
||||
print(f"example: {key}")
|
||||
if type == "scene":
|
||||
found_elements = find_element(project_data, element_path)
|
||||
if found_elements:
|
||||
print(f"🟨 Elements found for {element_path}")
|
||||
# scene type의 경우 문자열 변환
|
||||
found_elements = [convert_to_str(x) for x in found_elements]
|
||||
if found_elements == answer:
|
||||
total_points += points
|
||||
point_list.append(points)
|
||||
|
||||
elif found_elements and answer == None:
|
||||
total_points += points
|
||||
point_list.append(points)
|
||||
print(f"{element_path} found ")
|
||||
else:
|
||||
point_list.append(0)
|
||||
print(f"{found_elements} not found")
|
||||
else:
|
||||
print(f"🟥 Element '{element_path}' not found")
|
||||
point_list.append(0)
|
||||
|
||||
# 스크립트 타입의 경우
|
||||
# 스크립트 블록을 찾고, 블록 내의 요소를 확인
|
||||
# 블록 내의 요소를 확인하고, 정답과 비교하여 점수 계산
|
||||
if type == "script":
|
||||
script_raw = find_script_element(project_data, element_path)
|
||||
|
||||
if script_raw == None:
|
||||
script_data = None
|
||||
else:
|
||||
script_data = json.loads(script_raw)
|
||||
script_data = swap_script(script_data)
|
||||
|
||||
block_index = 1
|
||||
for block in block_list:
|
||||
block_type = block.get('type')
|
||||
|
||||
if script_data == None:
|
||||
print(f"{key}-{block_index}: Script Not exist")
|
||||
point_list.append("확인 필요")
|
||||
continue
|
||||
|
||||
elif block_type == "list":
|
||||
block_elements = find_list_element(script_data, block.get('ele'))
|
||||
else:
|
||||
block_elements = find_element(script_data, block.get('ele'))
|
||||
|
||||
answer = block.get('answer', None)
|
||||
|
||||
if block_elements and isinstance(answer, list):
|
||||
# 리스트의 모든 요소를 문자열로 변환
|
||||
flat_matches = [convert_to_str(x) for x in list(chain.from_iterable(block_elements))]
|
||||
else:
|
||||
if not block_elements:
|
||||
flat_matches = None
|
||||
else:
|
||||
# 단일 값을 문자열로 변환
|
||||
flat_matches = convert_to_str(block_elements[0])
|
||||
|
||||
if block_elements:
|
||||
# answer도 문자열로 변환하여 비교
|
||||
str_answer = convert_to_str(answer) if answer is not None else None
|
||||
if answer is not None and str_answer != flat_matches:
|
||||
print(f"{key}-{block_index}: {str_answer} != {flat_matches}")
|
||||
point_list.append(0)
|
||||
elif answer is not None and str_answer == flat_matches:
|
||||
print(f"{key}-{block_index}: {str_answer} == {flat_matches}")
|
||||
total_points += block.get('points')
|
||||
point_list.append(block.get('points'))
|
||||
elif answer is None and block_elements:
|
||||
total_points += block.get('points')
|
||||
point_list.append(block.get('points'))
|
||||
print(f"{key}-{block_index}: exist ele: {block_elements}")
|
||||
else:
|
||||
print(f"No elements found for {block.get('ele')}")
|
||||
point_list.append(0)
|
||||
|
||||
block_index = block_index + 1
|
||||
|
||||
point_list.append(total_points)
|
||||
return point_list
|
||||
|
||||
def process_project(project_data, scoring_data):
|
||||
total_points = 0
|
||||
score_list = []
|
||||
@@ -264,8 +172,8 @@ def process_project(project_data, scoring_data):
|
||||
# ✅ SCRIPT TYPE 처리
|
||||
elif question_type == "script":
|
||||
script_raw = find_script_element(project_data, element_path)
|
||||
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_json = json.loads(script_raw) if script_raw else None
|
||||
script_data = swap_script(script_json) if script_json else None
|
||||
|
||||
block_index = 1
|
||||
for block in block_list:
|
||||
@@ -321,82 +229,88 @@ def normalize_path(path):
|
||||
"""한글 경로명을 NFC 방식으로 정규화"""
|
||||
|
||||
return unicodedata.normalize('NFC', path)
|
||||
|
||||
|
||||
def main():
|
||||
# 파일 경로 설정
|
||||
project_json_path = './output/2507_CAT_3_A/'
|
||||
# project_json_path = './output/00_test/'
|
||||
scoring_json_path = './correct/2507_CAT_3_A.json'
|
||||
|
||||
scoring_data = read_json(scoring_json_path)
|
||||
student_score_list = []
|
||||
|
||||
# 컬럼명 생성
|
||||
columns = ['학생명']
|
||||
idx = 1
|
||||
for key in scoring_data.keys():
|
||||
if scoring_data[key].get('type') == 'scene':
|
||||
columns.append(f'{idx}')
|
||||
idx = idx + 1
|
||||
elif scoring_data[key].get('type') == 'script':
|
||||
for i in range(len(scoring_data[key].get('blocks', []))):
|
||||
columns.append(f'{idx}')
|
||||
idx = idx + 1
|
||||
|
||||
columns.append('총점')
|
||||
|
||||
# os.walk 결과를 리스트로 변환하고 정렬
|
||||
walk_results = []
|
||||
for root, dirs, files in os.walk(project_json_path):
|
||||
# 디렉토리명 정규화
|
||||
normalized_root = normalize_path(root)
|
||||
normalized_dirs = [normalize_path(d) for d in dirs]
|
||||
normalized_files = [normalize_path(f) for f in files]
|
||||
|
||||
normalized_dirs.sort() # 정규화된 디렉토리 정렬
|
||||
walk_results.append((normalized_root, normalized_dirs, normalized_files))
|
||||
|
||||
# 정렬된 결과를 바탕으로 처리
|
||||
for root, dirs, files in sorted(walk_results):
|
||||
for file in sorted(files): # 파일도 정렬
|
||||
if file == 'project.json':
|
||||
full_path = os.path.join(root, file)
|
||||
print(f"\nProcessing: {full_path}")
|
||||
try:
|
||||
# 디렉토리 패스 내에 학생 이름만 뽑아서 엑셀 컬럼 명으로 추가
|
||||
# output/cas-000040-이지원/temp/project.json
|
||||
# student_id = normalize_path(full_path.split('/')[3])
|
||||
match = re.search(r'(\d{6}[-_][^\\/]+)[\\/]', full_path)
|
||||
if match:
|
||||
student_id = match.group(1)
|
||||
else:
|
||||
if '정답' in full_path:
|
||||
student_id = '정답'
|
||||
else:
|
||||
student_id = '000000'
|
||||
|
||||
# project.json 파일 내용
|
||||
project_data = read_json(full_path)
|
||||
points = process_project(project_data, scoring_data)
|
||||
points.insert(0, student_id)
|
||||
student_score_list.append(points)
|
||||
print(f"Total Points for {points}")
|
||||
except Exception as e:
|
||||
# print(traceback.format_exc())
|
||||
logging.exception(f"🚫Error processing {full_path}: {str(e)}")
|
||||
continue
|
||||
|
||||
# DataFrame 생성 및 엑셀 저장
|
||||
df = pd.DataFrame(student_score_list, columns=columns).transpose()
|
||||
df.columns = df.iloc[0]
|
||||
df = df[1:]
|
||||
|
||||
timestamp = datetime.now().strftime("%y%m%d")
|
||||
test_mode = False # 테스트 모드 설정
|
||||
# test_mode = True # 테스트 모드 설정
|
||||
exam_round = "2508"
|
||||
exam_names = ["CAS_2_A", "CAS_2_B"] # 여러 시험명을 리스트로 설정
|
||||
excel_list = []
|
||||
|
||||
excel_path = f'{project_json_path}/{timestamp}_results.xlsx'
|
||||
|
||||
df.to_excel(excel_path, index=False)
|
||||
print(f"\nResults saved to {excel_path}")
|
||||
|
||||
for exam_name in exam_names:
|
||||
scoring_json_path = f'./correct/{exam_round}_{exam_name}.json'
|
||||
project_json_path = f'./output/{"00_test" if test_mode else exam_round+"_"+exam_name}/'
|
||||
excel_path = f'{timestamp}_{exam_round}_{exam_name}_{"TEST" if test_mode else "채점결과"}.xlsx'
|
||||
|
||||
scoring_data = read_json(scoring_json_path)
|
||||
student_score_list = []
|
||||
|
||||
# 컬럼명 생성
|
||||
columns = ['학생명']
|
||||
idx = 1
|
||||
for key in scoring_data.keys():
|
||||
if scoring_data[key].get('type') == 'scene':
|
||||
columns.append(f'{idx}')
|
||||
idx = idx + 1
|
||||
elif scoring_data[key].get('type') == 'script':
|
||||
for i in range(len(scoring_data[key].get('blocks', []))):
|
||||
columns.append(f'{idx}')
|
||||
idx = idx + 1
|
||||
|
||||
columns.append('총점')
|
||||
|
||||
# os.walk 결과를 리스트로 변환하고 정렬
|
||||
walk_results = []
|
||||
for root, dirs, files in os.walk(project_json_path):
|
||||
# 디렉토리명 정규화
|
||||
normalized_root = normalize_path(root)
|
||||
normalized_dirs = [normalize_path(d) for d in dirs]
|
||||
normalized_files = [normalize_path(f) for f in files]
|
||||
|
||||
normalized_dirs.sort() # 정규화된 디렉토리 정렬
|
||||
walk_results.append((normalized_root, normalized_dirs, normalized_files))
|
||||
|
||||
# 정렬된 결과를 바탕으로 처리
|
||||
for root, dirs, files in sorted(walk_results):
|
||||
for file in sorted(files): # 파일도 정렬
|
||||
if file == 'project.json':
|
||||
full_path = os.path.join(root, file)
|
||||
print(f"\nProcessing: {full_path}")
|
||||
try:
|
||||
# 디렉토리 패스 내에 학생 이름만 뽑아서 엑셀 컬럼 명으로 추가
|
||||
match = re.search(r'(\d{6}[-_][^\\/]+)[\\/]', full_path)
|
||||
if match:
|
||||
student_id = match.group(1)
|
||||
else:
|
||||
if '정답' in full_path:
|
||||
student_id = '정답'
|
||||
else:
|
||||
student_id = '000000'
|
||||
|
||||
# project.json 파일 내용
|
||||
project_data = read_json(full_path)
|
||||
if project_data:
|
||||
extract_and_format_scripts(project_data, root)
|
||||
points = process_project(project_data, scoring_data)
|
||||
points.insert(0, student_id)
|
||||
student_score_list.append(points)
|
||||
print(f"Total Points for {points}")
|
||||
except Exception as e:
|
||||
logging.exception(f"🚫Error processing {full_path}: {str(e)}")
|
||||
continue
|
||||
|
||||
# DataFrame 생성 및 엑셀 저장
|
||||
df = pd.DataFrame(student_score_list, columns=columns).transpose()
|
||||
df.columns = df.iloc[0]
|
||||
df = df[1:]
|
||||
|
||||
df.to_excel(excel_path, index=False)
|
||||
|
||||
excel_list.append(excel_path)
|
||||
|
||||
if excel_list:
|
||||
print(f"\nResults saved to {excel_list}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user