我正在开发一个分配服务器,学生可以上传他们的程序解决方案。它应该可以使用几种编程语言。为了测试程序,我正在执行一个shell脚本,并将测试用例和文件作为参数传递:
printf '10\n3\n+\n' | ./eval_python steps.py
它的工作,这不是问题。对于输出我得到类似的东西:
使用shell脚本运行python脚本:
$ How much steps? Step size? Counting up (+) or down (-) ? Step 0: 3
$ Step 1: 6
$ Step 2: 9
$ Step 3: 12
$ Step 4: 15
$ [..]
这种格式使得评估非常困难,也可能使学生感到困惑,因为他们没有看到输入(当你从shell运行python脚本时,输出看起来像下面的例子)。对于评估难度,学生不得像在此解决方案中那样命名他们的输入,如果他们只是问Steps?
而不是How much steps?
,那也没关系。
直接从shell运行python脚本:
$ How much steps? 10
$ Step size? 3
$ Counting up (+) or down (-)? +
$ Step 0: 3
$ Step 1: 6
$ Step 2: 9
$ Step 3: 12
$ Step 4: 15
$ [..]
有没有办法在输出中组合输入?或者其他想法如何解决这个问题?
非常感谢!
答案 0 :(得分:1)
自动处理用户提示比看上去困难,遗憾的是printf
不足以完全模拟它。如果您不想触及python代码本身,则可能必须使用expect
,这是一种用于处理交互式程序的脚本语言。
如果您的系统上没有(可能),请使用sudo apt install expect
或sudo yum install expect
进行安装。我在这里的这个粗糙的东西应该能够满足你的要求:
<强> expect_script.exp 强>
#!/usr/bin/expect -f
set steps [lindex $argv 0]
set size [lindex $argv 1]
set plus_or_minus [lindex $argv 2]
set script_name [lindex $argv 3]
spawn python3 ${script_name}
# Or `spawn eval_python ${script_name}`, as long as it is a python 3 interpreter as well
# If it is python 2, all `input` calls within need to be changed to `raw_input`
expect "steps"
send -- "${steps}\r"
expect "size"
send -- "${size}\r"
expect "Counting"
send -- "${plus_or_minus}\r"
expect eof
然后像这样称呼它:
./expect_script.exp 10 3 + steps.py
如果您对语法或语义有疑问,请随时提出。但是不要期待太多(哈哈),我不是很擅长奇怪的Unix工具。
使用可变数量的参数进行编辑:
<强> expect_script.exp 强>
#!/usr/bin/expect -f
spawn python3 [lindex $argv 0]
# Or `spawn eval_python [lindex $argv 0]`, as long as it is a python 3 interpreter as
# well. If it is python 2, all `input` calls within need to be changed to `raw_input`.
set sleep_time 0.1 # using `sleep` to wait for the next prompt is, usually,
# a very bad idea. Maybe you can control your input calls
# by including unique identifiers in them, such as 1, 2, 3..
# and using `except` to properly wait for them?
for {set i 1} {$i < [llength $argv]} {incr i 1} {
sleep $sleep_time
send -- [lindex $argv $i]\r
}
expect eof
调用顺序已更改,因为我们需要在以参与方式发送参数之前调用我们的python脚本:
./expect_script.exp test.py 10 3 +
或者,更改python脚本以接受命令行参数。如果您计划执行任务自动化,或重复使用代码,或者只是一般 - 命令行参数几乎总是比用户提示更好。本机python ArgParse
模块非常好,即使你不想重写当前的代码,它仍然值得研究并尝试将来应用它。
答案 1 :(得分:0)
可以使所有流“需求驱动”,但这不是一项微不足道的任务,尤其是脚本编写。我的意思是,当管道说它需要更多输入时,每个输入字符串只传递给管道。同样,您必须在准备好后立即收集输出。 通过这样做,您可以在消耗它们时组合输入和输出流,以便制作合理的报告。
请注意,您可能需要注入一些新行,以使其真正可读。
答案 2 :(得分:0)
也许不同的方法是告诉用户他们必须提出具体问题。
让你的线束按字符(我知道)读取输出字符,并且一旦它完全匹配特定的预期问题,它就会将匹配的答案作为输入注入,但每次匹配只注入一次。当然,一旦满足所有问题,您就可以切换到更快的批量读取。
然后,您可以按字节输出流式传输,并以自然顺序将注入的响应传输到日志文件,该顺序与您的线束正在执行的操作相匹配。对于线束来说,暂停并打印未消耗的问题作为诊断辅助可能是有益的。
这允许提到的问题排序,可选问题等,但是将设计规范的一部分硬连接到客户要求。向学生明确表示,如果与自动处理器的提示不匹配,或者说提供本地语言翻译的客户,他们将失去分数。