CES Help Information

ホームページ: https://www.ces-alpha.org/hp/information/           

コードの自動採点では、教員側が用意した解答例と学生の提出したコードを実行し、それぞれで生成された変数を比較して正誤判定を行っています。

 

Python 言語での変数の比較には、以下のアルゴリズムが使用されています。

特に、浮動小数点数の比較においては、擬似コードに使用される誤差の許容範囲 Error_Tolerance_デフォルト値は 1E-8 です。

 

教員は、各コード採点演習問題の設定において、以下の Python コードを解答例の先頭に記述することで、その演習問題における採点時の許容範囲をカスタマイズできます。。

GRADE_ERR_TOL  = 1E-8    # No indent 

 

採点時、教員側で採点用の比較関数をカスタマイズすることが可能です。たとえば、sklearn パッケージで定義されたモデルの比較のために、以下のような独自のモデル比較関数を定義できます。

注意:カスタマイズ関数の名前は必ず GRADE_COMPARE にしてください。

(※ 採点関数のカスタマイズ機能は、2025年6月25日より有効です。)

#カスタマイズした採点用の比較関数
def GRADE_COMPARE(model1, model2):
    """
    モデル model1 と model2 のパラメータを再帰的に比較する。内容がすべて一致していれば True、そうでなければ False を返す。
    """
    def get_all_params(est):
        params = est.get_params(deep=False).copy()
        for key, val in params.items():
            if hasattr(val, "get_params"):
                # 再帰的にネストされた estimator のパラメータを取得
                params[key] = get_all_params(val)
        return params
    return get_all_params(model1) == get_all_params(model2)

 

自動採点のアルゴリズム

注意:以下の擬似コードの説明では、教員側の解答例によって生成された変数を answer_、学生側の解答によって生成された変数を my_answer_ と表記します。

def compare(answer_ , my_answer_):
    #Customized compare function 
    if GRADE_COMPARE(answer_, my_answer) == True:
        return True

    # Try direct equality (including bool, int, str, etc.)
    try:
        if answer_ == my_answer_:
            return True
    except Exception:
        pass
     # Type-aware fallback
    try:
        # NumPy arrays
        import numpy as np
        if isinstance(answer_, np.ndarray):
            if np.array_equal(answer_, my_answer_):
                return True
            if np.allclose(answer_, my_answer_, atol=Error_Tolerance_):
                return True
         # Floats
        elif isinstance(answer_, float):
            if abs(answer_ - my_answer_) <= Error_Tolerance_:
                return True
         # Lists
        elif isinstance(answer_, list) or isinstance(answer_, tuple):
            if len(answer_) != len(my_answer_):
                raise ValueError("List lengths differ")
            all_good = True
            for a, b in zip(answer_, my_answer_):
                if isinstance(a, float):
                    if abs(a - b) > Error_Tolerance_:
                        all_good = False
                        break
                elif a != b:
                    all_good = False
                    break
            if all_good:
                return True
         # Dicts
        elif isinstance(answer_, dict) and isinstance(my_answer_, dict):
            if answer_.keys() != my_answer_.keys():
                raise ValueError("Dict keys differ")
            all_good = True
            for k in answer_:
                a, b = answer_[k], my_answer_[k]
                if isinstance(a, float):
                    if abs(a - b) > Error_Tolerance_:
                        all_good = False
                        break
                elif a != b:
                    all_good = False
                    break
            if all_good:
                return True
    except Exception:
        pass
        
    return False