练习5.1——四则运算 测试与封装

主程序





package com.h2;



import java.text.DecimalFormat;

import java.util.Scanner;

import java.util.regex.Pattern;

/*

 * 1.定制数量

 * 2.控制是否有乘除法

 * 3.控制数值范围

 * 4.定制真分数练习题

 * 5.校检用户输入

 * 6.输出答题正确率

 */

public class Main {

    public static int max = 10;// 控制算式个数

    public static String[] staticanser = new String[max];// 标准答案

    public static DecimalFormat decimal = new DecimalFormat("#.##");

    

    

    // 求最大公约数

    private static int calcMaxSubmultiple(int num1, int num2) {

        num1=Math.abs(num1);//防止负数时求不得最大公约数。

        num2=Math.abs(num2);

        int min = Math.min(num1, num2);

        int maxSubmultiple = 1;

        for (int i = min; i >= 1; i--) {

            if (num1 % i == 0 && num2 % i == 0)

            {

                maxSubmultiple = i;

                break;

            }

            

        }

        return maxSubmultiple;

    }

//主函数

    public static void main(String[] args) {

        

        char[] op = { ' ', '+', '-', '*', '/' };// 操作符

        int[] no = new int[4];// 操作符地址

        int useno = 0;// 控制操作符

        int n = 3;// 操作数个数(随机)

        int[] num1 = new int[10];// 操作数

        char opp;// 判断是否需要乘除法

        char real;// 判断是否需要真分数的题目

        int[] cs = { 1, 100 };// 数值范围

        String[] useranser = new String[max];// 用户输入的答案

        

        

        int f = 0;// 控制输出真分数的操作符

        int count = 0;// 统计答题正确的数量

        

        int s1 = 1;// 分子通分

        int ss1 = 1;// 分子通分

        int s2 = 1;// 分母通分

        int result = 0;// 分子计算

        int gys;// 最大公约数

        int ff = 0;// 分数除法,分子为0标志位

        int fff=0;//

        String zjfz = new String();// 最简分子

        String zjfm = new String();// 最简分母

        Pattern pattern = Pattern.compile("[0-9]*"); // 限定输入算式数量输入的必须是数字



        Scanner in = new Scanner(System.in);

         //定制要求 

        System.out.print("请输入需定制的算式数量(1-20):");// 1.定制数量

        do {

            String str = in.nextLine();

            if (pattern.matcher(str).matches()) {// 如果输入的是数字就执行

                max = Integer.parseInt(str);

                if(max<=20&&max>0)

                {

                    break;

                }

                else

                {

                    System.out.print("你输入的范围有误,请重新输入:");

                }

                

            } else {                                                                       

                System.out.print("你输入的不是数字,请重新输入:");

            }

        } while (true);



    

        System.out.print("是否需要乘除法(Y/N):");// 2.控制乘除参数

        do {

            opp = in.next().charAt(0);

            if (opp == 'Y' || opp == 'y') {

                useno = 4;

                break;

            } else if (opp == 'N' || opp == 'n') {

                useno = 2;

                break;

            } else {

                System.out.print("输入错误,请重新输入:");

            }

        } while (true);



        System.out.print("参数范围(eg:1,100):");// 3.控制数值范围

        String str = new String();

        int sr = 0;//判断循环结束

        in.nextLine();// 过滤掉上面.next()方面的回车。

        do {

            try {

                str = in.nextLine();

                String[] ss = new String[2];

                ss = str.split(",");

                cs[0] = Integer.valueOf(ss[0]);

                cs[1] = Integer.valueOf(ss[1]);

                sr = 1;

            } catch (Exception e) {

                System.out.print("输入格式错误,请重新输入:");

            }

        } while (sr != 1);





        System.out.print("是否增加真分数练习题(Y/N):");// 4.真分数题目

         do {

             real = in.next().charAt(0);

             if ( real == 'Y' || real == 'y') {

                 

                 break;

             } else if ( real == 'N' || real == 'n') {

                break;

             } else {

                 System.out.print("输入错误,请重新输入:");

             }

         } while (true);



         //----------------题目-----------------------

        System.out.println();

        System.out.println("                2014-2015学年度第一单元测试卷");

        System.out

                .println("班级:             姓名:             座号:          得分:                  ");

        System.out.println();

        System.out.println("一、请认真仔细地计算下面各题。(小数请保留小数点后两位)");

        System.out.println();

        Core c1=new Core();

        for (int i = 0; i < max; i++) {



            System.out.print("(" + (i + 1) + ") ");

            n = (int) (Math.random() * 4 + 2);// 2-5个操作数

            for (int j = 0; j < n; j++) {

                num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值

            }

            for (int k = 0; k < n - 1; k++) {

                no[k] = (int) (Math.random() * useno + 1);// 随机产生操作符

                if(no[k]==4&&num1[k+1]==0){

                    do{

                    num1[k+1]=(int) (Math.random() * (cs[1] - cs[0]) + cs[0]);//如果除号后为0,则重新取数。

                    }while(num1[k+1]==0);

                }

            }

            for (int h = 0; h < n; h++) {

                if (h != n - 1) {

                    if(num1[h]<0)

                    {

                        System.out.print("("+num1[h]+")");

                        System.out.print(op[no[h]]);

                    }

                    else{

                    System.out.print(num1[h]);

                    System.out.print(op[no[h]]);

                    }

                } else {

                    if(num1[h]<0)

                    {

                        System.out.print("("+num1[h]+")=");

                    }

                    else

                      System.out.print(num1[h] + "=");

                }

            }

            System.out.println();

            c1.calcute(num1, op, no, n);//计算答案

        }



        



        

        

        

        // 学生答题模块

        System.out.println("==================答题分割线=========================");

        for (int i = 0; i < max; i++) {

            System.out.print((i + 1) + ":");

            useranser[i]=in.next();

            if (useranser[i].equalsIgnoreCase(staticanser[i])) {

                count++;

            }

        }

        System.out.println("标准答案为:");

        for (int i = 0; i < max; i++) {

            System.out.println((i + 1) + ":" + staticanser[i]);

        }

        System.out.println("答题正确率为:" + String.valueOf(decimal.format(((float) count / (float) max) * 100))

                + "%");

        System.out.println("==================答题分割线=========================");



//真分数     

        if (real == 'Y' || real == 'y') {

            System.out.println("二、请计算下列真分数算式。(无法计算请填null)");

            System.out.println();

            for (int i = 0; i < max; i++) {

                System.out.print("(" + (i + 1) + ") ");

                for (int j = 0; j < 2; j++)// (第一个真分数)

                {

                    num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值

                    if (j == 1 ) {

                        while (num1[j - 1] >num1[j]||num1[j]== 0) {

                            num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值

                        }

                    }

                }

                for (int j = 2; j < 4; j++)// (第二个真分数)

                {

                    num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值

                    if (j == 3) {

                        while (num1[j - 1] >num1[j]||num1[j]== 0) {

                            num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值

                        }

                    }

                }



                for (int k = 0; k < 1; k++) {// 符号个数

                    no[k] = (int) (Math.random() * useno + 1);// 随机产生操作符

                }

                for (int h = 0; h < 4; h++) {// 2个真分数

                    if (h % 2 == 0)

                        System.out.print(("(" + num1[h] + "/"));

                    else if (h % 2 == 1) {

                        System.out.print(num1[h] + ")");

                        if (f < 1) {// 控制只输出一个操作符

                            System.out.print(op[no[f]]);

                            f++;

                        } else

                            System.out.println("=");



                    }

                }



                f = 0;

                //计算第二大题标准答案

                count=0;

                

            }



            // 答题模板

            System.out.println("==================答题分割线=========================");

            for (int i = 0; i < max; i++) {

                System.out.print((i + 1) + ":");

                useranser[i] = in.next();

                if (useranser[i].equals(staticanser[i])) {

                    count++;

                }

            }

            System.out.println("标准答案为:");

            for (int i = 0; i < max; i++) {

                System.out.println((i + 1) + ":" + staticanser[i]);

            }

            System.out.println("答题正确率为:" + String.valueOf(decimal.format(((float) count / (float) max) * 100))

                    + "%");

            System.out

                    .println("==================答题分割线=========================");

        }



    }

}

 

 1 将计算功能封装成Core类

 2 

 3 

 4 package com.h2;

 5 

 6 public class Core {

 7     int sign; // 累加运算时的符号

 8     float left, right;// 保存蹭结果

 9     int i=0;

10     float result;

11 public void  calcute(int[] num1,char[] op,int[] no,int n){

12     //一个算式中的所有数字num1,符号op,随机产生的符号下标no,随机产生的算式操作数个数n.

13     //  // 计算第一大题答案

14         for (int h = 0; h < n - 1; h++){

15         if((no[h]==4)&&(num1[h+1]==0)){

16         throw new ArithmeticException();

17         }

18         }

19             left = 0;

20             right = num1[0];

21             sign = 1;

22     for (int g = 0; g < n - 1; g++) {

23         switch (op[no[g]]) {

24         case '+':

25             left = left + sign * right;

26             sign = 1;

27             right = num1[g + 1];

28             break;

29         case '-':

30             left = left + sign * right;

31             sign = -1;

32             right = num1[g + 1];

33             break;

34         case '*':

35             right = right * num1[g + 1];

36             break;

37         case '/':

38             right = right / num1[g + 1];

39             break;

40         }

41     }

42      result=left + sign * right;

43     Main.staticanser[i] = String.valueOf(Main.decimal.format(left + sign * right));

44     i++;

45 }

46 

47 public float getResult(){

48     return this.result;

49 }

50 }

 

 1 根据助教提示做出测试类CoreTest

 2 

 3 

 4 package com.h1;

 5 

 6 import static org.junit.Assert.*;

 7 

 8 import org.junit.Assert;

 9 import org.junit.Test;

10 

11 import com.h2.Core;

12 

13 public class CoreTest {

14     @Test

15     public void testAdd() {// 加法

16         int n = 3;// 操作数个数

17         int[] num1 = { 1, 2, 3 };// 操作数

18         char[] op = { ' ', '+', '-', '*', '/' };// 操作符

19         int[] no = { 1, 1 };// 操作符下标

20         Core c = new Core();

21         c.calcute(num1, op, no, n);// 运算1+2+3

22         int r = (int) c.getResult();

23         System.out.println(r);

24         assertEquals(6, r);

25     }

26     

27     @Test

28     public void testJian() {// 减法

29         int n = 3;// 操作数个数

30         int[] num1 = { 1, 2, 3 };// 操作数

31         char[] op = { ' ', '+', '-', '*', '/' };// 操作符

32         int[] no = { 2, 2 };// 操作符下标

33         Core c = new Core();

34         c.calcute(num1, op, no, n);// 运算1-2-3

35         int r = (int) c.getResult();

36         System.out.println(r);

37         assertEquals(-4, r);

38     }

39     

40     @Test

41     public void testMulti() {// 乘法

42         int n = 3;// 操作数个数

43         int[] num1 = { 2, 2, 3 };// 操作数

44         char[] op = { ' ', '+', '-', '*', '/' };// 操作符

45         int[] no = { 3, 3 };// 操作符下标

46         Core c = new Core();

47         c.calcute(num1, op, no, n);// 运算2*2*3

48         int r = (int) c.getResult();

49         System.out.println(r);

50         assertEquals(12, r);

51     }

52     

53     @Test

54     public void testDiv() {// 除法

55         int n = 2;// 操作数个数

56         int[] num1 = { 2, 2, 3 };// 操作数

57         char[] op = { ' ', '+', '-', '*', '/' };// 操作符

58         int[] no = { 4 };// 操作符下标

59         Core c = new Core();

60         c.calcute(num1, op, no, n);// 运算2/2

61         int r = (int) c.getResult();

62         System.out.println(r);

63         assertEquals(1, r);

64     }

65     

66     @Test

67     public void testNormal() {// 混合运算

68         int n = 3;// 操作数个数

69         int[] num1 = { 1, 2, 3 };// 操作数

70         char[] op = { ' ', '+', '-', '*', '/' };// 操作符

71         int[] no = { 1, 3 };// 操作符下标

72         Core c = new Core();

73         c.calcute(num1, op, no, n);// 运算1+2*3

74         int r = (int) c.getResult();

75         System.out.println(r);

76         assertEquals(7, r);

77     }

78 

79     @Test(expected = ArithmeticException.class)

80     public void testZero() {// 除以零

81         int n = 3;// 操作数个数

82         int[] num1 = { 1, 0, 3 };// 操作数

83         char[] op = { ' ', '+', '-', '*', '/' };// 操作符

84         int[] no = { 4, 1 };// 操作符下标

85         Core c = new Core();

86         c.calcute(num1, op, no, n);// 运算1/0+3

87     }

88 

89 }

在测试类中共测试了简单的加法,减法,除法,乘法,和除数为零。

缺点:长整形等特殊的数,没有测试。但其实在实际的主程序中不会出现长整形的数。也不会出现除数为零的情况。

总结:稍微了解了程序设计,虽然学骑单车的时候摔了很多次,但最终我们有了进步。这是值得开心的事情。在整个测试中,我负责写封装,以及封装之后的测试类,小伙伴负责写黑白盒。截图、黑白盒等小伙伴会继续完善并发博客。

结对小伙伴:陈建:http://www.cnblogs.com/be-the-one/

由于五一要出发去远方,所以作业比较赶,感谢小伙伴的体谅,接下来就交给你了。

 

你可能感兴趣的:(四则运算)