模拟input输入并获得print输出的内容
Posted 哦...
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟input输入并获得print输出的内容相关的知识,希望对你有一定的参考价值。
需求源自要进行一次Python考试的判题。题目的答案使用print输出的,我希望获得输出的内容然后与标准答案进行比对,进而做出是否得分的判定。
我的思路是利用io操作,修改用户提交的py源文件,加入一些我的自定义内容,形成一个新的py源文件。
例如,这是用户提交的原始文件
word = input()
word = list(word)
l = len(word)
for i in range(l):
if(ord(word[i])+3<123):
word[i]= chr(ord(word[i])+3)
else:
word[i]= chr(ord(word[i])+3-122+96)
print(''.join(word))
题目本身并不难,就是凯撒密码,但是作为判卷程序需要模拟input输入和获得学生程序print输出的结果。所以我首先写了一个辅助判卷程序mytest.py
answer = "defghijklmnopqrstuvwxyzabc"
question = "abcdefghijklmnopqrstuvwxyz"
def myinput(a=None):
return question
然后再写一个程序用来将mytest.py与学生提交的原始程序有机结合一下。结合的目的无非两个:1、模拟input的输入 2、重定向print的输入
生成新程序的程序gen.py(这是生成程序的第一部分)
import os.path
import os
import sys
import mytest
fout_ac = open("result_ac.txt", "a", encoding="utf8")
fout_un = open("result_un.txt", "a", encoding="utf8")
lines = [
"import mytest\\n", "import sys\\n", "\\n", "input = mytest.myinput\\n",
'sys.stdout = open("result.txt", "w+", encoding="utf8")\\n'
]
pyfiles = os.listdir("clean")
pyfile = pyfiles[0]
try:
#写mytest相关的内容
with open(pyfile, "w", encoding="utf8") as fw:
fw.writelines(lines)
#写学生的源代码
with open(pyfile, "a", encoding="utf8") as fw:
f = open(os.path.join("clean", pyfile), "r", encoding="utf8")
line = f.readline()
while (line):
if not line.startswith("import") and not line.startswith("from"):
fw.write(line + "\\n")
line = f.readline()
fw.write("\\n")
fw.write("\\n")
fw.write("\\n")
f.close()
新生成的结合了mytest和学生提交的原始程序的py文件
import mytest
import sys
input = mytest.myinput
sys.stdout = open("result.txt", "w+", encoding="utf8")
word = input()
word = list(word)
l = len(word)
for i in range(l):
if(ord(word[i])+3<123):
word[i]= chr(ord(word[i])+3)
else:
word[i]= chr(ord(word[i])+3-122+96)
print(''.join(word))
这个生成的程序中,将input函数屏蔽为mytest下的myinput函数,这样input函数的返回值就是26个小写字母,然后原封不动的利用学生书写的业务逻辑来处理这26个小写字母。一旦这个新生成的程序运行结束,最后的处理结果被print输出到重定向的result.txt中。
所以,我们继续完成gen的第二部分,运行生成的程序,并读取生成的程序写入到result.txt中的内容,看这个内容是否是我们期望的内容:
import os.path
import os
import sys
import mytest
fout_ac = open("result_ac.txt", "a", encoding="utf8")
fout_un = open("result_un.txt", "a", encoding="utf8")
lines = [
"import mytest\\n", "import sys\\n", "\\n", "input = mytest.myinput\\n",
'sys.stdout = open("result.txt", "w+", encoding="utf8")\\n'
]
pyfiles = os.listdir("clean")
pyfile = pyfiles[0]
try:
#写mytest相关的内容
with open(pyfile, "w", encoding="utf8") as fw:
fw.writelines(lines)
#写学生的源代码
with open(pyfile, "a", encoding="utf8") as fw:
f = open(os.path.join("clean", pyfile), "r", encoding="utf8")
line = f.readline()
while (line):
if not line.startswith("import") and not line.startswith("from"):
fw.write(line + "\\n")
line = f.readline()
fw.write("\\n")
fw.write("\\n")
fw.write("\\n")
f.close()
#运行上面生成的新程序
os.system("python " + pyfile)
#如果新生成程序正常执行完毕,此时result.txt中应该有一行输出
#读取result.txt中的内容
read_fr_result = open("result.txt", "r+", encoding="utf8")
#result.txt刚写完数据且处于打开的状态,此时游标位于写入内容的最后
#所以直接read是读不到任何内容的,需要用seek将游标拨到文件的开头处
#再进行读入才能读到内容
read_fr_result.seek(0, 0)
line = read_fr_result.readline().strip()
if line == mytest.answer:
#读取的内容与预置答案一致,将包含学生信息的文件名称写入result_ac.txt文件
fout_ac.write(pyfile + "\\n")
else:
raise ValueError()
except:
#程序的RE WA都会被这个except捕捉
#无论是RE WA都视为错误,将包含学生信息的文件名称写入result_un.txt文件
fout_un.write(pyfile + "\\n")
在gen.py中,生成了程序后,就调用os.system来运行这个生成的程序。运行的结果无非是两种情况1,程序正确执行,将处理结果写入了result.txt中 2,程序运行错误,这种错误显然都是RE错误,会被except捕获视为不通过。那么程序运行正确,写入result.txt的结果是否正确呢,就需要读出判定。读出前需要seek,原因在代码注释中已经说明。取出的答案符合预期的就AC,否则就是WA扔出异常供except捕获。
以上是关于模拟input输入并获得print输出的内容的主要内容,如果未能解决你的问题,请参考以下文章
Python3.7入门之print格式化输出以及input输入
Python3.7入门之print格式化输出以及input输入