case1. 入出力ベースの採点

基本的なファイル構造の設定で、以下のフォルダとファイルを追加します。

  • inputフォルダ / outputフォルダ:採点用のテストケースを定義します。

  • testcases.pyファイル:各テストケースごとの部分点と正解・不正解メッセージを設定します。

1. 入力・出力の採点のためのテストケース作成

採点に使用する入力・出力値を保存するためのファイルを作成し、各テストケースを作成します。

  • inputフォルダ

    • テストケースごとの入力値をtxtファイルとして保存します。

    • 各ケースごとに1つの入力値を保存します。

  • outputフォルダ

    • テストケースごとの出力値をtxtファイルとして保存します。

    • inputフォルダ内で作成した各入力値に対応する出力値を保存します。

2. 採点メッセージの作成

テストケースで設定した各項目ごとの正解・不正解メッセージを定義します。 また、各テストケースごとの部分点を設定します。

# テストケースごとの正解メッセージ
correct_messages = [
        "テストケース 1. 正解です!",
"テストケース 2. 正解です!"
]

# テストケースごとの不正解メッセージ

wrong_message = [
"テストケース 1. 不正解です!",
"テストケース 2. 不正解です!"
]

# テストケースごとの部分点

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