Java教程

湖南大学结对编程之个人项目互评

本文主要是介绍湖南大学结对编程之个人项目互评,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

本篇博客为对结对编程搭档邹同学的个人项目(中小学数学卷子自动生成程序)的评价。该代码使用语言为Java,与我的个人项目语言一致,本次评价旨在总结反省,共同进步。

此次评价主要基于三个方面:

一、代码结构

mathpaper包:

  • Create类主要用来出题

  • User类用来对用户类型定义

  • Begin类包括对输出页面的一系列操作,对用户的输入类型做判断

  • Database类主要用来对保存并判断用户信息。

  • 调用Main类来运行整个项目

结构较为清晰。在组织类的结构时充分考虑面向对象的特点进行书写。

二、功能完成

  1. 登录功能

  1. 退出功能

 

  1. 生成试卷功能

  1. 切换功能

操作均在操作台实现,我们去看一下生成的文件:

基本功能验证完毕!均已实现。

三、代码分析

1. User类:

未使用到定义的setName、setPassword、setType函数。

 2. Database类

逻辑简单,便于理解。经检验,功能正常;

但可复用性不高,当且仅当账户信息不变时使用正常,如需修改账户信息,则代码结构也必须随之发生变化;

 3. Create类

(1)createProblem函数

点击查看代码
public static String createProblem(String type) throws IOException{
        String[] signs={"+","-","*","/","²","√","sin","cos","tan"};
        Random random=new Random();
        String prob="";                            //题目,目前还是空的
        int opNumber=random.nextInt(5)+1;   //操作数数量1~5
        if(type.equals("小学")) {
            opNumber= random.nextInt(4)+2;    //小学2~5
        }
        int[] operand1=new int[opNumber];
        String[] oprand=new String[opNumber];
        int[] flag=new int[opNumber];           //标记是否成为了特殊数
        for(int i=0;i<opNumber;i++){            //给数赋值
            operand1[i]=random.nextInt(100)+1;            //取值范围1~100
            oprand[i]=String.valueOf(operand1[i]);               //将数变为字符串类型
            flag[i]=0;                                           //如果这个数字有改动,会被标记
        }

        if(type.equals("小学")){
            String[] opsign=new String[opNumber-1];              //小学题目的符号比数字少一个
            int[] index=new int[opNumber-1];
            for(int i=0;i<opNumber-1;i++) {
                index[i]=random.nextInt(4);
                opsign[i]=signs[index[i]];
            }
            prob=Add(opNumber,opsign,oprand);
        }

        else if(type.equals("初中")){
            int a= random.nextInt(opNumber)+1;                   //有a个被平方或开根号了
            //处理a个特殊的数
            for(int i=0;i<a;i++) {
                int signIndex= random.nextInt(2)+4;       //选择操作符下表4或5,平方或开根号
                int changeIndex=0;                               //改变的数字下标

                while(true){
                    changeIndex=random.nextInt(opNumber);        //选择要改变的数字的下标
                    if(flag[changeIndex]==0) {
                        flag[changeIndex]++;
                        break;
                    }
                }
                if(signIndex==4){   //平方
                    oprand[changeIndex]=oprand[changeIndex]+"²";
                } else if(signIndex==5){    //开根号
                    oprand[changeIndex]="√"+oprand[changeIndex];
                }
            }
            //加上+-*/运算符
            String[] opsign=new String[opNumber-1];              //初中题目的符号比数字少一个
            int[] index=new int[opNumber-1];
            for(int i=0;i<opNumber-1;i++) {
                index[i]=random.nextInt(4);
                opsign[i]=signs[index[i]];
            }

            prob=Add(opNumber,opsign,oprand);
        }

        else if(type.equals("高中")){
            //处理b个sin,cos,tan
            int b=random.nextInt(opNumber)+1;                //有b个数是有sin,cos,tan,至少有一个
            for(int i=0;i<b;i++) {
                int signIndex = random.nextInt(3) + 6;       //选择操作符下表6或7或8
                int changeIndex = 0;              //改变的数字下标

                while (true) {
                    changeIndex = random.nextInt(opNumber);     //选择要改变的数字的下标
                    if (flag[changeIndex] == 0) {
                        flag[changeIndex]++;
                        break;
                    }
                }
                oprand[changeIndex] = signs[signIndex] + oprand[changeIndex];
            }

            //如果还有的数未被sin,cos,tan标记,可以加上平方或开根号
            if(b<opNumber) {
                int a = random.nextInt(opNumber - b);
                for (int i = 0; i < a; i++) {
                    int signIndex2 = random.nextInt(2) + 4;       //选择操作符下表4或5,平方或开根号
                    int changeIndex2 = 0;              //改变的数字下标

                    while (true) {
                        changeIndex2 = random.nextInt(opNumber);     //选择要改变的数字的下标
                        if (flag[changeIndex2] == 0) {
                            flag[changeIndex2]++;
                            break;
                        }
                    }
                    if (signIndex2 == 4) {   //平方
                        oprand[changeIndex2] = oprand[changeIndex2] + "²";
                    } else if (signIndex2 == 5) {    //开根号
                        oprand[changeIndex2] = "√" + oprand[changeIndex2];
                    }
                }
            }
            //加上+-*/运算符
            String[] opsign=new String[opNumber-1];              //初中题目的符号比数字少一个
            int[] index=new int[opNumber-1];
            for(int i=0;i<opNumber-1;i++) {
                index[i]=random.nextInt(4);
                opsign[i]=signs[index[i]];
            }

            prob=Add(opNumber,opsign,oprand);
        }
        return prob;
    }

程序逻辑是小学、初中、高中各自用一个函数去写,里面不但复用的代码很多,而且如果有别的运算符比如大学难度,也要重新写一个大学的......扩展与修改难度大,其实仔细阅读后小学、初中、 高中,三者区别不大,一个判断语句足以......函数的作用更多应该是去实现一个独立的功能,而不是将程序部分代码变成一个函数。

(2)Add函数

点击查看代码
public static  String Add(int opNumber,String[] opsign,String[] oprand){
        String prob="";
        Random random=new Random();

        if(random.nextBoolean()&&opNumber>2){                    //加括号
            //Left
            int leftBracket= random.nextInt(opNumber-1);
            //Right
            int rightBracket=random.nextInt(opNumber-leftBracket-1)+leftBracket+1;

            if(leftBracket==0&&rightBracket==opNumber-1){
                rightBracket--;
            }
            for(int i=0;i<opNumber-1;i++){
                if(i==leftBracket){
                    prob=prob+"("+oprand[i]+opsign[i];
                } else if(i==rightBracket) {
                    prob=prob+oprand[i]+")"+opsign[i];
                } else {
                    prob=prob+oprand[i]+opsign[i];
                }
            }
            if(rightBracket==opNumber-1){
                prob=prob+oprand[opNumber-1]+")";
            } else{
                prob=prob+oprand[opNumber-1];
            }
        }
        else{                                        //不加括号
            for(int i=0;i<opNumber-1;i++){
                prob=prob+oprand[i]+opsign[i];
            }
            prob=prob+oprand[opNumber-1];
        }
        return prob;
    }

将括号设置这一函数单独设置,增加代码的复用性,让结构更加明朗

在处理表达式时可以增加一些功能:除号右边不能为0,括号可不可以设置不止一对。

(3)checkRepeat函数

点击查看代码
public static boolean checkRepeat(String name,String problem) throws IOException{
        File filePaper=new File("math_problems\\"+name);
        File[] paperList=filePaper.listFiles();          //获取指定目录下的所有文件或者文件目录的File对象数组
        int len=paperList.length;
        InputStream fileRead;           //字节输入流,将文件中的数据读取到java中
        for(int i=0;i<len;i++) {
            fileRead=new FileInputStream(paperList[i]);
            byte[] problems=new byte[2048];
            fileRead.read(problems);                     //获取当前试卷文件的所有题目,输入流会把读取到的内容放入到这个字节数组中
            String content=new String(problems,"utf-8");
            if(content.indexOf(problem)!=-1) {           //看看字符串content中有无problem这个字符串,没有返回-1
                return true;
            }
            fileRead.close();
        }
        return false;
    }

查重算法简单易懂。能有效实现查重

查重算法采用直接循环遍历,在题目大量出现的情况下,查重效率低

(4)获取文件路径

 题目要求将对应的试题存在账号的文件夹内,并且对于相应的地址位置,大部分同学都是单纯的提前设置好在自己电脑的文件夹,若是在别人的电脑就得重新修改代码,而队友则是采用了getAbsolutePath()获取绝对路径的方式,动态的去创建文件,灵活高效。

四、代码规范

代码规范比较好,缩进,空格,包括在文件前面的包头声明都是非常明确且清晰的,可读性高,并且类、类函数等都做了充分的注解,让我看着并不会很吃力,命名比较规范,能够清楚得知道每个变量和函数具体在起什么作用。

总结:

邹同学的代码有很多值得我学习的地方,以上列出的优点只是可以看出来的结构,其中蕴含的思想需要我之后多多学习。在此次个人项目中再一次熟悉了Java语言,对之后的项目开始可能大有裨益。

这篇关于湖南大学结对编程之个人项目互评的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!