結對編程項目—四則運算 第二週 總體總結

20175214林郅聰 結對編程項目—四則運算 第二週 總體總結

1、需求分析

1.題目要求:

  • 實現一個命令行程序,要求:java

    • 自動生成小學四則運算題目(加、減、乘、除)git

      • 支持整數
      • 支持多運算符(好比生成包含100個運算符的題目)
      • 支持真分數
    • 統計正確率express

2.擴展需求

  • 能夠實現多語言,包括簡體中文,繁體中文和英文
  • 生成題目去重
  • 輸入題目到文件,從文件中讀取題目並判斷對錯

3.深度需求

本次結對項目要求完成小學生的四則運算,除了題目中要求的內容外,還能夠包含如下方面編程

  • 進行難度更高的運算,好比嵌套運算或其餘運算符例如求方冪、求整、取餘等
  • 因爲是經過程序完成,在給出測試的正確率的狀況下能夠判斷正確率是否達到合格標準,若未達到則繼續進行直到達到標準爲止
  • 讓學生自由選擇題目難度,根據不一樣難度給出相應評價

2、設計思路

在開始本週任務前,我對咱們的程序進行了簡要的分析,和上週相比有以下的改變學習

  • 增長了真分數的運算,並控制分數的格式(在後面會有說明)
  • 給出了多語言的支持:簡體中文、繁體中文、英文
  • 生成了題目去重的功能:在原來的基礎上進行了適當的修改,由於當生成算式較短時比較容易重複,但這一部分的代碼還存在一些問題,目前只能判斷兩道題目是否徹底相同,不能排除1 + 22 + 1 這種重複的狀況

UML類圖

3、變更的代碼

  • 首先是分數的形式,選擇將分號「/」也當作隨即字符和加減乘除一塊兒隨機產生,而在中綴轉後綴運算式將分號的優先級設置爲僅低於有括號,這樣能夠區別分號「/」和除號「÷」
public int compareValue(char chi) {    
    int number = 0;    
    switch (chi) {        
        case '(':            
            number = 1;            
            break;        
        case '+':        
        case '-':            
            number = 2;            
            break;        
        case '*':        
        case '÷':            
            number = 3;            
            break;        
        case '/':            
            number = 4;            
            break;        
        case ')':            
            number = 5;            
            break;        
        default:            
            number = 0;            
            break;    
        }    
    return number;
}
  • 如何產生真分數?分數的產生很容易,那如何控制產生真分數呢?和其餘小組的同窗討論研究後發現他們的方式都不適合咱們,由於在產生算式用到的方法不一樣,分數的生成方式也存在差別,所以他們聲稱分數的方法並不適合咱們。在和結對夥伴討論後,咱們決定先產生分子,根據分子的範圍控制分母的大小
else if (rand == 0 && flag2 % 2 == 0 || flag5 % 3 == 0 && flag2 % 2 == 0    {                                        //插入數字                
    if(flag6==1)                     //當產生了分號時 
        n = num.GetNumber(a-n)+n;    //控制分號後面的數比分號前面的數大但不會超過給出的最大值
    else n = num.GetNumber(a);    
        q += n;    
        flag2++;    
        flag5 = 0;    
        countTotal++;
  • 接下來是真分數的產生和運算部分,關於這一部分,在編寫以前花了很長時間思考,由於分數在運算時涉及到了壓棧的問題,而在運算時若是將分子分母和分號分開壓棧那麼就失去了原本的意義,若是將分數控制爲字符串的形式進行壓棧操做,那麼以前的代碼須要所有重寫,最後在翻看教材的時候發現的書上第四章Example4_23中給出了一個有理數Rational類,能夠經過該類進行分數的運算,而這種方法也正適合咱們以前寫的程序。在對書上的例子進行少量修改後,應用到咱們的程序中
Rational div(Rational r)  { //除法運算    
    int a=r.getNumerator();    
    int b=r.getDenominator();   
    int newNumerator=numerator*b;    
    int newDenominator=denominator*a;    
    Rational result=new Rational();   
    if(a==0) {        
        System.out.println("該算式無解");        
        result.setNumerator(0);    
    }    
    else {        
        result.setNumerator(newNumerator);        
        result.setDenominator(newDenominator);    
    }    
    return result;
}
  • 簡要說明:這一部分的程序與書上基本相同,但因爲書上是控制輸入,所以不須要排除分母爲0的狀況,而咱們的程序中數字時隨機產生的,可能會在運算的過程當中產生了計算出的結果是0做爲了分母,所以須要控制這種狀況測試

  • 多語言選擇:在完成這一部份內容時,咱們選擇了用抽象類的方法,將每一種提示做爲一個抽象方法,三種語言做爲子類重寫其中的方法編碼

package CalculateSystem;
public abstract class Language {    
    public abstract String getQuestionNumber();    
    public abstract String getMaxNumber();    
    public abstract String getMaxOperator();    
    public abstract String getInputAnswer();    
    public abstract String getRight();    
    public abstract String getWrong();    
    public abstract String getRate();    
    public abstract String getContinue();   
    public abstract String getThanks();
}

下面是子類English中重寫的方法命令行

public class English extends Language {    
    public String getQuestionNumber() {        
        return "Enter the number of questions you want to do:";    
    }    
    public String getMaxNumber() {        
        return "Please enter the maximum number you want to operate:";   
    }    
    public String getMaxOperator() {        
        return "Please enter the length of the expression you want to operate:";    
    }    
    public String getInputAnswer() {        
        return "Enter your answer :(floating point)";    
    }    
    public String getRight() {        
        return "Congratulations! Your answer is right";    
    }    
    public String getWrong() {        
        return "Wrong answer! The correct answer is";    
    }    
    public String getRate() {        
        return "Test over! Your accuracy is";    
    }    
    public String getContinue() {        
        return "Do you want to continue? Please enter 1 to continue and 0 to exit";    
    }    
    public String getThanks() {        
        return "Test over, thanks for using!";    
    }
}
  • 題目去重:這一部分的代碼的功能 並不全面,只限於判斷兩道題目是否徹底相同,並不能判斷其中是否含有沒有意義的重複
GetQuestion q = new GetQuestion();
String question1 = q.get(maxnum,maxop);
if(question1.equals(question2)) {                     //判斷時候和前一題是否相等,相等則不計入次數,從新產生等式    
    i--;        continue;
}
System.out.println(question1);
question2 = question1;                                 //不相同則把該題目賦值給question2用於和下一題進行比較

4、遇到的問題

  • 開始時我和夥伴在考慮如何生成真分數的同時,也在考慮如何保證過程當中也都控制真分數,後來發現沒有必要糾結這個問題,只須要控制在生成時生成簡單的真分數,例如13/15 便可,由於在運算過程當中給存在括號優先級的問題,例如 (15*3+8)/16 並不須要在運算過程當中控制都是真分數
  • 在進行壓棧和彈棧運算時,將彈出的數轉化爲有理數時,發現第一個彈出的數老是會被第二個數覆蓋,在探討測試後發現是由於定義了一個變量num,他的做用是,當棧中的數不是運算符的時候,要將其放回。這個變量定義在了if-else 語句外,所以只有最開始初始化了變量,在運算過程當中一直使用後面的數覆蓋前面的數,所以彈出的兩個數會同樣,更該方法是將變量的初始化放在else語句中,每次判斷時,都要初始化,這樣不會對以前的產生影響。
while (token.hasMoreTokens()) {    
    temp = token.nextToken();    
    if (Isop(temp) == 1)//遇到操做符,彈出棧頂的兩個數進行運算    {        
        op2 = (Rational) stack.pop();        
        op1 = (Rational) stack.pop();//彈出最上面兩個操做數        
        result = cal(temp.charAt(0), op1, op2);//根據運算符進行運算        
        stack.push(result);//將計算結果壓棧    
    } 
    else {        
        Rational num = new Rational();        //每次從新初始化
        num.setNumerator(Integer.parseInt(temp));        
        stack.push(num);//操做數入棧    
    }
}
  • 產生分數時會產生 5/7/8 的形式,事實上這種分數產生的意義不大,咱們但願避免這種狀況,幾經嘗試後選擇在產生問題的類中再加flag變量進行控制

5、運行過程截圖




6、代碼託管

https://gitee.com/fzlzc/java2019/tree/master/src/CalculateSystem設計

7、對結對夥伴的評價

我以爲個人小夥伴很是棒,這周他主要負責添加真分數功能和語言包,這部分基本由他獨立完成,我只負責對接,最後拼接雖然有些磕磕絆絆,有許多沒有發現的bug錯誤,可是一一糾正檢驗,一塊兒討論學習的氛圍讓我以爲十分酣暢,並且成果仍是比較讓咱們滿意的,基本完成了預期,但願之後能夠繼續這樣快樂合做,快樂編程。3d

### 8、預估時間與實際時間

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃
•Estimate • 估計這個任務須要多少時間 570 815
Development 開發
• Analysis • 需求分析 (包括學習新技術) 30 40
• Design Spec • 生成設計文檔 30 30
• Design Review • 設計複審 (和同事審覈設計文檔) 20 40
• Coding Standard • 代碼規範 (爲目前的開發制定合適的規範) 20 60
• Design • 具體設計 20 25
• Coding • 具體編碼 360 500
• Code Review • 代碼複審 20 20
• Test • 測試(自我測試,修改代碼,提交修改) 30 50
Reporting 報告
• Test Report • 測試報告 20 20
• Size Measurement • 計算工做量 10 10
• Postmortem & Process Improvement Plan • 過後總結, 並提出過程改進計劃 10 20
合計 570 815
相關文章
相關標籤/搜索