MathExam小學一二年級計算題生成器V1.0
阿新 • • 發佈:2018-09-12
post date() date 而且 目標 任務 準備工作 void 內心
MathExam小學一二年級計算題生成器v1.0
一、預估與實際
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | ||
? Estimate | ? 估計這個任務需要多少時間 | 880 | 1540 |
Development | 開發 | ||
? Analysis | ? 需求分析 (包括學習新技術) | 60 | 100 |
? Design Spec | ? 生成設計文檔 | 20 | 20 |
? Design Review | ? 設計復審 | 10 | 20 |
? Coding Standard | ? 代碼規範 (為目前的開發制定合適的規範) | 20 | 30 |
? Design | ? 具體設計 | 60 | 90 |
? Coding | ? 具體編碼 | 300 | 500 |
? Code Review | ? 代碼復審 | 10 | 30 |
? Test | ? 測試(自我測試,修改代碼,提交修改) | 300 | 600 |
Reporting | 報告 | ||
? Test Repor | ? 測試報告 | 60 | 100 |
? Size Measurement | ? 計算工作量 | 10 | 20 |
? Postmortem & Process Improvement Plan | ? 事後總結, 並提出過程改進計劃 | 30 | 30 |
合計 | 880 | 1540 |
二、需求分析
我通過在網絡搜索的方式了解到,小學一年級數學有如下的幾個特點:
- 特點1:一年級數學只有加減法。
- 特點2:只有三位數以下的加減。
- 特點3:得出的結果不能為負數,因此當式子為減法式子時,前面的數字要小雨後面的數字。
- 特點4:二年級數學有加減乘除。
- 特點5:二年級數學有余數。
- 特點6:二年級數學除法的除數只有個位數。
經過分析,我認為,這個程序應當:
- 使用的數字應為[0,100)
- 除數的數字應[1,10)
三、設計
1. 設計思路
- 根據題目要求,最終需要寫入文本out.txt中,因此要先創建文本。
- 數字需要隨機得出,因此需要簡歷隨機數。
- 隨機出來的式子需要寫入文本,因此需要多個數組進行存儲。
- 答案需要的格式為“等式+答案”,並且還需要判斷符號以及是否有余數,所以需要if{} else if{}進行判斷。
需要寫入文本out.txt,所以需要BufferedWriter( )和循環,將數組裏的數據一 一寫入文本中。- 文本末尾需顯示當前時間,因此創建Date,提取當前系統時間。
2. 實現方案
- 準備工作:先在Github上創建倉庫,克隆到本地...
- 技術關鍵點:
- 數組會越界,從而導致程序無法正常運行,因此循環時需要註意循環體是否達到要求,是否有問題。
- 使用隨機數Random( )時,需要註意隨機數生成範圍,比如除數的範圍只有【1-9】
- 當式子為減法時,減數要等於或小於被減數。
- 使用 BufferedWriter( )將存入數組的數據一一輸入文本 out.txt 裏面。
- 使用正則表達式、Pattern、Matcher判斷輸入參數是否達標,不達標則提示重新輸入,並給予格式。
- 使用 DateFormat( )獲取系統當前時間。
四、編碼
請說明你如何按照設計思路進行編碼,並記錄你在開發中遇到的問題,與解決過程
1. 調試日誌
記錄編碼調試的日誌,請記錄下開發過程中的 debug 歷程
- 在for循環中,存放數據的數組因為循環體出錯,反復循環多次,導致越界,是程序無法正常運行。最後通過system.out.println打印出數組,判斷出循環問題。
- 在寫入正則表達式之後,關於Boolean的判定,一開始使用的是 matcher.find(),後來發現只要數據帶有相關的數字就會通過檢驗,因此改換成matcher.matches() ,成功將參數範圍以及類型進行限定。
- 當參數只寫入一個的時候,程序出現問題,使用args.length判斷輸入參數的長度,再傳參時,如果args.length==1則默認年級為1年級。
2. 關鍵代碼
請展示一段程序的關鍵代碼,並解釋代碼的作用
- 通過main函數中String[] args的參數,進行正則表達式的判斷,最後傳入create()方法內。
- count表示要生成的題數,grade表示對應的年級。
- 使用random()隨機生成數字。
public static void create(int count,int grade) {
Date date = new Date();
DateFormat dt = DateFormat.getDateTimeInstance();
dt.format(date);
File file = new File ("out.txt");//創建文本
FileWriter fw=null;
try {
fw = new FileWriter(file);
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
BufferedWriter bw = new BufferedWriter(fw);
int first=0,symbol=0,second=0,mark=0,w=0;
int [] an=new int[count];//創建數組,用於存儲數據,存儲答案。
int [] bn=new int[count];//存儲第一個數字,式子的第一個數;
int [] cn=new int[count];//存儲第二個數字,用於判斷符號;
int [] dn=new int[count];//存儲第三個數字,式子的第二個數
int [] en=new int[count];//存儲余數;
Random r =new Random();
while(w <count) {
if(mark==0) //判斷題號是否需要更新,若需要則輸入題號。
{
try {
bw.write(String.valueOf("("+ (w+1) +") "));
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
for(int i=0;i<4;i++)//循環四次,隨機生成三個數。並在第四次進行符號判斷,最後在文本輸入式子。
{
if(i==0)
{
int number = (int)Math.floor((r.nextDouble()*100.0));//生成式子的第一個數
first=number;
bn[w]=first; //將式子的數字存入數組中,方便之後的提取
}
else if(i==1)
{
if(grade==1)
{
int number = (int)Math.floor((r.nextDouble()*2.0));//生成第二個數字,用於判斷符號
symbol=number;
}
else if(grade==2)
{
int number = (int)Math.floor((r.nextDouble()*4.0));//生成第二個數字,用於判斷符號
symbol=number;
}
cn[w]=symbol;//將式子的數字存入數組中,方便之後的提取
}
else if(i==2)
{
if(symbol==3)
{
int number = 1+(int)Math.floor((r.nextDouble()*10.0));//生成第三個數字
second=number;
}
else
{
int number = 1+(int)Math.floor((r.nextDouble()*100.0));//生成第三個數字
second=number;
}
dn[w]=second;//將式子的數字存入數組中,方便之後的提取
}
else if(i==3)
{
en[w]=0;//輸入余數
if (symbol==0)//判斷符號,0為+號,1為-號,2為×號,3為÷號
{
try {
bw.write(String.valueOf(" "+ first+ " + " +second+" = "));//輸入式子
an[w]=first+second;//將答案存儲在數組an中
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
else if((symbol==1))
{
if(first-second < 0)
{mark=1;break;}
try {
bw.write(String.valueOf(" "+ first+ " - " +second+" = "));//輸入式子
an[w]=first-second;//將答案存儲在數組an中
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
else if((symbol==2))
{
try {
bw.write(String.valueOf(" "+ first+ " × " +second+" = "));//輸入式子
an[w]=first*second;//將答案存儲在數組an中
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
else if((symbol==3))
{
try {
en[w]=first % second;//將余數存入數組en中
bw.write(String.valueOf(" "+ first+ " ÷ " +second+" = "));//輸入式子
an[w]=(int)(first/second);//將答案存儲在數組an中
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
mark=0;//證明式子成功寫入,題號需要更新。
w++;
}
}//內循環結束
if(mark==0)//判斷式子是否成功寫入,如果成果則執行換行。
try {
bw.newLine();
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}//while循環結束。
3. 代碼規範
請給出本次實驗使用的代碼規範:
- 第一條:代碼中的變量名不能以下劃線開始也不能以下劃線結束。
- 第二條:代碼中的命名嚴禁使用拼音與英文混合,更不許使用中文命名。
- 第三條:常量命名全部大寫,單詞鍵用下劃線隔開,力求語義表達完整,不要嫌名字長。
- 第四條:類型與中括號緊挨相連來定義數組。
- 第五條:杜絕完全不規範的縮寫,避免忘文不知義。
- 第六條:第四條:不要使用一個常量類維護所有常量,按常量功能進行歸類,分開維護。並人工檢查代碼是否符合規範
五、測試
請思考並記錄你認為必要的測試點,並記錄測試用例與測試結果
參數個數 | 測試用例 | 結果 |
---|---|---|
一個參數 | java MathExam6360 10 | 運行正常 |
java MathExam6360 0 | 提示錯誤,需重新輸入 | |
java MathExam6360 00001 | 提示錯誤,需重新輸入 | |
java MathExam6360 a | 提示錯誤,需重新輸入 | |
java MathExam6360 10000 | 提示錯誤,需重新輸入 | |
java MathExam6360 -1 | 提示錯誤,需重新輸入 | |
java MathExam6360 0.1 | 提示錯誤,需重新輸入 | |
2個參數 | java MathExam6360 10 2 | 運行正常 |
java MathExam6360 10 20 | 提示錯誤,需重新輸入 | |
java MathExam6360 10 a | 提示錯誤,需重新輸入 | |
java MathExam6301 d 2 | 提示錯誤,需重新輸入 | |
java MathExam6301 0001 2 | 提示錯誤,需重新輸入 | |
java MathExam6301 100 0.1 | 提示錯誤,需重新輸入 | |
java MathExam6360 10 | 運行正常 |
六、總結
請總結過程中的教訓和經驗,思考
- 在寫代碼的過程中,每功課一次目標,其實內心是很歡喜的,因為這代表著我在攻克這目標之前所用的時間都得到了相應的回報,我的水平並不高,因此可能功課每一步的時間花費的比其他人都要長,不過我也確實在這次的過程中學到了一些東西,嚴格來說其實不算是學到,而是把上學期所學過的,所用過的進行了一次鞏固。當然水平不足的我少不了翻看曾經的PPT、作業以及上網查詢某一些函數的用法。
- 由於水平不足,其實我的代碼有著冗余,還是在同學的指導下,發現了其中一些代碼冗余的地方。而且剛開始決定敲代碼時,並沒有程序進行相應規劃以及設計,屬於想到什麽就寫什麽,因此遇到了問題時,總是手忙腳亂的找錯誤。倒是養出了給代碼註釋的習慣,方便之後出錯可以迅速查找。
- 相比於其他人,我確實是自愧不如,敲代碼的時間四五天有余,雖然最後敲出來了成果,但是卻依然比不得其他同學,還有許多需要改進的地方。使用正則表達式限制了輸入參數的類型以及範圍,最開始使用的matcher.find()的boolean判斷,卻總能被判斷正確,即使輸入參數不對。之後再同學的建議下修改成matcher.matche()的boolean判斷,總算成功限定了參數類型和範圍。
- 這一次的作業,讓我受益良多,即使代碼看多了腦殼會疼,不過在完成目標後,那種可以令人上癮的感覺,實在是欲罷不能,這或許是我堅持那麽久去推敲代碼的動力吧。
MathExam小學一二年級計算題生成器V1.0