zoukankan      html  css  js  c++  java
  • 四则运算结对作业

    1、代码地址:https://git.coding.net/sixtyseven/Twinning.git

    2、PSP表格

    PSP

    任务内容

    计划共完成需要的时间(min)

    实际完成需要的时间(min)

    Planning

    计划

    30

    30

     Estimate

    估计这个任务需要多少时间,并规划大致工作步骤

    10

    12

    Development

    开发

    2234

    4375

    Analysis

    需求分析 (包括学习新技术)

    60

    240

    Design Spec

    生成设计文档

    0

    0

    Design Review

    设计复审 (和同事审核设计文档)

    0

    0

    Coding Standard

    代码规范 (为目前的开发制定合适的规范)

    7

    10

    Design

    具体设计

    80

    260

    Coding

    具体编码

    1800

    2800

    Code Review

    代码复审

    40

    240

    Test

    测试(自我测试,修改代码,提交修改)

    80

    140

    Reporting

    报告

    90

    240

    Test Report

    测试报告

    25

    190

    Size Measurement

    计算工作量

    10

    15

    Postmortem & Process Improvement Plan

    事后总结, 并提出过程改进计划

    40

    240

    3、Information Hiding

           信息隐藏是软件的首要技术使命中格外重要的一种启发式方法,因为它强调的就是隐藏复杂度。信息隐藏有着独特的启发力,它能够激发出有效的设计方案。信息隐藏同样有助于设计类的公开接口。代码模块应该采用定义良好的接口来封装,这些模块的内部结构应该是程序员的私有财产,外部是不可见的。

    Interface Design

    设计接口 design interface是传统的后勤保障的一种要素也是一种后勤功能。

    接口要符合rest、命名要规范优雅、单一性、扩展性。

    接口命名规范:命名以英文或者英文缩写并以驼峰命名法命名

                             返回字段中表示同一个含义的字段在不同接口中命名尽量一致

    Loose Coupling

    松耦合的基本概念是:允许改变或者当问题发生在“电线的一端时”来避免影响到其他的端点。也就是说,改变或者供应者或者服务的问题不能影响到用户----或者用户的问题不应影响到供应者或者服务。作为提供松耦合的必备基本要素,Web服务管理代理经常使用在用户和供应者之间。

    4、计算模块接口的设计与实现过程

    共四个类:Background类、Fraction类、Integer类、MyWindows类。

    Background类:testNum 题目数量、question 储存题目的数组、result 储存答案的数组

    Fraction类:qstr储存题目的字符串、astr 储存答案的字符串

    Integer类:qstr储存题目的字符串、astr 储存答案的字符串

    MyWindows类:testNum 题目数量、question 储存题目的数组、result 储存答案的数组、rightNum 文件读出的正确数量、errorNum 文件读出的错误数量、rightNum2 本次正确数量、errorNum2  本次错误数量、answers 储存用户的回答

    5、计算模块接口部分的性能改进

    public static List<String> generateExp(int exprCount,int low,int high,
                int maxOpCount,boolean muldiv,boolean bracket) {
            List<String> exprList=new ArrayList<>();
            
            Random rand=new Random();
            for(int i=0;i<exprCount;++i) {
                StringBuilder exprBuilder=new StringBuilder();
                
                int opCount=rand.nextInt(maxOpCount)+1;
                int[] lbs=new int[opCount];
                int k=0;
                for(int j=0;j<opCount;++j) {
                    boolean bracketFlag=false;
                    //以40%概率添加左括号
                    if(bracket&&rand.nextDouble()<0.4) {
                        exprBuilder.append('(');
                        lbs[k++]=exprBuilder.length()-1;
                        bracketFlag=true;
                    }
                    //添加操作数
                    exprBuilder.append(rand.nextInt(high+1-low)+low);
                    //以50%的概率添加右括号
                    if(bracket&&!bracketFlag&&k>0&&rand.nextDouble()<0.5) {
                        exprBuilder.append(')');
                        k--;
                    }
                    //添加操作符
                    exprBuilder.append(muldiv?ops[rand.nextInt(4)]:ops[rand.nextInt(2)]);
                }
                exprBuilder.append(rand.nextInt(high+1-low)+1);
                if(k>1) {
                    exprBuilder.append(')');
                    k--;
                }
                //删除多余左括号
                for(int m=0;m<k;++m) {
                    exprBuilder.deleteCharAt(lbs[m]);
                }
                exprList.add(exprBuilder.toString());
            }
            return exprList;
        }
        
        
        //比较运算符优先级
        private static int cmpPrior(char sign1,char sign2) {
            @SuppressWarnings("serial")
            Map<Character,Integer> map=new HashMap<Character,Integer>() {{
                put('+',1);put('-',1);put('x',2);put('÷',2);put('#',0);put('(',0);put(')',0);
            }};
            
            return map.get(sign1)-map.get(sign2);
        }
        
        //进行一次运算
        private static int calc(int num1,int num2,char op) {
            switch(op) {
            case '+':return num2+num1;
            case '-':return num2-num1;
            case 'x':return num2*num1;
            case '*':return num2*num1;
            case '/':return num2/num1;
            case '÷':return num2/num1;
            default: return 0;
            }
        }
        
        //判断字符c是否为运算符
        private static boolean isOperator(char c) {
            if(c=='+'||c=='-'||c=='x'||c=='*'||c=='÷'||c=='/'||c=='#') {
                return true;
            }
            else {
                return false;
            }
        }
        
        //判断字符c是否为数字
        private static boolean isNumber(char c) {
            return Character.isDigit(c);
        }
        public static int calculate(String expr) {
            Stack<Integer> numStack=new Stack<>();
            Stack<Character> opStack=new Stack<>();
            
            expr=expr.concat("#");
            
            int num=0,i=0;
            while(i<expr.length()) {
                char ch=expr.charAt(i);
                if(isOperator(ch)) {
                    if(opStack.isEmpty()||cmpPrior(ch, opStack.getTop())>0) {
                        opStack.push(ch);
                        i++;
                    }
                    else {
                        numStack.push(calc(numStack.pop(),numStack.pop(),opStack.pop()));
                    }
                }
                else if(ch=='(') {
                    opStack.push(ch);
                    i++;
                }
                else if(ch==')') {
                    while(!opStack.isEmpty()&&opStack.getTop()!='(') {
                        numStack.push(calc(numStack.pop(),numStack.pop(),opStack.pop()));
                    }
                    //表达式括号不匹配处理
                    if(opStack.isEmpty()) {
                        System.out.println("表达式括号不匹配");
                        return -1;
                    }
                    else {
                        opStack.pop();
                        i++;
                    }
                }
                else {
                    num=ch-'0';
                    while(isNumber(expr.charAt(i+1))) {
                        ch=expr.charAt(++i);
                        num=num*10+(ch-'0');
                    }
                    numStack.push(num);
                    i++;
                }
            }
            
            return numStack.pop();
        }

    6、计算模块部分单元测试展示

    private class OpNode{
            //节点类型(0:运算符节点   1:操作数节点)
            private int nodeType;
            private int value;
            private int interResult=0;
            private OpNode leftChild,rightChild,parent;
            public OpNode(int nodeType,int value, OpNode parent) {
                this.nodeType=nodeType;
                this.value=value;
                this.parent=parent;
                this.leftChild=this.rightChild=null;
            }
            
            //判断是否为操作符节点
            public boolean isOperator() {
                if(nodeType==0) {
                    return true;
                }
                else return false;
            }
            
            public int getNodeType() {
                return nodeType;
            }
            public void setNodeType(int nodeType) {
                this.nodeType = nodeType;
            }
            public int getValue() {
                return value;
            }
            public void setValue(int value) {
                this.value = value;
            }
            public int getInterResult() {
                return interResult;
            }
            public void setInterResult(int interResult) {
                this.interResult = interResult;
            }
            public OpNode getLeftChild() {
                return leftChild;
            }
            public void setLeftChild(OpNode leftChild) {
                this.leftChild = leftChild;
            }
            public OpNode getRightChild() {
                return rightChild;
            }
            public void setRightChild(OpNode rightChild) {
                this.rightChild = rightChild;
            }
            public OpNode getParent() {
                return parent;
            }
            public void setParent(OpNode parent) {
                this.parent = parent;
            }
            
            
        }
        
        private OpNode root;
        public Expression(int maxOpCount,int low,int high,
                boolean containsMulDiv,boolean containsBracket) {
            Random rand=new Random();
            int opCount=1;
            root=newOperNode(null,containsMulDiv,rand);
            
            while(opCount<=maxOpCount) {
                int leftNodeType=rand.nextInt(2);
                int rightNodeType=rand.nextInt(2);
                
                //生成二叉树。。。。
            }
        }
        
        //随机生成运算符节点
        private OpNode newOperNode(OpNode parent,Boolean containsMulDiv,Random rand) {
            int value=containsMulDiv?rand.nextInt(2):rand.nextInt(4);
            return new OpNode(0,value,parent);
        }
        
        //随机生成数值节点
        private OpNode newNumNode(OpNode parent,int low,int high,Random rand) {
            int value=rand.nextInt(high-low+1)+low;
            return new OpNode(1,value,parent);
        }
    
        public Expression(String expr) {
            
        }

    7、计算模块部分异常处理说明

    public void History() {
            
            try {
                reader = new BufferedReader(new FileReader(new File("history.txt")));
                rightNum = reader.readLine();
                errorNum = reader.readLine();
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            labRight.setText("历史正确量:"+ rightNum );  
            labError.setText("历史错误量:"+ errorNum );          
        }
            
        @Override
        public void actionPerformed(ActionEvent e) {
            
        }
    
    }
    btnSubmit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    timer.stop();
                    for (int i = 0; i < Background.testNum; i++) {
                        answers[i]=tfdAnswer[i].getText();  // 提取用户的答案
                        if(result[i].equals(answers[i])){
                            labCheck[i].setText("right");
                            rightNum2++;
                        }
                        else{
                            labCheck[i].setText("wrong");
                            errorNum2++;
                            wrong.add(new Integer(i+1).toString());
                        }                    
                    }
                    
                    rightNum2 = rightNum2 +Integer.parseInt(rightNum);
                    errorNum2 = errorNum2 +Integer.parseInt(errorNum);                
                    Integer a = new Integer(rightNum2);
                    Integer b = new Integer(errorNum2);
                    
                    try {
                        writer = new BufferedWriter(new FileWriter(new File("history.txt")));
                        writer.write(a.toString());
                        writer.newLine();
                        writer.write(b.toString());
                        writer.newLine();
                        writer.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                                                    
                }
            });
                        
        }

    8、界面模块的详细设计过程

    try {
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
            } catch (Exception e) {
                e.printStackTrace();
            }
            background = new Background();
            background.createTest();
            questions = background.getQuestions();
            result = background.getResult();
    
            jpMain = new JPanel();
            jpMain.setLayout(null);
            
            labRight = new JLabel();
            labRight.setBounds(300, 0, 100, 50);
            jpMain.add(labRight);        
            
            labError = new JLabel();
            labError.setBounds(400, 0, 100, 50);
            jpMain.add(labError);        
            
            History();
            
            labTime = new JLabel();
            labTime.setFont(new Font("Consolas", 0, 20));
            labTime.setBounds(100, 0, 120, 50);
            jpMain.add(labTime);    
            now.setHours(0);
            now.setMinutes(0);
            now.setSeconds(0);
            final Timer timer = new Timer(1000, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    Date now2 = new Date(now.getTime() + 1000);
                    now = now2;
                    SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
                    labTime.setText(formatter.format(now));
                }
            });
    for (int i = 0; i < Background.testNum; i++) {
                jpQuestions[i] = new JPanel();
                jpQuestions[i].setLayout(null);
                
                labQuestions[i] = new JLabel(questions[i], JLabel.CENTER);
                labQuestions[i].setFont(new Font("Consolas", 0, 20));
                jpQuestions[i].add(labQuestions[i]);
                labQuestions[i].setBounds(0, 0, 200, 25);
                
                tfdAnswer[i] = new JTextField(8);
                tfdAnswer[i].setFont(new Font("Consolas", 0, 20));
                jpQuestions[i].add(tfdAnswer[i]);
                tfdAnswer[i].setBounds(380, 0, 60, 30);
                                        
                labCheck[i] = new JLabel("", JLabel.CENTER); 
                labCheck[i].setFont(new Font("Consolas", 0, 16));
                jpQuestions[i].add(labCheck[i]);
                labCheck[i].setBounds(440, 0, 60, 25);
                            
                jpTest.add(jpQuestions[i]);
            }

    9、界面模块与计算模块的对接

    做题

            submitBtn=GuiUtils.newButton(100, 35, "提交答案", new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    int ret=JOptionPane.showConfirmDialog(ProblemDoPanel.this, "确定提交答案?");
                    if(ret==JOptionPane.OK_OPTION) {
                        timer.stop();
                        List<String> answerList=new ArrayList<>();
                        for(int i=0;i<sc.getProblemCount();++i) {
                            answerList.add(answerFieldList.get(i).getText());
                        }
                        sc.setResultAnswers(answerList);
                        
                        StringBuilder wrong=new StringBuilder();
                        for(int i:sc.getWrongList()) {
                            wrong.append(i+",");
                        }
                        String t=timer.getHour()+"时"+timer.getMinute()+"分"+timer.getSecond()+"秒";
                        
                        JOptionPane.showMessageDialog(ProblemDoPanel.this, 
                                "本次测验得分:"+sc.getScore()+"
    共用时:"+t+"
    做错题号:"+wrong.toString());
                        
                        
                        inputBtn.setEnabled(true);
                        submitBtn.setEnabled(false);
                    }
                }
            });

    出题

        JPanel btnPanel=new JPanel();
            btnPanel.add(GuiUtils.newButton(150, 50, "开始出题", new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    //生成题目文件
                    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                    int ret=chooser.showSaveDialog(ProblemOfferPanel.this);
                    if(ret==JFileChooser.APPROVE_OPTION) {
                        int exprCount=Integer.valueOf(exprCountField.getText());
                        int opMaxCount=Integer.valueOf(opMaxCountField.getText());
                        int numLow=Integer.valueOf(numLowField.getText());
                        int numHigh=Integer.valueOf(numHighField.getText());
                        
                        boolean containsMulDiv=containsMulDivBox.isSelected();
                        boolean containsBracket=containsBracketBox.isSelected();
                        
                        List<String> exprList=Calculator.generateExp(exprCount, numLow, numHigh, opMaxCount, 
                                containsMulDiv, containsBracket);
                        
                        BufferedWriter writer=null;
                        try {
                            String filePath=chooser.getSelectedFile().getAbsolutePath()+"/题目.txt";
                            File file=new File(filePath);
                            if(!file.exists()) {
                                file.createNewFile();
                            }
                            writer=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
                            for(int i=1;i<=exprList.size();++i) {
                                writer.write("("+i+") ");
                                writer.write(exprList.get(i-1));
                                writer.newLine();
                                writer.newLine();
                            }
                            writer.close();
                            JOptionPane.showMessageDialog(ProblemOfferPanel.this, "生成题目文件成功!");
                        } catch (IOException e) {
                            JOptionPane.showMessageDialog(ProblemOfferPanel.this, "生成题目文件失败!");
                            e.printStackTrace();
                        }
                    }
                    
                }

    10、描述结对的过程

    11、结对编程

    优点:知识共享,协同合作、思维开阔、互相督促、学习促进。

    缺点:对于队友擅长的领域了解不多的话,容易产生设计分歧。

               沟通不到位,考虑不全面两个人的设计,容易失败,这次本来的设计是网页版,后来发现在交互和服务器上出现很大问题,不得已废弃,浪费了时间和精力。

               需要大量的交流,但是因为非职业原因,时间不好统一。

    个人评价:

    杨思琦:优点:善于学习,想法独到,沟通耐心,流程规划完善

                缺点:时间规划不完善、有点拖延

    刘士齐(我):

                优点:比较有时间观念,善于总结问题,乐于沟通

                缺点:对于项目方向有点佛系,喜欢纠结于不必要的细节,浪费时间,对于此次作业所使用语言基础太薄弱,因此进行的很吃力。

    12、PSP表格(请见上文2)

  • 相关阅读:
    使用 GitHub, Jekyll 打造自己的免费独立博客
    如何解决数据科学计数法在数据库中的显示
    RDF
    C# 在 4.0 以后一共有3种创建线程的方式
    C#多线程
    1、框架概述
    3、IDEA 中使用 Maven
    2、Maven 核心概念
    1、Maven 概述
    JDK动态代理
  • 原文地址:https://www.cnblogs.com/liushiqi67/p/8776089.html
Copyright © 2011-2022 走看看