小学四则运算结对项目报告
目录
一、仓库地址
二、PSP
一、仓库地址:https://git.coding.net/yanglq/Twork.git
二、PSP
PSP2.1 |
任务内容 |
计划共完成需要的时间(h) |
实际完成需要的时间(h) |
Planning |
计划 |
5 |
10 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
2 |
1.5 |
Development |
开发 |
30 |
40 |
Analysis |
需求分析 (包括学习新技术) |
10 |
15 |
Design Spec |
生成设计文档 |
0 |
0 |
Design Review |
设计复审 (和同事审核设计文档) |
5 |
5 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
0.5 |
0.5 |
Design |
具体设计 |
30 |
60 |
Coding |
具体编码 |
8 |
12 |
Code Review |
代码复审 |
1 |
2 |
Test |
测试(自我测试,修改代码,提交修改) |
1 |
4 |
Reporting |
报告 |
2 |
2 |
Test Report |
测试报告 |
0.5 |
1 |
Size Measurement |
计算工作量 |
0.5 |
0.5 |
Postmortem & Process Improvement Plan |
事后总结, 并提出过程改进计划 |
1 |
2 |
我在构建之法中并没有找到这些接口说明,这些大多信息都是在网上查找的。
Information Hiding信息隐藏:信息隐藏指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是不可访问的。
Interface Design接口设计:是传统的后勤保障的一种要素也是一种后勤功能。
Loose Coupling松耦合:系统通常是基于消息的系统,此时客户端和远程服务并不知道对方是如何实现的。客户端和服务之间的通讯由消息的架构支配。改变或者供应者或者服务的问题不能影响到用户.----或者用户的问题不应影响到供应者或者服务。
我负责计算模块,计算模块创建了两个类,一个是User类,与Web页面交互生成要求的算式题目。一个是News类。User里包含expression方法产生四则运算式,toSuffix方法实现中缀转后缀,dealEquation对后缀表达式进行计算。
代码展示:
public LinkedList<String> expression(int n,int c,int b,int min,int max ){ char[] operator=new char[]{'+','-','*','÷'}; Random random=new Random(); LinkedList<String> expression=new LinkedList<String>(); int ope[]= operator(n,c); //产生的运算符的个数 int[] number=new int[ope.length+1]; //运算数的个数,该数组存储运算数 for(int j=0;j<=ope.length;j++){ number[j]=random.nextInt(max-min)+min; //限制产生的数字在上下界之间 } int bracketnum=random.nextInt(ope.length); if (b==1&&bracketnum>0) { // System.out.println("括号数:"+bracketnum); int [] lbracketloc=new int[bracketnum]; int [] rbracketloc=new int[bracketnum]; int [] leftnum=new int[ope.length+1]; int [] rightnum=new int[ope.length+1]; for (int i = 0; i <bracketnum; i++) { lbracketloc[i]=random.nextInt(ope.length); rbracketloc[i]=random.nextInt(ope.length)+1; if (rbracketloc[i]<=lbracketloc[i]) { i--; } } for (int i = 0; i < bracketnum; i++) { //利用桶函数的思想,记录每个运算数对应的括号的个数 leftnum[lbracketloc[i]]++; rightnum[rbracketloc[i]]++; } for (int i = 0; i < ope.length+1; i++) { if (!(leftnum[i]==0||rightnum[i]==0)) { while (!(leftnum[i]==0||rightnum[i]==0)) { leftnum[i]--; rightnum[i]--; } } } int right=0; int left=0; for (int i = 0; i < ope.length; i++) { for (int j = 0; j < leftnum[i]; j++) { expression.add("("); left++; } expression.add(String.valueOf(number[i])); for (int j = 0; j < rightnum[i]; j++) { expression.add(")"); right++; } expression.add(String.valueOf(operator[ope[i]])); if(ope[i]==3){ number[i+1]=decide(number[i],number[i+1]); } } expression.add(String.valueOf(number[ope.length])); for (int i = right; i < left; i++) { expression.add(")"); } } else { for(int i=0;i<ope.length;i++){ expression.add(String.valueOf(number[i])); expression.add(String.valueOf(operator[ope[i]])); if(ope[i]==3){ number[i+1]=decide(number[i],number[i+1]); } } expression.add(String.valueOf(number[ope.length])); } return expression; }
public static String toSuffix(String infix){ List<String> queue = new ArrayList<String>(); List<Character> stack = new ArrayList<Character>(); char[] charArr = infix.trim().toCharArray(); String standard = "*/+-()"; char ch = '&'; int len = 0; for (int i = 0; i < charArr.length; i++) { ch = charArr[i]; if(Character.isDigit(ch)) { len++; }else if(Character.isLetter(ch)) { len++; }else if(ch == '.'){ len++; }else if(Character.isSpaceChar(ch)) { if(len > 0) { queue.add(valueOf(Arrays.copyOfRange(charArr, i - len, i))); len = 0; } continue; }else if(standard.indexOf(ch) != -1) { if(len > 0) { queue.add(valueOf(Arrays.copyOfRange(charArr, i - len, i))); len = 0; } if(ch == '(') { stack.add(ch); continue; } if (!stack.isEmpty()) { int size = stack.size() - 1; boolean flag = false; while (size >= 0 && ch == ')' && stack.get(size) != '(') { queue.add(valueOf(stack.remove(size))); size--; flag = true; } while (size >= 0 && !flag && level.get(stack.get(size)) >= level.get(ch)) { queue.add(valueOf(stack.remove(size))); size--; } } if(ch != ')') { stack.add(ch); } else { stack.remove(stack.size() - 1); } } if(i == charArr.length - 1) { if(len > 0) { queue.add(valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1))); } int size = stack.size() - 1; while (size >= 0) { queue.add(valueOf(stack.remove(size))); size--; } } } return queue.stream().collect(Collectors.joining(",")); }
public static String dealEquation(String equation){ String [] arr = equation.split(","); List<String> list = new ArrayList<String>(); for (int i = 0; i < arr.length; i++) { int size = list.size(); switch (arr[i]) { case "+": double a = Double.parseDouble(list.remove(size-2))+ Double.parseDouble(list.remove(size-2)); list.add(valueOf(a)); break; case "-": double b = Double.parseDouble(list.remove(size-2))- Double.parseDouble(list.remove(size-2)); list.add(valueOf(b)); break; case "*": double c = Double.parseDouble(list.remove(size-2))* Double.parseDouble(list.remove(size-2)); list.add(valueOf(c)); break; case "/": double d = Double.parseDouble(list.remove(size-2))/ Double.parseDouble(list.remove(size-2)); list.add(valueOf(d)); break; default: list.add(arr[i]); break; } } return list.size() == 1 ? list.get(0) : "运算失败" ; }
@org.junit.Test public void testCore(){//测试产生随机式、中缀转后缀和计算后缀表达式 LinkedList<String> list=makeQuestion.expression(5, 0, 1, 2, 99); LinkedList<String> list1=makeQuestion.expression(10, 1, 0, 2, 99); Iterator<String> it=list.iterator(); StringBuilder sd=new StringBuilder(); while (it.hasNext()) { sd.append(it.next()).append(" "); } String[] ss=sd.toString().split(" "); Iterator<String> it1=list1.iterator(); StringBuilder sd1=new StringBuilder(); while (it1.hasNext()) { sd1.append(it1.next()).append(" "); } String[] ss1=sd1.toString().split(" "); makeQuestion.toSuffix("test.txt"); makeQuestion.dealEquation("test.txt"); makeQuestion.toSuffix("test.txt"); makeQuestion.dealEquation("test.txt"); }
@org.junit.Test
public void testIsOpe(){
assertThat(makeQuestion.isOperator("5"), org.hamcrest.CoreMatchers.is(false));
assertThat(makeQuestion.isOperator("+"), org.hamcrest.CoreMatchers.is(true));
assertThat(makeQuestion.isOperator("-"), org.hamcrest.CoreMatchers.is(true));
assertThat(makeQuestion.isOperator("*"), org.hamcrest.CoreMatchers.is(true));
assertThat(makeQuestion.isOperator("÷"), org.hamcrest.CoreMatchers.is(true));
assertThat(makeQuestion.isOperator("("), org.hamcrest.CoreMatchers.is(true));
assertThat(makeQuestion.isOperator(")"), org.hamcrest.CoreMatchers.is(true));
}
News类中
优点:
①可以每时每刻都处在代码复审的状态
②一对程序员可以平等地、互补地进行开发工作
③在开发层次,结对编程能提供更好的设计质量和代码质量,两人合作能有更强的解决问题的能力
④对开发人员自身来说,结对工作能带来更多的信心,高质量的产出能带啦更高的满足感
⑤结对编程能相互督促,在心理上,能够更好地监督自身和更好地提高自身的技术能力
⑥在企业管理层次上,结对能更有效地交流,互相学习和传递经验,能更好地处理人员流动
⑦结对编程能得到更高的投入产出比(Return of Investment)
⑧结对编程在一定程度上避免了个人英雄主义,能够帮助建立集体拥有代码的意识
缺点:
①在高速度中完成任务,任务有较高的技术要求,任务失败的代价很高
②开发人员需要时间来适应这种新的开发模式,刚开始的结对编程效率可能不见得比单独开发效率高
③结对编程要求两个人协调一致,每个人的作息时间需要同步。当有一人出现情况另一人不得不等待
④结对编程不能像单独开发一样自主和自由
⑤结对编程中两个人的职责是相同的,可以减小每一个人的压力,但又容易造成缺乏责任感
结对中的你我:
YLQ:在这次结对作业中她连续几天熬夜查阅各种资料、学习知识来攻克这次的作业,非常地认真尽职,但因为遇到一些难题而变得比较焦躁,写代码时bug较多。总的来说她是个非常棒的结对partner。
ZST:这次结对作业过程中她能比较耐心地尽力完成每一部分,但同时也遇到非常多不懂的知识面,通过查阅各种资料并学习攻克。虽然她掌握的技能和知识较为匮乏,但能努力学习并补足,也是个值得结对的pair。