@user2357112的注释正确地描述了它无法工作的原因.当您的管道将第一个脚本的输出发送到评分器时,您没有向第一个脚本发送‘grader.py’的响应.
因此,我们需要做的是建立一种双向沟通.
这里有一个方法可以做到这一点.在评分器中,将您要测试的脚本命名为subprocess
,并通过管道与其通信.
我在代码中添加了额外的解释.
1_Guess_the_Number.py
和你的一样:
#!/usr/bin/env python3
l, r = 1, 1000000
while l != r:
mid = (l + r + 1) // 2
print(mid, flush=True)
response = input()
if response == "<":
r = mid - 1
else:
l = mid
print("!", l)
grader.py
接受测试文件的名称作为输入,并使用subprocess.Popen
执行它:
# !/usr/bin/env python3
import sys
import subprocess
INP = 12
def interactor(n):
if n > INP:
return "<"
return ">="
def decodeBytes(message):
# Helperfunction to decode the message from stdin
# guess has the format b'12345\r\n'
# rstrip() removes the \r\n, then we decode it as ascii
return message.rstrip().decode('ascii')
if __name__ == '__main__':
print(f'The secret answer is: {INP}')
# get script name:
name = sys.argv[1]
print(f'calling script {name}')
# start script as a subprocess
p = subprocess.Popen(["python3", name], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
# create iterator to read subsequent guesses
stdout_iterator = iter(p.stdout.readline, b"")
# loop over all guesses
for msg_in in stdout_iterator:
#msg_in is a byte array, we need to decode it
guess = decodeBytes(msg_in)
print(f'got msg: {guess}')
if guess.startswith("!"):
final_answer = int(guess.split()[1])
print(f'The final answer is: {final_answer}')
if final_answer == INP:
print('Answer was correct!')
break
print('Answer is wrong!')
break
# we determine the message to send out
msg_out = interactor(int(guess))
print(f'send msg: {msg_out}')
# sending it to the scripts stdin.
p.stdin.write((msg_out + '\n').encode())
# we need to flush stdin, to make sure the message is not stuck in a buffer
p.stdin.flush()
在命令行中,您可以通过以下方式调用评分器
python grader.py 1_Guess_the_Number.py
打印输出为:
The secret answer is: 12
calling script 1_Guess_the_Number.py
got msg: 500001
send msg: <
got msg: 250001
send msg: <
got msg: 125001
send msg: <
got msg: 62501
send msg: <
got msg: 31251
send msg: <
got msg: 15626
send msg: <
got msg: 7813
send msg: <
got msg: 3907
send msg: <
got msg: 1954
send msg: <
got msg: 977
send msg: <
got msg: 489
send msg: <
got msg: 245
send msg: <
got msg: 123
send msg: <
got msg: 62
send msg: <
got msg: 31
send msg: <
got msg: 16
send msg: <
got msg: 8
send msg: >=
got msg: 12
send msg: >=
got msg: 14
send msg: <
got msg: 13
send msg: <
got msg: ! 12
The final answer is: 12
Answer was correct!