2016012027+小学四则运算练习软件项目报告
git地址:https://git.coding.net/lhycoding/qylbc2.git
一、需求分析
- 程序可从命令行接收一个输入参数n,然后随机产生n道加减乘除练习题。
- 每个数字在0和100之间,运算符3个到5个之间。
- 每个练习题至少要包含2种运算符。
- 所出的练习题在运算过程中不得出现负数与非整数。
- 将学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中。
- 支持有括号的运算式,包括出题与求解正确答案。注意,算式中存在的括号必须大于2个,且不得超过运算符的个数。(附加)
- 支持真分数的出题与运算(只需要涵盖加减法即可),且支持分数的自动化简。(附加)
二、功能设计
1.基本功能:
Ⅰ程序接收参数n,并对n的合法性作出判断,若出现错误则提示。
Ⅱ自动生成n个运算式,并计算得出结果。
Ⅲ将计算后的结果与运算式一同存入txt文件中,保存在指定目录下。
2.扩展功能(附加):
Ⅰ由于面向对象是小学生,因此数字在0-100之间。
Ⅱ随机产生括号并保证括号的合法有效性。
Ⅲ加入分数运算式,并且保证计算前后都是真分数,且不可化简。
三、设计实现
1.先建一个类进行随机数的生成
2.并用符号去进行随机数组的生成
3.然后再去将他们合并的一个字符串中
4.建两个字符串,一个用来输出,一个用来计算结果
5.最后进行输出
四、算法详解
将数字和符号输入到一个字符串中,判断如果为÷,则str1加一个/,否则str和str1同时加入产生的符号或者数字,最后对整串进行求解,截图上只是三个运算符的计算,四个和五个的原理相同,都通过这样去解决
for (int m=0;m<x;m++) { int i=(int)(Math.random()*3+3); // int i=5; int a,b,c,d,e,f; char k,y,z,q,w; String temp; if(i==3) { a=Operate.num(); String str = Integer.toString(a); String str1 = Integer.toString(a); k=Operate.getOperator(); str += String.valueOf(k); if(k=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(k); } b=Operate.num(); str += b; str1 += b; y=Operate.getOperator(); str += String.valueOf(y); if(y=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(y); } c=Operate.num(); str += c; str1 += c; z=Operate.getOperator(); str += String.valueOf(z); if(z=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(z); } d=Operate.num(); str += d; str1 += d; System.out.print(str); System.out.print("="); System.out.println(jse.eval(str1)); temp = String.valueOf(jse.eval(str1)); Double result = Double.parseDouble(temp); if(result<0||result%1!=0){ m--; } else { System.out.print(str); System.out.print("="); System.out.println(jse.eval(str1)); fop.write(str.getBytes()); fop.write(("=" + jse.eval(str1)).getBytes()); fop.write("\r\n".getBytes()); }
五、测试运行
命令行中显示的结果
文件中结果
六、部分代码展示
public class Operate { public static char getOperator() { char[] a = {'+', '-', '÷', '*'}; int b = (int) (Math.random() * 4); char x = a[b]; return x; } public static int num() { int number = (int) (Math.random() * 101); return number; } }
这段代码是用来产生随机数和运算符号,因为要求用÷显示,所以在除的时候显示÷。
import jdk.nashorn.internal.ir.CallNode; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.io.File; import java.io.IOException; import java.util.Scanner; public class Main { public static void main(String [] args) throws ScriptException, IOException { int x; try { x = Integer.parseInt(args[0]); if(x<1||x>1000){ System.out.println("Sorry,you can only input the number between 1 to 1000!"); return; } }catch (NumberFormatException e){ System.out.println("Sorry,you can only input the number between 1 to 1000!"); return; } MakeFile makeFile = new MakeFile(); makeFile.getFile(x); } }
这一段,让用户输入时出现错误的时候进行提醒,如果输入非法字符,则进行提示。
import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.io.FileOutputStream; import java.io.IOException; public class MakeFile { public void getFile(int x) throws ScriptException, IOException { ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript"); java.io.File file = new java.io.File("result.txt"); //生成保存结果的文件 FileOutputStream fop = new FileOutputStream(file); if (!file.exists()) { file.createNewFile(); } String serialNo = "2016012027"; fop.write(serialNo.getBytes()); fop.write("\r\n".getBytes()); for (int m=0;m<x;m++) { int i=(int)(Math.random()*3+3); int a,b,c,d,e,f; char k,y,z,q,w; String temp; if(i==3) { a=Operate.num(); String str = Integer.toString(a); String str1 = Integer.toString(a); k=Operate.getOperator(); str += String.valueOf(k); if(k=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(k); } b=Operate.num(); str += b; str1 += b; y=Operate.getOperator(); str += String.valueOf(y); if(y=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(y); } c=Operate.num(); str += c; str1 += c; z=Operate.getOperator(); str += String.valueOf(z); if(z=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(z); } d=Operate.num(); str += d; str1 += d; temp = String.valueOf(jse.eval(str1)); Double result = Double.parseDouble(temp); if(result<0||result%1!=0){ m--; } else { System.out.print(str); System.out.print("="); System.out.println(jse.eval(str1)); fop.write(str.getBytes()); fop.write(("=" + jse.eval(str1)).getBytes()); fop.write("\r\n".getBytes()); } } else if (i==4) { a=Operate.num(); String str = Integer.toString(a); String str1 = Integer.toString(a); k=Operate.getOperator(); str += String.valueOf(k); if(k=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(k); } b=Operate.num(); str += b; str1 += b; y=Operate.getOperator(); str += String.valueOf(y); if(y=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(y); } c=Operate.num(); str += c; str1 += c; z=Operate.getOperator(); str += String.valueOf(z); if(z=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(z); } d=Operate.num(); str += d; str1 += d; q=Operate.getOperator(); str += String.valueOf(q); if(q=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(q); } e=Operate.num(); str += e; str1 += e; temp = String.valueOf(jse.eval(str1)); Double result = Double.parseDouble(temp); if(result<0||result%1!=0){ m--; } else { System.out.print(str); System.out.print("="); System.out.println(jse.eval(str1)); fop.write(str.getBytes()); fop.write(("=" + jse.eval(str1)).getBytes()); fop.write("\r\n".getBytes()); } } else if (i==5) { a=Operate.num(); String str = Integer.toString(a); String str1 = Integer.toString(a); k=Operate.getOperator(); str += String.valueOf(k); if(k=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(k); } b=Operate.num(); str += b; str1 += b; y=Operate.getOperator(); str += String.valueOf(y); if(y=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(y); } c=Operate.num(); str += c; str1 += c; z=Operate.getOperator(); str += String.valueOf(z); if(z=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(z); } d=Operate.num(); str += d; str1 += d; q=Operate.getOperator(); str += String.valueOf(q); if(q=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(q); } f=Operate.num(); str += f; str1 += f; w=Operate.getOperator(); str += String.valueOf(w); if(w=='÷'){ str1 += '/'; } else{ str1 += String.valueOf(w); } e=Operate.num(); str += e; str1 += e; temp = String.valueOf(jse.eval(str1)); Double result = Double.parseDouble(temp); if(result<0||result%1!=0){ m--; } else { System.out.print(str); System.out.print("="); System.out.println(jse.eval(str1)); fop.write(str.getBytes()); fop.write(("=" + jse.eval(str1)).getBytes()); fop.write("\r\n".getBytes()); } } } } }
这一段用来进行计算,一个str一个str1,一个进行显示,一个进行计算,最后结果result,用来加到显示str之后,让用户看到的式子是÷。题数上的话,我是通过for循环,如果结果是分数或者小数,使循环的数减一,即相当于不加,而如果是整数的话,则进行输出,这样就保证了输出的算式数量与用户需求一样。
代码上的话,因为之前没学过Java,所以这一个星期,临阵磨枪,学了一些Java的简单输入输出语句,以及看了看网上的一些博客的做法,最后还是决定用js里的eval函数,这个函数用起来比较方便仅通过几行代码,便实现了需要好多行代码才能实现的功能
七、项目总结
之前没有接触过Java,这个作业做了好多天,自从布置了作业一直在看这个东西怎么做,好多次因为在工作室看这个忘记时间,去了食堂已经没饭,只能回去泡面,不过所幸最后做出来一个基本功能,也算有所收获,周末也如杨老师说的一样,在补以前的东西,附加功能的话,实在是时间太短,做不出来,这次项目,学到了一些Java的基本语言,有所收获。
八、PSP展示
PSP2.1 |
任务内容 |
计划共完成需要的时间(h) |
实际完成需要的时间(h) |
Planning |
计划 |
2 |
2 |
· Estimate |
· 估计这个任务需要多少时间,并规划大致工作步骤 |
1 |
1 |
Development |
开发 |
20 |
37 |
· Analysis |
· 需求分析 (包括学习新技术) |
0.5 |
0.5 |
· Design Spec |
· 生成设计文档 |
0.2 |
0.2 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
0.1 |
0.1 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
0.5 |
0.6 |
· Design |
· 具体设计 |
1 |
1 |
· Coding |
· 具体编码 |
15 |
20 |
· Code Review |
· 代码复审 |
2 |
2 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
1 |
2 |
Reporting |
报告 |
1 |
3 |
· Test Report |
· 测试报告 |
1 |
1 |
· Size Measurement |
· 计算工作量 |
1 |
1 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
0.2 |
0.2 |