這個作業的要求來自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2232。
我結對同伴的姓名:郭曉瑩 學号:201606120105 部落格:https://www.cnblogs.com/kunnkkk/p/9809435.html
本次作業的代碼在我的同伴郭曉瑩的github位址:https://github.com/kunnkkk/16rg。
開發環境:IntelliJ Idea。
我們選取了5個方向,分别為:
- 使用者答題結束以後,程式可以顯示使用者答題所用的時間;
- 使用者可以選擇出題的個數(最多不能超過5個題目),答題結束可以顯示使用者答錯的題目個數和答對的題目個數;
- 程式可以出單個整數階乘的題目:如:4!=24;
- 程式可以設定皮膚功能,可以改變界面的顔色即可;
- 程式可以設定答題時間,時間設定為整數,機關為秒,最大不能超過120秒,若超過了答題時間未答題,則提示:時間已到,不能答題。
分工:我負責Java使用者界面設計以及第2、3、4方向的實作,我的同伴負責第1、5方向的實作以及調試、修改程式的一些小錯誤。除此之外,我們還嘗試制作了web版本的系統,我的同伴運用JavaScript的知識對本次作業進行了網頁設計和制作基本要求、答題數目選擇和答案顯示及階乘的功能,而我負責運用JavaScript知識進行設定答題時間和倒計時功能的實作。本次作業最主要的檔案是CalculationsSystem!另外一個是我們額外做的!助教可以打開兩個檔案進行運作。
第一部分:需求分析
從個人項目出發,将程式改裝成一個單機帶使用者界面(不是控制台)的程式,這個程式最基本要達到:
- 生成題目,單個題目最多不能超過4個運算符,操作數小于100;
- 使用者可以輸入答案;
- 若使用者輸入答案正确,則提示正确;若答案錯誤,則提示錯誤,并要提示正确答案是多少。
第二部分:概要設計
(1)Java Class類算法設計說明:
public class FourCalculations {...}
随機生成最多不能超過4個運算符,操作數小于100的單個四則運算式,并且能進行正确答案的計算。
public class FactorialCalculations {...}
設定随機數種子随機産生一個範圍在1~20的數字,并且能進行正确的階乘運算。
public class JudgeLabel extends JLabel {...}
建立一個JudgeLabel類用于顯示圖示“√”和“×”,若使用者在答案區輸入的答案正确,則圖示為“√”,若使用者在答案區輸入的答案錯誤,則圖示為“×”。
public class Window extends JFrame implements Runnable {...}
設計非控制台的使用者界面,初始化各類按鈕,主函數就在這個類裡面,程式的執行從主函數裡的代碼語句開始。
(2)Java Class類之間的調用關系:

第三部分:詳細設計
(1)
public int generateCorrectAnswer(List<String> operators, List<Integer> operations) {
//周遊運算符容器,完成乘除運算
for (int i = 0; i < operators.size(); i++) {
String operator = operators.get(i);
if (operator.equals("*") || operator.equals("/")) {
operators.remove(i); //乘除符号将其從集合中移除
int operateLeft = operations.remove(i); //拿運算符左側的數字
int operateRight = operations.remove(i); //拿運算符右側的數字
if (operator.equals("*"))
operations.add(i, operateLeft * operateRight);
else
operations.add(i, operateLeft / operateRight);
i--; //運算符容器的指針回到原來的位置,防止跳過下一個運算符
}
}
//周遊運算符容器,完成加減運算,當運算符容器為空時,運算結束
while (!operators.isEmpty()) {
String operator = operators.remove(0);
int operateLeft = operations.remove(0);
int operateRight = operations.remove(0);
if (operator.equals("+"))
operateLeft = operateLeft + operateRight;
else
operateLeft = operateLeft - operateRight;
operations.add(0, operateLeft);
}
return operations.get(0);
}
這個方法的作用是計算四則運算式的正确結果,首先周遊存儲在operators清單中的所有運算符,當有乘除時,就取出operations清單中位于此符号的左右兩側的操作數,然後進行四則運算。計算結束後要将此運算符和操作了的兩個操作數從清單中移除,運算符容器的指針回到原來的位置。周遊完所有的乘号和除号後,再周遊operators清單中的所有加号和減号。
(2)
//随機産生的階乘數字
public int generateFormula() {
Random random = new Random();
int num = random.nextInt(19)+1;
//計算階乘結果
int result = 1;
for (int i = 1; i <= num; i++) {
result*= i;
}
correctAnswerList.add(String.valueOf(result));
return num;
}
這個方法的作用是産生一個範圍在1~20的随機數,進行階乘運算,将最終得到的int整型運算結果result轉換成String字元串類型。
(3)
private void markingPapers() {
if(fourCalculation == true) {
for (int i = 0; i < answerArea.length; i++) {
//System.out.println("answer:"+fourCalculations.correctAnswerList.get(i));
//System.out.println("input:"+answerArea[i].getText());
if (answerArea[i].getText().equals(fourCalculations.correctAnswerList.get(i))) {
judgeLabel[i].setImageUrl("./FourOperations/src/main/img/right.png"); // 正确,顯示“√”圖示
numT++;
}
else {
//answerArea[i].setText("錯");
judgeLabel[i].setImageUrl("./FourOperations/src/main/img/error.png"); // 錯誤,顯示“×”圖示
answerArea[i].setText(fourCalculations.correctAnswerList.get(i)); //将使用者輸入的錯誤答案修改為正确答案
numF++;
}
}
}
else{
for (int i = 0; i < answerArea.length; i++) {
//System.out.println("answer:"+fourCalculations.correctAnswerList.get(i));
//System.out.println("input:"+answerArea[i].getText());
if (answerArea[i].getText().equals(factorialCalculations.correctAnswerList.get(i))) {
judgeLabel[i].setImageUrl("./FourOperations/src/main/img/right.png"); // 正确,顯示“√”圖示
numT++;
}
else {
//answerArea[i].setText("錯");
judgeLabel[i].setImageUrl("./FourOperations/src/main/img/error.png"); // 錯誤,顯示“×”圖示
answerArea[i].setText(factorialCalculations.correctAnswerList.get(i)); //将使用者輸入的錯誤答案修改為正确答案
numF++;
}
}
}
}
這個方法主要是進行答案判斷的。首先判斷使用者進行的是四則運算操作還是階乘運算操作,接着從答題區answerArea[]中取出使用者輸入的答案與标準正确答案進行對比,若相同,則在圖示區顯示“√”,若不相同,則表示使用者計算結果不正确,圖示區顯示“×”,并且将答題區使用者原先輸入的答案修改為正确答案。
(4)
public void run() { // 完成時間計時
int second = 0;
int minute = 0;
String time;
timeLabel.setText("用時 00:00"); // 初始化用時
while (true) {
try {
Thread.sleep(1000); // 按時間設定
} catch (InterruptedException e) {
e.printStackTrace();
}
second++;
if (second == 60) {
second = 0;
minute++;
}
if (minute < 10) {
time = "用時 " + "0" + minute + ":";
} else {
time = "用時 " + minute + ":";
}
if (second < 10) {
time = time + "0" + second;
} else {
time = time + second;
}
if (minute == 2) { // 如果時間到120s,使用者還未答完題,提示資訊
JOptionPane.showMessageDialog(this, "時間已到,不能答題!");
submit();
return;
}
timeLabel.setText(time);
}
}
這個方法是設定時間線程顯示使用者答題時間,若使用者在120s時仍未答題結束,則彈出提示框提示使用者“時間已到,不能答題!”。
(5)
// 背景色按鈕
JButton changeButton = new JButton("背景色");
changeButton.setBounds(startX, startY+step*5, width, height);
changeButton.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
Color color = JColorChooser.showDialog(outPanel, "背景色", outPanel.getBackground()); // 彈出顔色界面供使用者自由選擇背景色
if (color != null) {
outPanel.setBackground(color);
}
}
這個方法是設定使用者界面的背景色,當使用者單擊“背景色”按鈕時,會顯示一個顔色選擇界面,使用者選擇合适的背景色之後單擊“确認”按鈕,背景色就會改變。
第四部分:調試報告
(1)問題:
一開始我們兩個成員都沒有仔細看清楚作業題目的基本要求,于是就選取了四個方向在第一次作業的基礎上進行完善修改。在我們大概要完成作業時,多虧一位同學發現我們采用Visual C++進行程式設計的,于是提醒我們用這個軟體無法自行建立非控制台的使用者界面,而作業明确要求是“非控制台”。是以,經過商量我們決定采用Idea進行Java程式設計,重頭開始。
在進行使用者界面設計時,因為我設定的變量參數不當,導緻許多按鈕出現重合以及按鈕排列順序混亂等問題。經過我同伴的耐心指點,我才知道如何正确選取恰當的參數,并成功修正過來。其次,在做本次作業之前我還未運用Java語言進行過界面皮膚功能設定,是以剛開始是很迷茫的,詢問了班上幾個實力比較強的朋友也未能成功解決此問題。于是我便上網查資料,通過浏覽網友的一些代碼,再結合JDK文檔我才發現其實改變背景色是很容易的。Java本身提供了JColorChooser.showDialog()類和方法,通過調用此方法便可以實作選擇背景色和修改背景色的功能。
最後,是我在運作程式時發現當使用者選擇階乘運算,單擊“送出”按鈕後,在圖示區無法顯示“√”和“×”,也就是程式無法判斷使用者輸入結果和标準答案是否一緻。經過調試代碼我發現是因為使用者輸入的值我将它放在JTextField類的setText()方法中,也就是說使用者輸入的結果是儲存在String類型中的,而階乘運算的正确運算結果是儲存在int類型中,兩個類型不一樣的數無法進行比較。于是我在FactorialCalculations類中添加correctAnswerList.add(String.valueOf(result))代碼,将階乘運算的正确結果轉化成String類型,問題得以解決。
(2)程式調試結果:
使用者界面:
使用者單擊“背景色”按鈕,改變界面顔色:
當使用者在空白文本框中輸入的題目數大于5時,文本框出現提示資訊。當使用者單擊文本框時,文本框提示資訊清空,使用者可重新輸入題目個數:
使用者選擇“目前:四則運算”,單擊“開始”按鈕,進入答題界面,程式開始計時:
當使用者輸入答案,單擊“交卷”按鈕時,程式會判斷使用者輸入是否正确:
當時間達到120s時,使用者仍未單擊“交卷”按鈕,程式會出現提示框:
使用者選擇“目前:階乘”,單擊“開始”按鈕,進入答題界面,程式開始計時:
web版首頁選擇答題數目與類型:
web版選擇題目數量進入簡單運算,120秒倒計時開始,輸入結果:
web版選擇題目數量進入階乘運算,120秒倒計時開始,輸入結果對比後判斷對錯和計算用時,确定傳回首頁:
web版答題超過120秒時按确認傳回首頁:
第五部分:統計表與總結
(1)統計表:
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
Planning | 計劃 | 420 | |
· Estimate | 估計這個任務需要多少時間 | ||
Development | 開發 | ||
· Analysis | 需求分析 (包括學習新技術) | 30 | 15 |
· Design Spec | 生成設計文檔 | ||
· Design Review | 設計複審 | 20 | 40 |
· Coding Standard | 代碼規範 | 120 | |
· Design | 具體設計 | 35 | |
· Coding | 具體編碼 | 400 | |
· Code Review | 代碼複審 | 100 | 60 |
· Test | 測試(自我測試,修改代碼,送出修改) | ||
Reporting | 報告 | 125 | |
Test Report | 測試報告 | ||
·workload | 計算工作量 | ||
·correction | 并提出過程改進計劃 |
(2)結對工作的照片:
(3)結對程式設計項目總結:
在這次結對程式設計項目設計中,我和我的同伴都遇到了不少困難,但是在我們的堅持和虛心請教中都得到順利解決。本次項目設計中,我發現理論必須和實踐相結合,才能真正學會軟體設計,才能完成一個課題。在這次設計中我查閱了網上許多關于Java程式設計的知識,反複看了JDK文檔很多次,也參考了其他學生的相關部落格,總結了自己與他們的經驗,快速掌握了本次結對程式設計項目設計的整體思路。在完成這個項目的過程中,加深了我對Java語言知識的充分運用以及了解,使自己的程式設計水準得到了一定的提高,在處理問題方面的能力也提高了。
更重要的是,我和我的同伴為了提升自我能力,在時間充裕的情況下進行了web版本項目設計,但是因為能力和時間有限,有關功能的子產品沒有來得及實作。但是在她制作網頁的過程中我跟着她學到了很多前端的知識,和同伴在本次合作中十分愉快。我們合理分工,互相幫助,沒有出現很大的分歧,也沒有互相推卸責任等,這次合作讓我獲益匪淺,收獲知識,更收獲了友誼。
我們在此項目上實作了最多四個運算符的四則運算操作,也就是針對助教在我第四次作業中提出的問題而進行完善。這個程式還存在諸多不足之處----在現實中許多功能現在還沒有實作,還有不少需要進一步完善的操作等等,可能是因為經驗不足,對問題預期不夠等一些不可預見的原因所緻,這些都是我和我同伴在接下來的學習和實踐中要汲取的教訓。