本次結對編程讓我學到了許多許多知識,受益不淺!在此以前,我沒想過我能作出一個雙擊運行的小程序。html
感謝個人隊友與我同心合力,感謝室友宇欣告訴我操做符爲「最多多少」而不是「多少」並教我使用效能分析工具,感謝陳杰任勞任怨幫我測試14寸顯示屏效果,感謝福孝大佬給我發的安裝包!感謝學姐對項目的建議!java
代碼倉庫地址:https://git.coding.net/Siamese_miao/team.gitgit
本人:莊莉,學號:2016012034算法
隊友:王璐瑤,學號:2016012095編程
PSP小程序 |
任務內容數組 |
計劃共完成須要的時間(h)多線程 |
Planningapp |
計劃dom |
0.5 |
Estimate |
估計這個任務須要多少時間,並規劃大體工做步驟 |
0.5 |
Development |
開發 |
39.25 |
Analysis |
需求分析 (包括學習新技術) |
0.5 |
Design Spec |
生成設計文檔 |
0.25 |
Design Review |
設計複審 (和同事審覈設計文檔) |
0.25 |
Coding Standard |
代碼規範 (爲目前的開發制定合適的規範) |
0.25 |
Design |
具體設計 |
2 |
Coding |
具體編碼 |
30 |
Code Review |
代碼複審 |
1 |
Test |
測試(自我測試,修改代碼,提交修改) |
5 |
Reporting |
報告 |
4 |
Test Report |
測試報告(包括博客) |
3 |
Size Measurement |
計算工做量 |
0.5 |
Postmortem & Process Improvement Plan |
過後總結, 並提出過程改進計劃 |
0.5 |
Information hiding is part of the foundation of both structured design and object-oriented design. In structured design, the notion of 「black boxes」 comes from information hiding. In object-oriented design, it gives rise to the concepts of encapsulation and modularity, and it is associated with the concept of abstraction.
在《代碼大全》中列出了兩類須要隱藏的內容:
第一類信息是複雜化的信息。對於咱們的項目,咱們的main函數只有一個對gui的實例化,使用者並不知道內部的運行方式。內部的算法實現封裝起來,外部只有調用的接口,只能夠調用方法,不能夠改變內部變量,作到了信息隱藏。
對於第二類,是指變更的信息。好比在用戶的輸入需求中出現了錯誤,提示並返回,這個錯誤在類中進行了適當的處理,錯誤沒有擴散,這樣能夠提升程序的容錯性。
在本項目設計接口過程當中,按需求新建接口,使用明確的命名方式使接口的功能清晰化,加強了可讀性;接口與接口之間互相獨立,使用方便。
耦合的強度依賴於:(1)一個模塊對另外一個模塊的調用;(2)一個模塊向另外一個模塊傳遞的數據量;(3)一個模塊施加到另外一個模塊的控制的多少;(4)模塊之間接口的複雜程度。等等。
模塊內子程序(下一個層次上)應共享數據(有必定的耦合度),而減小全局變量能下降子程序性間的耦合性。
類與類之間一般經過接口的契約實現服務提供者/服務請求者模式,這就是典型的鬆耦合。
耦合程度越高,模塊與模塊之間的聯繫性就更高,系統的靈活性就越低,報錯率就更高。在咱們的項目中,計算模塊的調用都比較單一,沒有雙向調用,使用之間互不干擾,增長了靈活性。
通過商討,咱們決定基於個人我的項目修改。我先刪除了原來的分數運算,在將普通四則運算與括號四則運算拆分,變成簡單加減、四則運算、有括號加減與有括號四則運算。如圖我分爲5個類(test爲單元測試)。
其中,有條件生成操做符與後一位數我較爲滿意,它大大的下降了運行效率,部分代碼可看第5模塊的性能改進模塊。
基於原來的我的項目代碼,因爲出現了運算過程以及運算結果數值範圍的限制,本來的result(String temp)再也不使用,改用了棧運算。
1 // 計算結果 2 public static Object result(String temp) { 3 ScriptEngineManager sem = new ScriptEngineManager(); 4 ScriptEngine se = sem.getEngineByName("js"); 5 Object last = 0; 6 try { 7 last = se.eval(temp); 8 } catch (ScriptException e) { 9 e.printStackTrace(); 10 } 11 return last; 12 }
在棧的運算中加入判斷
1 if (Math.abs(sresulat) > upper || Math.abs(sresulat) < lower) 2 { 3 return 0; 4 }
而對於簡單加減無括號全程不改變優先級的運算則不過棧,直接邊生成數字便運算,減小了運算時間。
另外,本來的操做符是一開始隨機生成好的再判斷選擇後一個數,而後再判斷符號是否合法,再修改符號,若是仍是有小數或負數,則從新運行生成算式的函數,這樣使得代碼運行有些慢且屢次運行。再加上數值範圍的限定以及能夠存在負數,我改變了想法。
由於負數的存在,使得加減號並無數字的限制,而乘法有上限限制,除法有下限限制。因此在只有加減的運算中,符號隨機生成,後一個數根據運算符以及數值範圍生成合法的數。
1 // 相加不超過範圍 2 public static int decide0(int x, int min, int max) 3 { 4 int y; 5 int temp = 0; 6 if (x > 0) 7 { 8 temp = max - min - x + 1;// 加一個正整數範圍 9 } else 10 { 11 temp = max - (min - x) + 1;// 加至正整數的範圍 12 } 13 if (temp < 0) 14 {// 範圍小於0 15 if (x > 0) 16 { 17 temp = Math.abs(x) - min * 2 + 1;// 正整數過大,需加負數 18 y = 0 - (int) (Math.random() * temp) - min; 19 } else 20 { 21 temp = Math.abs(x) - 2 * min + 1;// 負數太小,越值,加小整數至負數範圍 22 y = (int) (Math.random() * temp) + min; 23 } 24 } else 25 { 26 y = (int) (Math.random() * temp + min); 27 } 28 return y; 29 } 30 31 // 相減不小於最小 32 public static int decide1(int x, int min, int max) 33 { 34 int temp = 0; 35 int y = 0; 36 if (x > 0) 37 { 38 temp = x - 2 * (min - 1) - 1; // 減一個正數範圍 39 } else 40 { 41 temp = max + x - min + 1;// 減一個正數範圍 42 } 43 if (temp > 0) 44 { 45 if (x < 0 && temp < min) 46 { 47 temp = Math.abs(x) - 2 * min + 1;// 負數太小,需減負數 48 y = 0 - (int) (Math.random() * temp) - min; 49 } else 50 { 51 y = (int) (Math.random() * temp + min); 52 } 53 } else 54 { 55 temp = max - x - min + 1;// 只有x>0的狀況會出現,正數太小,需減負數 56 y = 0 - (int) (Math.random() * temp) - min; 57 } 58 return y; 59 }
當有乘除時,則根據上一個數生成操做符,再根據操做符生成合法的後一位數。
1 // 操做符的選定 2 public static int operator(int num, int middle2, int middle3) 3 { 4 if (Math.abs(num) <= middle2) 5 {// 除法下界 6 if (Math.abs(num) < middle3) 7 { 8 return 3; 9 } else 10 { 11 return 0; 12 } 13 } else if (Math.abs(num) >= middle3) 14 {// 乘法上界 15 return 2; 16 } else 17 { 18 return (int) (Math.random() * 4); 19 } 20 } 21 // 下一位數字的選定 22 public static int[] numberB(int key, int num, int lower, int upper) 23 { 24 int[] find = new int[] { 0, lower }; 25 if (key == 0) 26 { 27 find[1] = decide0(num, lower, upper); 28 return find; 29 } else if (key == 2) 30 { 31 int[] judge = new int[2]; 32 judge = decide2(num, lower);// 確保可以整除,並不低於下限 33 if (judge[0] == 0) 34 { 35 find[1] = judge[1]; 36 return find; 37 } else 38 { 39 find[0] = 1; 40 } 41 } else if (key == 3) 42 { 43 find[1] = decide3(num, lower, upper); 44 if (find[0] == 0) 45 { 46 return find; // 乘法不超過上限 47 } 48 } 49 find[1] = decide1(num, lower, upper); 50 return find; 51 }
這樣大大減小了從新調用函數的問題,而且實現了運算過程與數值皆在範圍內的功能。
在附加題記錄用戶模塊,一開始使用contains(name)函數判斷用戶,後來發現這樣會出現abc與abcabc被認爲同一我的而的狀況,通過思考,咱們使用字符串的斷開。
1 String[] arrays = txt.split(" ");
再使用equals(String)函數判斷用戶,解決了這個問題。
其中,生成有括號與乘除的式子生成的函數判斷耗時最多,由於它的判斷較多,限制較多,優先級易改變,容易生成最終不合法的式子而從新運行。
1 // 帶括號的四則運算 2 public static String Bracket(int lower, int upper, int o) { 3 int middle2 = lower * lower;// 除法下界 4 int middle3 = upper / lower;// 乘法上界 5 int brack_left = 0; // 記錄未匹配的左括號個數 6 int brack = 0; // 括號個數 7 int j = 0; 8 char[] p = new char[] { '+', '-', '÷', '*' }; 9 String temp1 = ""; 10 int[] num = new int[o + 1]; // 數字 11 int[] key = new int[o]; // 符號所在的下標 12 num[0] = (int) (Math.random() * (upper - lower + 1) + lower); 13 int result; 14 int[] find = new int[2]; 15 for (j = 0; j < (o - 1); j++) { 16 if (num[j] < 0) { 17 temp1 += "(" + String.valueOf(num[j]) + ")"; 18 } else { 19 temp1 += String.valueOf(num[j]); 20 } 21 int tmpcnt = brack_left; 22 for (int i = 0; i < tmpcnt; i++) { // 若當前有未匹配的左括號,則對每個未匹配的左括號,都有必定機率生成相應右括號。 23 if ((int) (Math.random() * 5) > 1) { // 生成右括號機率爲0.6 24 brack_left--; 25 temp1 += ")"; 26 } 27 } 28 key[j] = calculate.operator(num[j], middle2, middle3); 29 find = calculate.numberB(key[j], num[j], lower, upper); 30 if (find[0] == 1) { 31 key[j] = 1; 32 } 33 num[j + 1] = find[1]; 34 temp1 += String.valueOf(p[key[j]]); 35 if (((brack * 2) <= o) && (((int) (Math.random() * 2)) == 0)) { // 以必定機率生成左括號,機率爲1/2 36 temp1 += "("; 37 brack++; 38 brack_left++; 39 j++; 40 if (num[j] < 0) { 41 temp1 += "(" + String.valueOf(num[j]) + ")"; 42 } else { 43 temp1 += String.valueOf(num[j]); 44 } // 生成左括號後必須生成一個數字和運算符,否則可能出現(15)這樣的錯誤 45 key[j] = calculate.operator(num[j], middle2, middle3); 46 find = calculate.numberB(key[j], num[j], lower, upper); 47 if (find[0] == 1) { 48 key[j] = 1; 49 } 50 num[j + 1] = find[1]; 51 temp1 += p[key[j]]; 52 } 53 } 54 while (j != o) { // 判斷是否爲最後一個數 55 if (num[j] < 0) { 56 temp1 += "(" + String.valueOf(num[j]) + ")"; 57 } else { 58 temp1 += String.valueOf(num[j]); 59 } 60 key[j] = calculate.operator(num[j], middle2, middle3); 61 temp1 += p[key[j]]; 62 find = calculate.numberB(key[j], num[j], lower, upper); 63 if (find[0] == 1) { 64 key[j] = 1; 65 } 66 j++; 67 num[j] = find[1]; 68 } 69 if (num[o] < 0) { 70 temp1 += "(" + String.valueOf(num[o]) + ")"; 71 } else { 72 temp1 += String.valueOf(num[o]); 73 } 74 while ((brack_left) != 0) { // 補全右括號 75 temp1 += ")"; 76 brack_left--; 77 } 78 result = stack.work(temp1, lower, upper, 1); 79 if (result == 0) { 80 temp1 = Bracket(lower, upper, o); 81 } 82 return temp1; 83 84 } 85 86 }
項目整體分析圖,從內存,多線程,CPU等方面分析了計算模塊的性能,截圖以下:
性能分析過程截圖:
按F4,出現如下截圖。資源所有被回收。證實沒有資源泄露。程序性能良好。
使用單元測試的CPU分析以下圖:
使用Command.java的CPU效能分析以下圖:
1 @Test 2 public void testWork() { 3 assertEquals(0, stack.work("7-5÷(1*37)÷(1*83)", 1, 900, 1)); 4 assertEquals(30, stack.work("55+(-25)÷5*(20-15)", 2, 300, 1)); 5 assertEquals(80, stack.work("((55+25)÷5)*(20-15)", 2, 300, 1)); 6 assertEquals(0, stack.work("60*(20-15)", 2, 200, 1)); 7 }
第一個斷言測試的是沒法整除返回錯誤標誌0;
第二個斷言測試的是負數運算;
第三個斷言測試的是特殊括號位置的運算;
第四個斷言測試的是超過數值返回錯誤標誌0。
1 @Test 2 public void testAll() { 3 // 順序不一樣以及異常測試。生成的文件會被覆蓋。 4 String[] arg0 = new String[] { "-n", "100", "-m", "5", "100", "-o", "3", "-c", "-b" }; 5 String[] arg1 = new String[] { "-m", "5", "50", "-o", "3", "-n", "100", "-c" }; 6 String[] arg2 = new String[] { "-o", "3", "-m", "5", "50", "-n", "100", "-b" }; 7 String[] arg3 = new String[] { "-n", "100", "-o", "3", "-m", "5", "50" }; 8 Command.main(arg0);// 有括號四則運算測試 9 Command.main(arg1);// 四則運算測試 10 Command.main(arg2);// 有括號加減運算測試 11 Command.main(arg3);// 加減運算測試 12 }
該部分測試的命令行的更改輸入順序的四種出題選擇正常運行。輸入異常部分請看第七點。
命令行單元測試覆蓋率截圖以下:
1 @Test 2 public void testDecide2() { 3 int[] find = new int[2]; 4 find = calculate.decide2(20, 2); 5 assertEquals(2, find[1]); 6 find = calculate.decide2(13, 2); 7 assertEquals(1, find[0]); 8 }
decide2(int x, int min)爲除法選擇除數的函數,函數以下:
1 // 被除數能被除數整除並不低於最小 2 public static int[] decide2(int x, int min) 3 { 4 int[] judge = new int[] { 1, 0 }; 5 int temp = Math.abs(x) / min - min + 1;// 除數的範圍 6 for (int i = min; i < (temp + min); i++) 7 { 8 if (Math.abs(x) % i == 0) 9 {// 判斷是否整除 10 judge[0] = 0; 11 judge[1] = i; 12 return judge; 13 } 14 } 15 return judge; 16 }
其中,judge[0]用於判斷該數可否有可整除的除數,1爲沒有,0爲有,judge[1]爲除數的值。該單元測試則測試了一次可產生除數與一次不能產生除數的狀況。
1 @Test 2 public void testAll() { 3 String[] arg4 = new String[] { "-o", "3", "-m", "5", "50", "-n" }; 4 String[] arg4_1 = new String[] { "-o", "3", "-n", "-m", "5", "50" }; 5 String[] arg4_2 = new String[] { "-n", "100000", "-m", "5", "50" }; 6 String[] arg4_3 = new String[] { "-o", "3", "-m", "5", "50" }; 7 8 String[] arg5 = new String[] { "-n", "50" }; 9 String[] arg5_1 = new String[] { "-m", "5", "-n", "50", "-o", "3" }; 10 String[] arg5_2 = new String[] { "-n", "50", "-m", "3" }; 11 String[] arg5_3 = new String[] { "-n", "50", "-o", "3", "-m" }; 12 String[] arg5_4 = new String[] { "-m", "-n", "50" }; 13 14 String[] arg6 = new String[] { "-o", "11", "-m", "5", "50", "-n", "100" }; 15 String[] arg6_1 = new String[] { "-n", "100", "-o", "-m", "5", "50" }; 16 String[] arg6_2 = new String[] { "-n", "100", "-m", "5", "50", "-o" }; 17 18 String[] arg7 = new String[] { "-m", "5", "20", "-n", "100", "-c" }; 19 String[] arg7_1 = new String[] { "-m", "5", "50", "-n", "100", "-b" }; 20 21 String[] arg8 = new String[] { "-b", "1", "-o", "3", "-m", "5", "50", "-n", "100" }; 22 String[] arg8_1 = new String[] { "-c", "1", "-o", "3", "-m", "5", "50", "-n", "100" }; 23 String[] arg8_2 = new String[] { "-n", "100", "-m", "5", "50", "-d" }; 24 25 Command.main(arg4);// 缺乏題數值測試 26 Command.main(arg4_1); 27 Command.main(arg4_2);// 題數值過大測試 28 Command.main(arg4_3);// 缺乏題數測試 29 30 Command.main(arg5);// 缺乏數值範圍 31 Command.main(arg5_1);// 缺乏數值範圍上限測試 32 Command.main(arg5_2); 33 Command.main(arg5_3);// 缺乏數值範圍上下限測試 34 Command.main(arg5_4); 35 36 Command.main(arg6);// 操做符數值過大測試 37 Command.main(arg6_1);// 缺乏操做符數值測試 38 Command.main(arg6_2); 39 40 Command.main(arg7);// 乘除須要上界大於下界的平方 41 Command.main(arg7_1);// 括號須要操做符數大於1 42 43 Command.main(arg8);// 輸入非法測試之b後有數字 44 Command.main(arg8_1);// 輸入非法測試之c後有數字 45 Command.main(arg8_2);// 輸入非法測試之無辨識字符 46 }
對於命令行可能出現的異常大概有13個:
設計圖以下:
咱們先從選擇出題或作題開始。
選擇出題則進入出題參數輸入界面。
利用MouseListener的mouseEntered(MouseEvent e)與setTitle(String);使得鼠標移到參數上,標題會有提示功能。
輸入完畢點擊確認後,由輸入的參數判斷是否有異常並提示直至無異常建立文件。
1 public class submitListener implements ActionListener { 2 public void actionPerformed(ActionEvent e) { 3 String m = "題數與數值上下限爲必填項,請按標題提示輸入正整數!"; 4 String m2 = "建立文件成功!"; 5 int n0, lower0, upper0, o0, c0, b0; 6 o0 = 1; 7 c0 = 0; 8 b0 = 0; 9 String o1 = ""; 10 try { 11 n0 = Integer.parseInt(n.getText()); 12 lower0 = Integer.parseInt(lower.getText()); 13 upper0 = Integer.parseInt(upper.getText()); 14 if (n0 < 1 || n0 > 10000) { 15 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "題數範圍爲1-10000", "提示", 16 JOptionPane.INFORMATION_MESSAGE); 17 return; 18 } 19 if (lower0 < 1 || lower0 > 100) { 20 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "下界範圍爲1-100", "提示", 21 JOptionPane.INFORMATION_MESSAGE); 22 return; 23 } 24 if (upper0 < 50 || upper0 > 1000) { 25 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "上界範圍爲50-1000", "提示", 26 JOptionPane.INFORMATION_MESSAGE); 27 return; 28 } 29 if (upper0 < (2 * lower0)) { 30 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "上界必須大於兩倍下界", "提示", 31 JOptionPane.INFORMATION_MESSAGE); 32 return; 33 } 34 } catch (NumberFormatException e2) { 35 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), m, "提示", JOptionPane.INFORMATION_MESSAGE); 36 return; 37 } 38 try { 39 o1 = o.getText(); 40 o0 = Integer.parseInt(o1); 41 } catch (NumberFormatException e2) { 42 if (!o1.equals("")) { 43 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "請輸入1-10的正整數或不輸入保持默認,默認爲1", "提示", 44 JOptionPane.INFORMATION_MESSAGE); 45 return; 46 } 47 } 48 if (c.isSelected()) { 49 c0 = 1; 50 } 51 if (b.isSelected()) { 52 b0 = 1; 53 } 54 if (o0 == 1 && b0 == 1) { 55 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "括號須要操做符數量大於1", "提示", 56 JOptionPane.INFORMATION_MESSAGE); 57 return; 58 } 59 if (c0 == 1 && upper0 < (lower0 * lower0)) { 60 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "乘除法須要上界數值大於下界的平方", "提示", 61 JOptionPane.INFORMATION_MESSAGE); 62 return; 63 } 64 createFile.fileCreate(n0, lower0, upper0, o0, c0, b0); 65 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), m2, "提示", JOptionPane.INFORMATION_MESSAGE); 66 System.exit(0); 67 } 68 }
選擇作題則先輸入作題人名字(在這裏建議使用英文,中文名字沒法很好的記錄)。
接着上傳文件,在這裏使用了txt文件過濾器,使之僅可上傳txt文件。
1 FileFilter filter = new FileNameExtensionFilter("Text file", "txt"); 2 JFileChooser fileChooser = new JFileChooser(); 3 fileChooser.setAcceptAllFileFilterUsed(false); 4 fileChooser.addChoosableFileFilter(filter); 5 FileSystemView fsv = FileSystemView.getFileSystemView();
另外,出題與作題都統一爲utf-8編碼,免去執行文件編碼錯誤。
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"));
InputStreamReader read = new InputStreamReader(new FileInputStream(file), "utf-8");
上傳成功後開始計時作題,並於最後結果中顯示用時。
通過後面JTextPane控件的啓發,我考慮到出題時題目長度有長短,爲了更加美觀顯示,應該須要自動換行,我一樣採用了HTML編輯文本的想法,作出改進。
1 public static void JlabelSetText(JLabel jLabel, String longString) throws InterruptedException { 2 StringBuilder builder = new StringBuilder("<html>"); 3 char[] chars = longString.toCharArray(); 4 FontMetrics fontMetrics = jLabel.getFontMetrics(jLabel.getFont()); 5 int start = 0; 6 int len = 0; 7 while (start + len < longString.length()) { 8 while (true) { 9 len++; 10 if (start + len > longString.length()) 11 break; 12 if (fontMetrics.charsWidth(chars, start, len) > jLabel.getWidth()) { 13 break; 14 } 15 } 16 builder.append(chars, start, len - 1).append("<br/>"); 17 start = start + len - 1; 18 len = 0; 19 } 20 builder.append(chars, start, longString.length() - start); 21 builder.append("</html>"); 22 jLabel.setText(builder.toString()); 23 }
計時方面我本來採用秒數計時,後來考慮到當作題時間較長時,秒數很難清晰明確的表達,因此改用了 hh:mm:ss 法顯示。
1 public static String getTimeStrBySecond(long second) { 2 if (second <= 0) { 3 return "00:00:00"; 4 } 5 int hours = (int) second / HOUR_SECOND; 6 if (hours > 0) { 7 8 second -= hours * HOUR_SECOND; 9 } 10 int minutes = (int) second / MINUTE_SECOND; 11 if (minutes > 0) { 12 second -= minutes * MINUTE_SECOND; 13 } 14 return (hours > 10 ? (hours + "") 15 : ("0" + hours) + ":" + (minutes > 10 ? (minutes + "") : ("0" + minutes)) + ":" 16 + (second > 10 ? (second + "") : ("0" + second))); 17 }
自動換行處理與秒數轉換被我寫入新類——dataDeal類中。
最終作完題目後除了顯示用時,還顯示題數、分數、錯題以及該題正確答案,非首次用戶會顯示歷史分數以及最高分數。
本來該部分使用了JTextArea控件,但學姐建議正確答案部分對齊顯示會更加美觀,並提出了C#中的ListView控件,但很遺憾,Java中彷佛並無。JTextArea控件是純文本顯示,很難作到不一樣的對齊方式,因此我刪除了該類。通過多方學習比較,我最終選擇了JTextPane控件,該控件簡單易用,可將文本顯示爲HTML文本,大大提升了編輯的樣式性。我最終採起了表格法對齊,另外對重點突出的地方加粗變紅顯示,達到強調與必定視覺衝擊效果,可從後文看到對比圖。
1 String text = "<p style='font-family:楷體; font-size:19'>" + name + " 本次用時<span style='color:red'><strong> " 2 + dataDeal.getTimeStrBySecond(spentTime) + " </strong></span>,得分<span style='color:red'><strong> " 3 + goal + " </strong></span>分。<br>"; 4 if (size0 == 0) { 5 text += "你總共答了<span style='color:red'><strong> " + size 6 + " </strong></span>道題,並所有答對!<span style='color:red'><strong>恭喜!</strong></span></p>"; 7 } else { 8 text += "你總共答了<span style='color:red'><strong> " + size 9 + " </strong></span>道題,答對<span style='color:red'><strong> " + size1 10 + " </strong></span>道,答錯<span style='color:red'><strong> " + size0 11 + " </strong></span>道,分別爲:</p><p><table border=0>"; 12 for (int i = 0; i < (size0 * 2); i++) { 13 text += "<tr><td style='font-family:楷體; font-size:19'><strong>" + wrong.get(i++) 14 + " </strong></td><td width='180' style='font-family:楷體; font-size:19;color:red'><strong> " 15 + wrong.get(i) + "</strong></td></tr>"; 16 } 17 } 18 text += "</table></p>"; 19 text += "<p style='font-family:楷體; font-size:19'>" + createFile.record(name, goal) + "</p>"; 20 21 JTextPane textarea = new JTextPane(); 22 textarea.setContentType("text/html"); 23 textarea.setText(text); 24 textarea.setEditable(false); 25 JScrollPane textAreascrollPane = new JScrollPane(textarea); 26 add(textAreascrollPane, BorderLayout.CENTER);
如圖所示
在界面模塊選擇出題輸入參數以後調用fileCreate類,再由fileCreate類調用計算模塊,建立result.txt
在界面模塊選擇作題輸入名字、上傳文件、作題。作題時調用計算模塊的stack類計算判斷正確性,記錄錯題。最終結果由計算模塊中的fileCreate類的record(String name, int goal)記錄,由界面模塊顯示。
實現的功能大體有12個,而且爲了提升用戶體驗,修改了圖標並增長了背景,將操做符數修改成下拉框選擇,默認選擇爲1,避免輸入非數字錯誤:
出題參數輸入(先後對比圖)
輸入參數有誤提醒(見第七點異常)
生成文件
記錄用戶
上傳文件(只容許txt文件)
判斷文件是否爲空或非練習題
計時
一道一道作題而且題目過長時自動換行
評分
根據學姐給的建議作出了修改,如下爲先後對比圖,正確答案對齊,使之更加美觀。另外我修改了作題時間的顯示形式,這樣當作題時間較長時能夠更加清晰的看出時間狀況。而作題時間、得分狀況、錯題與正確答案皆加粗甚至標紅,使之更加顯眼,提升用戶體驗。
記錄歷史分數與最高分數
咱們先一塊兒分析了需求與功能的實現,並提出了一些有實質性的方法,並確認數據的傳遞方式。再分析各自的我的項目代碼,指出了雙方優劣性,在綜合考慮選擇基礎代碼加以改進。
咱們根據本身較爲擅長的方面分工,如相對之下,我對gui較爲熟悉,而她對字符串處理較爲熟悉,則我負責界面展現而她負責命令行的分析。各自寫完以後咱們再複審雙方代碼,對代碼不理解之處詢問並補充註釋,以及對雙方異常狀況補充。最後在一塊兒整合雙方代碼,使之成爲完整項目。
在此過程當中咱們互相幫助、互相學習、能力上獲得互補,而代碼和產品質量提升,有效地減小bug而且考慮到更多方面的狀況。有兩臺電腦能夠測試程序效果,如她的電腦比我小,個人gui顯示不一樣,她的部分算式被遮擋,最終我選擇了將按鈕部分的面板設爲透明,解決了這個問題。
不足之處在於隊友之間的進度相互影響,不一樣的代碼風格之間的磨合也花費了必定時間。
雙方優缺點:
莊莉 | 王璐瑤 | |
優勢 | 認真細心,有責任心 |
不辭辛苦 |
代碼能力高 |
對字符串以及字符串數組的處理十分熟練 |
|
動手能力強 |
頗有想法,有好點子 |
|
缺點 | 有時候對於小問題過於鑽牛角尖 |
因生病而不在狀態,沒注意到比較細的地方,時間較少 |
PSP |
任務內容 |
實際完成須要的時間(min) |
Planning |
計劃 |
0.5 |
Estimate |
估計這個任務須要多少時間,並規劃大體工做步驟 |
0.5 |
Development |
開發 |
53.25 |
Analysis |
需求分析 (包括學習新技術) |
0.5 |
Design Spec |
生成設計文檔 |
0.25 |
Design Review |
設計複審 (和同事審覈設計文檔) |
0.25 |
Coding Standard |
代碼規範 (爲目前的開發制定合適的規範) |
0.25 |
Design |
具體設計 |
1 |
Coding |
具體編碼 |
40 |
Code Review |
代碼複審 |
1 |
Test |
測試(自我測試,修改代碼,提交修改) |
10 |
Reporting |
報告 |
9 |
Test Report |
測試報告 |
8 |
Size Measurement |
計算工做量 |
0.5 |
Postmortem & Process Improvement Plan |
過後總結, 並提出過程改進計劃 |
0.5 |
本次結對編程真的讓我學到不少知識,尤爲是各類操做,就像上一篇博客的連接同樣,我查了許許多多這樣的連接,學習了一種有一種的方法,與隊友配合,完成了此次項目。而每次寫博客,都能從新總結個人思路,受益良多。
雖然真的很辛苦,但能作出來也就夠了。
如下部分因爲時間與精力關係,咱們小組並無完成,僅提供思路參考,有想法的同窗可加以嘗試。
附加題多語言思路參考:程序國際化
https://blog.csdn.net/zhuxinquan61/article/details/51540806
http://www.javashuo.com/article/p-gdfjqelb-me.html
思路注意點參考: