case1. 입.출력 기반 채점

기본 세팅된 파일 구조에서 아래 폴더&파일을 추가합니다.

  • input 폴더 / output 폴더 : 채점을 위한 테스트케이스를 정의합니다.

  • testcases.py 파일 : 각 테스트케이스 별 부분점수 및 정.오답 메시지를 설정합니다.

1. 입.출력 채점을 위한 테스트케이스 작성

채점을 위한 입.출력값을 저장하기 위한 파일을 생성한 후, 각 테스트케이스를 작성합니다.

  • input 폴더

    • 테스트케이스 별 입력값을 txt파일로 저장합니다.

    • 각 케이스 별로 1개의 입력값을 저장합니다.

  • output 폴더

    • 테스트케이스 별 출력값을 txt파일로 저장합니다.

    • input 폴더 내에 작성한 각 입력값에 대응하는 출력값을 저장합니다.

2. 채점 메시지 작성

테스트케이스에서 설정한 각 항목 별 정.오답 메시지를 정의합니다. 또한, 각 테스트케이스 별 부분점수를 설정합니다.

# testcase 별 정답 메시지
correct_messages = [
        "testcase 1. 정답입니다!",
        "testcase 2. 정답입니다!"
    ]

# testcase 별 오답 메시지
wrong_message = [
        "testcase 1. 오답입니다!",
        "testcase 2. 오답입니다!"
     ]

# testcase 별 부분점수
scores = [50, 50]

3. grader.py 채점코드 작성

테스트케이스의 갯수만큼 학생의 코드를 실행하여, 학생이 작성한 코드의 출력 결과를 확인합니다. 이후, 예측한 정답 출력값 (output 파일)과 동일한지를 비교하여 실습의 정.오답을 판단합니다.

각 테스트케이스 별로 부분점수를 제공할 수 있으며, 최종 채점 결과는 elice_utils.secure_send_score(total_score)를 통해 플랫폼(LXP) 내에 전송합니다.

예시 코드는 다음과 같습니다.

import os
import subprocess
import sys
from testcases import *
sys.path.append(os.getcwd())
from grader_elice_utils import EliceUtils  # isort:skip

elice_utils = EliceUtils()
elice_utils.secure_init()

SUM_TESTCASE_SCORES = 100
INPUT_DIR = '.elice/input/'
OUTPUT_DIR = '.elice/output/'

try:
    total_score = 0

    # 0. input, output 파일 불러오기
    input_data = [x for x in os.listdir(INPUT_DIR) if x.endswith('.txt')]
    output_data = [x for x in os.listdir(OUTPUT_DIR) if x.endswith('.txt')]
    
    # 1. 테스트케이스 갯수 확인하기
    if len(input_data) != len(output_data):
        sys.exit(1)
    NUM_TESTCASES = len(input_data)
    
    # 2. 파일명 확인하기
    matching = True
    for i in range(1, NUM_TESTCASES + 1):
        input_file = '%d.txt' % i
        output_file = '%d.txt' % i

        if input_file not in input_data:
            matching = False
        if output_file not in output_data:
            matching = False
    if not matching:
        sys.exit(1)
    
    # 3. 테스트케이스 별 채점 진행
    for i in range(0, NUM_TESTCASES):
        testcase_score = scores[i]
        input_file = '%d.txt' % (i+1)
        
        input_text = subprocess.run(['cat', '%s%s' % (INPUT_DIR, input_file)],
                                    stdout=subprocess.PIPE).stdout
        result = subprocess.run(['/bin/bash', '.elice/runner.sh'],
                                input=input_text,
                                stdout=subprocess.PIPE)
        student_result = result.stdout.decode('utf-8')
        
        answer = ''.join(open('%s%s' % (OUTPUT_DIR, input_file)).readlines())

        student_result = student_result.strip()
        answer = answer.strip()
        
        # 테스트케이스 별 정.오답 판단
        if answer == student_result:
            total_score += testcase_score # 테스트케이스 부분점수 추가
            elice_utils.secure_send_grader('✅ {} \n'.format(correct_messages[i]))
            
        else:
            elice_utils.secure_send_grader('❌ {} \n'.format(wrong_message[i]))
            
    # 5. 실습 최종 점수 계산
    total_score = int(total_score)
    elice_utils.secure_send_score(total_score)
    
except Exception as err:
    elice_utils.secure_send_grader('채점 도중 오류가 발생했어요. 코드가 정상적으로 실행되는지 확인해보세요.\n')
    elice_utils.secure_send_score(0)
    sys.exit(1)

Last updated