結對編程java
本次做業由 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編程,對於咱們來講是很是有必要的。算法
若是算上短學期程序設計基礎實踐那次的話,這是第二次結對編程,可使用上次積累的些許經驗。可是結對編程這個名詞是第一次接觸,爲了更好的完成做業,咱們去了解了一下這個名詞——結對編程是一種敏捷軟件開發的方法,兩個程序員在一個計算機上共同工做。一我的輸入代碼,而另外一我的審查他輸入的每一行代碼。結對編程能提供更好的設計質量和代碼質量,兩人合做能有更強的解決問題的能力。express
因而咱們找了一個空閒的下午,兩我的坐在寢室裏,模仿結對編程的場景開始咱們本次的做業。剛拿到這道題的時候,李思佳第一想法就是一個多重循環列出全部表達式,而後隨機選取300道題,但老師後面又給增長了需求。通過兩我的初步的討論,咱們定下了大體的程序框架。李思佳讀寫代碼的能力較強;遇到問題的時候善於分析,思路清晰;寫代碼以前會先想好算法。我寫代碼的能力比較弱,有時候思惟會放不開。因此咱們的分工是李思佳負責輸入代碼(駕駛員),我負責審查代碼(觀察員)。由於對JAVA語言的熟悉度不夠,咱們花了一整個下午,一邊查資料、翻書一邊寫代碼,才終於把程序大概的框架寫完了,這時程序的基本功能已經能夠實現。以後,咱們又利用了幾天的課餘時間,對代碼進行完善和優化。在這其間有想不出算法的苦惱,改bug時的迷茫和運行成功時的喜悅和自豪感,心情不可謂不復雜。編程
結對編程會使兩我的都會發現本身平時沒有注意到的地方。在進行我的編程的過程當中,不免會有思惟混亂的時候,也會有一些不熟悉的語法規則,而此時有一我的能夠與你討論或者一塊兒查閱資料,對你編程中的一些小錯誤也會即時指出來,這樣大大提升了編程的效率,也減小了代碼的出錯率,避免把問題拖到後面的階段。由於每人在各自獨立設計、實現軟件的過程當中難免要犯些錯誤,這是不可避免的。但在結對編程中,雙方有隨時的複審和交流,程序中的錯誤就會少得多,程序的初始質量會高不少,能夠省下不少代碼修改、測試的時間。此外,因爲每人天天可以高效編程的時間是有限的,在寫了一段時間代碼後也會有累的時候,而兩我的結對編程能夠共同分擔壓力讓每人都有適當的休息時間。小程序
固然,在具體的實現過程當中咱們也遇到了許多問題,好比李思佳認爲程序中的某個算法的實現用If語句來寫比較清晰,而我認爲用do-while語句更好;對於變量的定義是用字母仍是可讀性更高的單詞……諸如此類的小問題在編程的過程當中時有出現。遇到問題兩我的會一塊兒討論,互相闡述本身的觀點來講服對方,最後統一意見。值得注意的是,咱們兩我的在互相探討的時候又出現了新的更好的思路。畢竟一我的思想有侷限性,經過結對編程的方式,集兩我的的想法於一塊兒,這樣才能設計出更加完善的程序。網絡
如下爲程序代碼:app
package 軟工專題;框架
import javax.script.ScriptEngine;dom
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();
}
else if( Integer.valueOf(result) >= 100 || 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文件以下:
對此次做業的感觸是,之前都是本身一我的寫程序或者大做業,不多會有結對編程這種合做。結對編程不是爲了讓咱們中某我的偷懶的,而是兩我的一同進步的學習過程,互相幫助、學習和傳遞經驗,能夠獲得能力上的互補。結對編程使一我的的知識兩我的共享,雙方在編程過程當中的想法和意見,在互相溝通、交流以後能更快更有效地解決問題,的確不失爲一種良好的軟件開發的方法。