コメントだらけ

激しく抽象化したらあんまりコメントを書かない僕としては驚きのレベルのコメント比率のコードが出来上がった。

追記: レベルがHARDでrendererがシャッフルされたとき、?の位置がcodomではない可能性があるのでbogusの生成方法が間違っているなぁ。

    # 単項演算のジェネレータopgenをチョイスする
    opgen = choice(opgens)
    # opgenを引数にして演算の定義域domをチョイスする
    dom = opgen.get_domain()
    # 単項演算の定義域domから単項演算の引数argを3つ作る
    args = [dom.get_instance() for i in range(3)]

    # opgenとdomを引数にしてopgenのパラメータの定義域param_domを作る
    param_dom = opgen.get_param_dom(dom)
    # param_domから単項演算のパラメータparamを3つ作る、
    params = [param_dom.get_instance() for i in range(3)]
    # 単項演算ジェネレータopgenにparamを渡して具体的な単項演算opを3つ作る
    ops = [opgen.get_instance(p) for p in params]
    # 各々の単項演算opに各々の引数argを渡して演算結果resultを作る
    results = [op(arg) for (op, arg) in zip(ops, args)]
    correct_answer = results[2]

    # opgenと引数の定義域domから結果の定義域codomを作る(偽回答作成のため)
    codom = opgen.get_codom(dom)
    # 偽回答bogusを5つ作る
    bogus = []
    while len(bogus) < 5:
        v = codom.get_instance()
        if v != correct_answer:
            bogus.append(v)

    # opgenにdom, param_dom, codomを与えてそれぞれのrendererを作る
    dom_ren, pdom_ren, codom_ren = opgen.get_renderer(dom, param_dom, codom)
    renderers = [lambda cont, i: dom_ren(cont, args[i]),
                 lambda cont, i: pdom_ren(cont, params[i]),
                 lambda cont, i: codom_ren(cont, results[i])]
    if HARD: renderers = shuffled(renderers)

そしてこの範囲のデバッグ中に出したエラーの個数を考えると、1行に1個バグがあったことになる(ぉ

わーい、ちゃんと動いたー

この例ではまだ t -> t -> t な関数なんでここまで抽象化したメリットが生きてないけど、t1 -> t2 -> t3 をできるように枠組みを作ったので今後の具体的な実装が楽しみである。