第二次软件综合实验专题作业——结对编程 1759103 李思佳 、 1759107 陶彦婷

 结对编程

本次作业是由 1759103 李思佳 与 1759107 陶彦婷 共同完成

经过一番讨论,我们决定用JAVA来完成这次作业。选择JAVA的原因大致可以分为以下三点:(1)我们学过的语言一共有三种:C、C++和JAVA。JAVA和C++都是面向对象语言,但C++为了照顾大量的C语言使用者,而兼容了C,这多少影响了其面向对象的彻底性。相比之下,JAVA则是完全的面向对象语言,它句法更清晰,规模更小,且编程环境更为简单。(2)这学期的课程安排偏向于使用JAVA编程,如:移动应用程序开发需要在Eclipse上编写Android程序。由于JAVA是上学期新学的语言,我们对于它的理解和熟悉度不如C/C++,正好可以借这个机会先写一个小程序再次熟悉一下JAVA的语法和编程环境。(3)Java技术正沿着网络渗入各个应用领域。自1995年5月正式推出的11年以来,Java已从编程语言发展成为全球第一大通用开发平台,其跨平台的技术优势为网络计算带来了划时代的变革。Java技术已为计算机行业主要公司所采纳,同时也被越来越多的国际技术标准化组织所接受。所以,学会用JAVA编程,对于我们来说是非常有必要的。

如果算上短学期程序设计基础实践那次的话,这是第二次结对编程,可以使用上次积累的些许经验。但是结对编程这个名词是第一次接触,为了更好的完成作业,我们去了解了一下这个名词——结对编程是一种敏捷软件开发的方法,两个程序员在一个计算机上共同工作。一个人输入代码,而另一个人审查他输入的每一行代码。结对编程能提供更好的设计质量和代码质量,两人合作能有更强的解决问题的能力。

于是我们找了一个空闲的下午,两个人坐在寝室里,模仿结对编程的场景开始我们本次的作业。刚拿到这道题的时候,李思佳第一想法就是一个多重循环列出所有表达式,然后随机选取300道题,但老师后面又给增加了需求。经过两个人初步的讨论,我们定下了大致的程序框架。李思佳读写代码的能力较强;遇到问题的时候善于分析,思路清晰;写代码之前会先想好算法。我写代码的能力比较弱,有时候思维会放不开。所以我们的分工是李思佳负责输入代码(驾驶员),我负责审查代码(观察员)。

结对编程会使两个人都会发现自己平时没有注意到的地方。在进行个人编程的过程中,难免会有思维混乱的时候,也会有一些不熟悉的语法规则,而此时有一个人可以与你讨论或者一起查阅资料,对你编程中的一些小错误也会即时指出来,这样大大提高了编程的效率,也减少了代码的出错率,避免把问题拖到后面的阶段。因为每人在各自独立设计、实现软件的过程中不免要犯些错误,这是不可避免的。但在结对编程中,双方有随时的复审和交流,程序中的错误就会少得多,程序的初始质量会高很多,可以省下很多代码修改、测试的时间。此外,由于每人每天能够高效编程的时间是有限的,在写了一段时间代码后也会有累的时候。而两个人结对编程可以共同分担压力每人都有适当的休息时间。

当然,在具体的实现过程中我们也遇到了许多问题,比如李思佳认为程序中的某个算法的实现用If语句来写比较清晰,而我认为用do-while语句更好……诸如此类的小问题在编程的过程中时有出现。遇到问题两个人会一起讨论,互相阐述自己的观点来说服对方,最后统一意见。值得注意的是,我们两个人在互相探讨的时候又出现了新的更好的思路。毕竟一个人思想有局限性,通过结对编程的方式,集两个人的想法于一起,这样才能设计出更加完善的程序。

以下为程序代码:

package 软工专题;

import javax.script.ScriptEngine;

import javax.script.ScriptEngineManager;

import javax.script.ScriptException;

import java.io.File;

import java.io.FileWriter;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import java.util.Scanner;

 

public class CalculateGenerator {

 

private static ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");

 

private static final char PLUS = '+';

private static final char MINUS = '-';

private static final char MULTIPLY = '*';

private static final char DIVIDE = '/';

private static final char DISPLAY_DIVIDE = '÷';

private static final char EQUALS = '=';

private static final String DOT = ".";

private static final String DOT_REGEX = "\\.";

 

private static final char[] operators = {PLUS, MINUS, MULTIPLY, DIVIDE};

private static final Integer MIN_OPERATOR_COUNT = 2;

private static final Integer MAX_OPERATOR_COUNT = 2;

private static final Integer MIN_CAL_VALUE = 0;

private static final Integer MAX_CAL_VALUE = 100;

 

private static final String FILE_NAME = "result.txt";

private static final String STUDENT_NO = "软工实践";

private static final String NEW_LINE = "\r\n";

 

private static Random random = new Random();

 

 

public static void main(String[] args) throws ScriptException {

System.out.println("请输入要生成的练习题数量:");

Scanner scanner = new Scanner(System.in);

 

Integer expressionCount = scanner.nextInt();

 

List<String> expressionList = new ArrayList<>();

for (int i = 1; i <= expressionCount; i++) {

expressionList.add(getNextExpression());

System.out.println(String.format("正在生成第 %s 道题", i));

}

 

writeExpressionsToFile(expressionList);

System.out.println("生成练习题完成");

}

 

/**

* 将练习题输出到文件

*

* @param expressionList

*/

private static void writeExpressionsToFile(List<String> expressionList) {

File file = new File(FILE_NAME);

try (FileWriter fileWriter = new FileWriter(file)) {

fileWriter.append(STUDENT_NO);

for (String expression : expressionList) {

fileWriter.append(NEW_LINE);

fileWriter.append(expression);

}

} catch (IOException e) {

e.printStackTrace();

}

}

 

/**

* 生成练习题

*

* @return

* @throws ScriptException

*/

private static String getNextExpression() throws ScriptException {

System.out.println("尝试生成下一道题");

 

// 运算符数量

int operatorCount = random.nextInt(MAX_OPERATOR_COUNT + 1 - MIN_OPERATOR_COUNT) + MIN_OPERATOR_COUNT;

 

StringBuilder expression = new StringBuilder();

 

// 运算符

List<Character> operatorList = getOperatorList(operatorCount);

 

// 运算数

List<Integer> calValueList = getCalValueList(operatorCount + 1);

 

for (int i = 0; i < operatorList.size(); i++) {

Character operator = operatorList.get(i);

 

Integer previousCalValue = calValueList.get(i);

Integer nextCalValue = calValueList.get(i + 1);

expression.append(previousCalValue);

 

// 除法校验除数不为0且能被整除

if (DIVIDE == operator) {

calValueList.set(i + 1, getDivideCalValue(previousCalValue, nextCalValue));

} else if (MINUS == operator) {

// 减法校验被减数大于减数

// 当包含小数点时向下取整

String currentResultString = scriptEngine.eval(expression.toString()).toString();

if (currentResultString.contains(DOT)) {

currentResultString = currentResultString.split(DOT_REGEX)[0];

}

Integer currentResult = Integer.valueOf(currentResultString);

while (currentResult < nextCalValue) {

nextCalValue = random.nextInt(MAX_CAL_VALUE + 1);

}

calValueList.set(i + 1, nextCalValue);

}

 

expression.append(operator);

}

 

expression.append(calValueList.get(operatorCount));

 

// 计算当前结果是否为正整数

String result = scriptEngine.eval(expression.toString()).toString();

 

if (result.contains(DOT) || Integer.valueOf(result) < 0) {

System.out.println("当前题目不符合要求");

return getNextExpression();

}

 

String currentExpression = expression.append(EQUALS)

//.append(result)

.toString()

.replaceAll(String.valueOf(DIVIDE), String.valueOf(DISPLAY_DIVIDE));

return currentExpression;

}

 

/**

* 获取运算符

*

* @param operatorCount

* @return

*/

private static List<Character> getOperatorList(int operatorCount) {

List<Character> operatorList = new ArrayList<>();

for (int i = 1; i <= operatorCount; i++) {

Character operator = operators[random.nextInt(operators.length)];

operatorList.add(operator);

}

return operatorList;

}

 

/**

* 获取运算数

*

* @param calValueCount

* @return

*/

private static List<Integer> getCalValueList(int calValueCount) {

List<Integer> calValueList = new ArrayList<>();

for (int i = 0; i < calValueCount; i++) {

calValueList.add(random.nextInt(MAX_CAL_VALUE + 1));

}

return calValueList;

}

 

/**

* 当为除法时校验除数不为0且能被整除

*

* @param previousCalValue

* @param nextCalValue

* @return

*/

private static int getDivideCalValue(Integer previousCalValue, Integer nextCalValue) {

if (nextCalValue == 0 || previousCalValue % nextCalValue != 0) {

nextCalValue = random.nextInt(MAX_CAL_VALUE) + 1;

return getDivideCalValue(previousCalValue, nextCalValue);

}

return nextCalValue;

}

}

 

以下为程序类图:

以下为程序代码截图:

(1)输入要生成的练习题数量:300

     

(2)输出到result.txt文件中:(无答案版)

(3)增加输出答案的代码

(4)再次运行程序并打开result.txt文件,得到含答案版

此时,程序的功能基本完成,可以实现输入题目数量得到相应数量题目、避免题目重复等功能。

以下是输入5道题得到的result.txt文件:

                     

但我们发现300到题内还是存在答案不在0-100范围内的题目,于是对代码进一步修改后,得到的result.txt文件如下:

          

 

对这次作业的感触是,以前都是自己一个人写程序或者大作业,很少会有结对编程这种合作。结对编程不是为了让我们中某个人偷懒的,而是两个人一同进步的学习过程,互相帮助、学习和传递经验,可以得到能力上的互补。结对编程使一个人的知识两个人共享,双方在编程过程中的想法和意见,在互相沟通、交流之后能更快更有效地解决问题,的确不失为一种良好的软件开发的方法。

猜你喜欢

转载自www.cnblogs.com/tyt-/p/10544927.html