0

Codeacademyで基本的なバイオインフォマティクスコースを作成したいと思っています。コースを作成するための優れたインターフェイスがありますが、保存してからプレビューしてから実行する必要があるため、テストには少し時間がかかります。

だから私は彼らの環境を模倣した小さなテスト環境を書きたいと思っています。ユーザー入力コードが文字列として関数に読み込まれstr、コード内のすべてのインスタンスが変換されunicode(これには正規表現を使用しました)、コードがで実行されるように見えますexec

トリッキーな部分は、提出テストを組み込みたい場合のようです。

送信テストは、、、またはを返す必要がTrueありFalsestr関数の本体として記述されます。したがって、たとえば:

私がやろうとしていることの簡略版:

# The submission test must be a function.
def test_code(code, CC, error):
    # Use information from errors in student code
    if error:
        return "Yada yada %s" %error

    # Use information in the raw student code
    if len(code.split("\n")) is not 2:
        return "This should be accomplished in 2 lines"

    # Have direct access to variables from the student code
    # I'd like to avoid params['y'] if possible.
    try:
        y
    except NameError:
        return "Please use the variable y"

    if y is not 8:
        return "Wrong! Check stuff"

    # Use information from print output
    if str(y) not in CC:
        return "Remember to print your variable!"

    return True

# Read in student code
student_code = """y = 8
                  print y
                  potato"""

# Catch print output
CC = StringIO.StringIO()
sys.stdout = CC

# Execute student code and catch errors
try:
    exec student_code
except Exception as e:
    error = e

# Start outputting to the terminal again
sys.stdout = sys.__stdout__

# Run the submission test
submission_test = test_code(student_code, CC.split("\n"), error)

# Output the result of the submission test
if submission_test is True:
    print("Well done!")
elif submission_test is False:
    print("Oops! You failed... Try again!")
else:
    print(submission_test)

ただし、変数を取得して送信テスト関数(この場合)exec codeに渡すことができないようです。test_code

提出テストでコードを実行することもできますが、可能であればそれを避けたいと思います。そうしないと、各テストにコードを追加する必要があります。

どんな助けでも大歓迎です:)

4

3 に答える 3

2

の場合exec mystr in somedict、Python コードとしてsomedictの実行中に割り当てられたすべての変数への参照があります。mystrさらに、この方法で変数を渡すこともできます。

>>> d = {'y': 3}
>>> exec "x = y" in d
>>> d['x']
3

ユーザーコードを実行して取得した辞書を渡す必要があります。これにより、送信チェックコードがその値が適切であることを確認できます。

于 2013-02-24T13:28:58.023 に答える
1

codetestを同じ環境で実行したいようです。両方とも文字列として送信されるため、おそらく最も簡単な方法は、両方を連結execし、結合された文字列に対して実行することです。

from __future__ import unicode_literals

def wrap_body(body):
    indent = ' '*4
    return 'def test():\n' + indent + body.replace('\n','\n'+indent)    

code = '''
bool_1 = True
bool_2 = False

str_1 = 'Hello there!'
str_2 = "I hope you've noticed the apostrophe ;)"
'''

code_test = '''
try:
    bool_1, bool_2, str_1, str_2
except NameError:
    return "Please do not alter the variable names!"

if (bool_1 == bool_2 or str_1 == str_2):
    return "Please ensure that all of your variables are different " \
           "from one another"

if type(bool_1) != bool: return "bool_1 is incorrect"
if type(bool_2) != bool: return "bool_2 is incorrect"
if type(str_1) != unicode: return "str_1 is incorrect"
if type(str_2) != unicode: return "str_2 is incorrect"

return True
'''
code_test = wrap_body(code_test)
template = code + code_test
namespace = {}
try:
    exec template in namespace
    print(namespace['test']())
except Exception as err:
    print(err)
于 2013-02-24T14:45:04.853 に答える
0
于 2013-02-25T04:50:11.670 に答える