1. 程式人生 > >MathExam小學一二年級計算題生成器V1.0

MathExam小學一二年級計算題生成器V1.0

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