标签:... 输出 Popen PIPE 求导 import UnitOneTaskOne
OO:UnitOneTaskOne
如果你每周不熬个两三晚,你应该都不好意思说在OO划过水 --诸彤宇
目录
-
思路分享
-
关于测试
-
一些推荐
思路分享
以下是笔者完成第一次作业的大致思路,已省略若干细节
1.输入预处理:
去除空格和\t
替换++、--、+-、-+
将+x,-x,x+,x-替换成+1*x,-1*x,x**1+,x**1-。
目的?全部替换成[+-]\d+*x**[+-]?\d+
(可能各位神仙看到这,会想到笔者未说明的细节问题,笔者只是分享大致思路,不包含若干细节)
最后用正则提取每一项啦
2.合并化简求导
HashMap<BigInteger, BigInteger>存储用正则提取的项的系数,指数,边提取,边比较,边化简
如果你采用HashMap<String, String>完成上述步骤的话,可能存在一个问题,举个例子:x**2+x**+2,如果你一不小心直接把提取到的指数部分直接比较,程序可能当成是两个不同的指数
如果你的程序对上述样例的输出不如人意,那么恭喜你,你要被hack了
关于求导,建议采用工厂模式,虽然本次只有一种类型,但说不定我们优秀可爱的助教们在下次就会出类似于三角函数,对数函数等求导的要求
关于工厂模式,建议最后采用HashMap<String, Object>的方法取代switch-case的方法,方便拓展而且减少代码行数
3.关于格式化输出
因为系数和指数都是整数,所以求导之后只有指数是-2的项需要考虑系数是否为1或-1
求导之后指数是0,直接输出系数;指数是1,如果系数还是1或-1,那么求导之前项的系数只能是分数,如果只按指数讨论,笔者的格式化输出逻辑减少5-6行,当然你也可以像第一次实验的输出要求一样讨论
附上讨论区原帖:
最后附上两张笔者程序的性能图:
关于测试
测试部分包含多种方法,任君选择
本文未特殊标注Author的方法,均笔者所建,欢迎各位神仙投稿,扩充每篇推送的Author阵容
1.编写.sh
附上笔者在讨论区的分享:
大致思路如上,此处再补充一些细节
1.1 关于eval()函数无法将含有前导0的字符串转化成表达式的问题
#去除前导0
str = re.sub(r'(?<!\d)0+(?=\d)', "", str)
1.2 关于转换后的表达式如果是常数被认定为int,无法代值运算的问题
#直接特判
if isinstance(expr,int):
result = expr
else:
result = int(expr.evalf(subs={x: 2}))
1.3 关于管道的使用
#只是举个例子,说明.sh编写应有的样子
cat $InputFileName | while read line
do
...
correctOutput=$(echo "$line" | python diff.py)
result=$(echo "$myOutPut$space$correctOutput" | python compare.py)
...
done
当然你也可以为每个输出都创建文件
2.使用Junit
//只是举个例子,Junit的组件还是很多的
import org.junit.Test;
import JUnitTestTools.EnhancedUserTestTools;
import java.io.File;
public class PolyTest {
@Test
public void main() throws Exception {
new EnhancedUserTestTools(Poly.class, 2000).testAll(new File("./test/poly/test1.txt"));
}
}
笔者只是用惯了.sh,所以虽然Junit很强大,但用的次数较少
3.使用subprocess
Author:冯天昱
3.1关于subprocess的使用
我们可以通过调用subprocess.Popen()来运行我们的java程序,Popen()提供了stdin、stdout等参数,我们可以很方便地将输入输出重定向到python中的文件对象,或者重定向到subprocess.PIPE,直接使用write()、readlines()等方法输入和获得输出。
下面来看一个例子:
from subprocess import Popen, PIPE
p = Popen(r'echo hahaha', stdout = PIPE, shell = True, text=True)
print(p.stdout.readline())
运行结果为:
hahaha
在这个例子中我们把输出重定向到PIPE,之后通过PIPE的readline()
方法读取输出。text=True
参数可以帮助我们将PIPE的输入输出从字节流转化成str类型,方便进行数据处理。
同样地,如果把输入重定向到PIPE (stdin = PIPE
),那么就可以通过p.stdin.write(str)
来向程序输入数据了
3.2测试流程
测试的总体流程大概分为三个部分:测试用例生成、执行程序、运行结果验证。
在测试用例生成部分,我们使用xeger直接生成大量随机数据;
在执行程序部分,我们通过Popen调用Java程序;
在结果验证部分,我们使用sympy对原表达式进行求导,与程序求导结果进行比对。
大致的程序框架如下:
import ...
from ... import ...
caseSize = 100
cases = case_gen(caseSize, ...)#input list
p = Popen(r'java -classpath <path> <MainClass>',
stdin = PIPE, stdout = PIPE, shell = True, text=True)
for case in cases:
p.stdin.write(case)
out = p.stdout.readlines()#output list
ans = calcAns(cases)#answer list
for i in range(caseSize):
if (!equal(out[i],ans[i])):
print("<debug需要保留的信息>")
一些推荐
以下是笔者认为相对有价值的内容,推荐给各位
1.只有了解昂神对OO的改革,才知道17级及以后的6系学生面临的OO制度的合理性
https://www.zhihu.com/question/30413458/answer/733229545
2.作为贝导的学生,怎么会错过ljz学长的优秀博客
比如这篇新手教学:
https://www.cnblogs.com/neolinsu/p/10586550.html
3.阿里团队推出的优秀开发工具:Arthas
https://github.com/alibaba/arthas
随便一张官网介绍:
相信我,随便一个API都比你的print强
4.理论和实践结合的经典书:
-
《Effective Java》
-
《Java Concurrency In Practice》
标签:...,输出,Popen,PIPE,求导,import,UnitOneTaskOne 来源: https://www.cnblogs.com/joeye153/p/12423519.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。