1,   计划

为一年级小学生设计口算题卡

2,   需求分析

2.1,用户故事

作为一个一年级小学生的家长,我希望制作一个出题软件,完成100以内的正整数的加减法题随机产生,一边减轻我的负担

2.2 技术难点

随机产生100以内的正整数

随机产生加减符号

减法负值的剔除

任务一

随机产生一组(10个)算题----产生算式剔除不够减,随机产生

任务二

显示一组算题,选择解答界面,完成按钮,同步计时(秒)

任务三

显示对错,统计正确率,统计时间

2,生成设计文档

3,设计复审

 室友帮忙查看

4,代码规范

    类名和方法名的定义要让其他人能看懂是什么意思,不要用a或b定义

5,具体设计

 6,具体编码

package

package hnzj;
/**
 * 减法运算
 */
public class Reduce extends Operation{
    static String symbol="-";
    public Reduce() {
        super(symbol);
    }

    @Override
    //判断第一个随机数是否大于第二个数
    public void isRight() {
        if(num1<num2) {
            int temp=num1;
            num1=num2;
            num2=temp;
        }
    }

    @Override
    public void problemAnswers() {
        rightAnswers=num1-num2;
    }

}

package hnzj;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
/**
 * 图形用户界面
 */
public class TheForm {
         int[] userAnswer = new int[10];//用户答案数组
         int scores;//成绩
         int usedTime;//用户时间
         boolean isrun = false;
         Operation[] questions = new Operation[10];
         JFrame f = new JFrame("口算题卡");
         
         JPanel pshan = new JPanel();//面板上面部分
         JPanel pzhong = new JPanel();//面板中间部分
         JPanel pxia = new JPanel();//面板下面部分
         
         JButton bDoOover = new JButton("重做");//重做按钮
         JButton bStart = new JButton("开始做题");//开始做题按钮
         JLabel lAnswer = new JLabel("请输入答案");//输入答案提示标签
         JLabel jwelcome = new JLabel("欢迎来到自动出题系统");
         //显示题目
         JLabel[] lQuestions= new JLabel[10];
         //显示正确答案
         JLabel[] lAnswers = new JLabel[10];
         //显示用户答案是对是错
         JLabel[] lRightOrWrong = new JLabel[10];
         //获取用户答案的文本框
         JTextField[] tUsersAnswer = new JTextField[10];
         JLabel lScores = new JLabel("你的成绩为:");
        //设置时间的面板
         JPanel pTime = new JPanel();
         JLabel lRemainTime = new JLabel("剩余时间:");
         JTextField tTime = new JTextField("300");
         JLabel lTimeConsuming = new JLabel("用时:");
         //构造面板
         public TheForm() {
             //设置主面板
             f.setSize(900,700);//设置窗体大小
             //点击右上角x时关闭运行的程序
             f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             f.setLocationRelativeTo(null);//窗口显示在屏幕中间
             f.setVisible(true);//设置窗口为可见
             //设置面板上面部分
             pshan.setSize(800,100);//设置面板大小
             jwelcome.setFont(new Font("微软雅黑", Font.BOLD, 30));
             pshan.add(jwelcome);
             f.add(pshan,BorderLayout.NORTH);//边界布局
             //设置中间面板部分
             pzhong.setSize(800,500);
             //网格布局
             GridBagLayout gbl = new GridBagLayout();
             GridBagConstraints gbc = new GridBagConstraints();
             gbc.weightx = 2;
             gbc.weighty = 2;
             gbc.gridx=1;//组件的左边缘与网格左部之间的距离
             gbc.gridy=0;//组件的上边缘与网格顶部之间的距离
             gbc.anchor = GridBagConstraints.WEST;
             gbl.setConstraints(lAnswer, gbc);//设置此布局中指定组件的约束条件
             lAnswer.setFont(new Font("微软雅黑", Font.BOLD, 22));
             pzhong.add(lAnswer);
             //设置成绩的位置
             gbc.gridx = 4;
             gbc.gridwidth = 2;
             gbc.anchor = GridBagConstraints.CENTER;
             gbl.setConstraints(lScores, gbc);
             lScores.setFont(new Font("微软雅黑", Font.BOLD, 22));
             pzhong.add(lScores);
             //设置打印的题目和答案
             for(int i = 0;i < 5;i++){
                    lQuestions[i] = new JLabel("点击开始做题显示题目");
                    lQuestions[i].setFont(new Font("微软雅黑", Font.BOLD, 20));
                    tUsersAnswer[i] = new JTextField(5);
                    tUsersAnswer[i].setFont(new Font("微软雅黑", Font.BOLD, 20));
                    lAnswers[i] = new JLabel("");
                    lAnswers[i].setFont(new Font("微软雅黑", Font.BOLD, 20));
                    lRightOrWrong[i] = new JLabel("");
                    lRightOrWrong[i].setFont(new Font("微软雅黑", Font.BOLD, 20));

                    gbc.gridwidth = 1;
                    gbc.gridx = 0;
                    gbc.gridy = 2*i+1;
                    gbc.anchor = GridBagConstraints.EAST;
                    gbl.setConstraints(lQuestions[i], gbc);
                    pzhong.add(lQuestions[i]);
                    
                    gbc.anchor = GridBagConstraints.CENTER;
                    gbc.gridy = 2*i+2;
                    gbc.gridwidth = 2;
                    gbl.setConstraints(lAnswers[i], gbc);
                    pzhong.add(lAnswers[i]);

                    gbc.gridwidth = 1;
                    gbc.gridx = 1;
                    gbc.gridy = 2*i+1;
                    gbc.anchor = GridBagConstraints.WEST;
                    gbl.setConstraints(tUsersAnswer[i],gbc);
                    pzhong.add(tUsersAnswer[i]);

                    gbc.gridx = 2;
                    gbc.gridy = 2*i+2;
                    gbl.setConstraints(lRightOrWrong[i], gbc);
                    pzhong.add(lRightOrWrong[i]);
                }

                for(int i = 5;i < 10;i++){
                    lQuestions[i] = new JLabel("点击开始做题显示题目");
                    lQuestions[i].setFont(new Font("微软雅黑", Font.BOLD, 20));
                    tUsersAnswer[i] = new JTextField(5);
                    tUsersAnswer[i].setFont(new Font("微软雅黑", Font.BOLD, 20));
                    lAnswers[i] = new JLabel("");
                    lAnswers[i].setFont(new Font("微软雅黑", Font.BOLD, 20));
                    lRightOrWrong[i] = new JLabel("");
                    lRightOrWrong[i].setFont(new Font("微软雅黑", Font.BOLD, 20));

                    gbc.gridx = 4;
                    gbc.gridy = 2*i-9;
                    gbc.anchor = GridBagConstraints.EAST;
                    gbl.setConstraints(lQuestions[i], gbc);
                    pzhong.add(lQuestions[i]);
                    gbc.anchor = GridBagConstraints.CENTER;
                    gbc.gridy = 2*i-8;
                    gbc.gridwidth = 2;
                    gbl.setConstraints(lAnswers[i], gbc);
                    pzhong.add(lAnswers[i]);

                    gbc.gridwidth = 1;
                    gbc.gridx = 5;
                    gbc.gridy = 2*i-9;
                    gbc.anchor = GridBagConstraints.WEST;
                    gbl.setConstraints(tUsersAnswer[i],gbc);
                    pzhong.add(tUsersAnswer[i]);

                    gbc.gridx = 6;
                    gbc.gridy = 2*i-8;
                    gbl.setConstraints(lRightOrWrong[i], gbc);
                    pzhong.add(lRightOrWrong[i]);
                    }
                pzhong.setLayout(gbl);
                //把pzhong面板添加到界面中间
                f.add(pzhong,BorderLayout.CENTER);
                
                //下面面板设置
                pxia.setLayout(new FlowLayout(FlowLayout.CENTER,60,20)); 
                lRemainTime.setFont(new Font("微软雅黑", Font.BOLD, 20));
                lTimeConsuming.setFont(new Font("微软雅黑", Font.BOLD, 20));
                tTime.setFont(new Font("微软雅黑", Font.BOLD, 20));
                pTime.setLayout(new FlowLayout(FlowLayout.LEFT,10,20));
                pTime.add(lRemainTime);
                pTime.add(tTime);
                pTime.add(lTimeConsuming);
                pxia.add(pTime);
                //开始做题
                bStart.setFont(new Font("微软雅黑", Font.BOLD, 20));
                pxia.add(bStart);
                //重做
                bDoOover.setFont(new Font("微软雅黑", Font.BOLD, 20));
                pxia.add(bDoOover);
                f.add(pxia,BorderLayout.SOUTH);
                
              //使用匿名嵌套类的方式注册开始按钮的事件处理监听器对象
                bStart.addActionListener(
                        new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                if(bStart.getText().equals("开始做题")){
                               
                                        start(); //如果按钮上面的文字是"开始做题",则调用start()方法出题
                                        bStart.setText("提交答案"); 
                                        //倒计时线程开始
                                        LimitTime t = new LimitTime();
                                        t.start(); 
                                }else{
                                    for(int i = 0;i < 10;i++){
                                        if(tUsersAnswer[i].getText().equals("")){
                                            tUsersAnswer[i].setText("-1");
                                        }
                                    }
                                    isrun = false;//将runFlag设置为false(线程就会不再执行while循环里的内容)
                                    lTimeConsuming.setText("用时:"+usedTime);
                                    bStart.setText("开始做题");

                                }
                            }
                        }
                );

                //监听重做按钮
                bDoOover.addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent e){
                        //若已提交答案 则可以进行重做
                        if(bStart.getText().equals("开始做题")){
                            for(int i = 0;i < 10;i++){
                                tUsersAnswer[i].setText("");
                                lAnswers[i].setText("");
                                lRightOrWrong[i].setText("");
                                lScores.setText("");
                            }
                            lTimeConsuming.setText("用时:");
                            LimitTime t = new LimitTime();
                            t.start();
                            bStart.setText("提交答案"); 
                        }else{
                            //答案未提交 不能重做
                            JFrame notSubmit = new JFrame();
                            JOptionPane.showMessageDialog(notSubmit,"您需要提交答案之后才能重做");
                        }
                    }
                });
         } 
             //显示成绩
            public void printAnswer(){
                //成绩初始值为100
                scores = 100;

                //对于每道题
                for(int i = 0; i < 10;i++){
                    //给用户的答案这一数组赋值
                    userAnswer[i] = Integer.valueOf(tUsersAnswer[i].getText());
                    questions[i].setUserAnswers(userAnswer[i]);
                    //使正确答案显示在面板上
                    lAnswers[i].setText(questions[i].printrightAnswers());

                    //在面板上显示答案是否正确
                    lRightOrWrong[i].setText(questions[i].userRightOrWrong());

                    //如果错误则将答案和是否正确两个标签的字体颜色设置为红色
                    if(lRightOrWrong[i].getText().equals("回答错误")){
                        lAnswers[i].setForeground(Color.RED);
                        lRightOrWrong[i].setForeground(Color.RED);
                        scores-=10;
                    }else{
                        //如果正确显示为蓝色
                        lAnswers[i].setForeground(Color.BLUE);
                        lRightOrWrong[i].setForeground(Color.BLUE);
                    }
                }
                //显示成绩
                lScores.setText("你的成绩为:"+ scores);

            }
         //倒计时线程
            class LimitTime extends Thread{
                public void run(){
                
                    isrun = true;
                    int i = 300;//剩余秒数
                    usedTime = 0;//用户计时
                    while(isrun && i >= 0) {
                    //把整型转变为字符串类型
                        tTime.setText(Integer.toString(i));
                        try {
                            sleep(1000);
                            usedTime++;
                        } catch (InterruptedException e) {
                            JFrame jf = new JFrame();
                            JOptionPane.showMessageDialog(jf,"出现了未知问题,请重启程序");
                        }
                        i--;
                    }
                    //如果倒计时用户都没有输入答案则自动赋值为-1
                    for(int j = 0;j < 10;j++)
                    {
                        if(tUsersAnswer[j].getText().equals(""))
                        {
                            tUsersAnswer[j].setText("-1");
                        }
                    }
                    printAnswer();//倒计时结束打印答案并输出正确答案
                    bStart.setText("开始做题");
                    lTimeConsuming.setText("用时:"+usedTime);
                }
            }
            
            public void start(){
                //清除TextField和答案标签的内容
                for(int i = 0;i < 10;i++){
                    tUsersAnswer[i].setText("");
                    lAnswers[i].setText("");
                    lRightOrWrong[i].setText("");
                    lScores.setText("");
                    lTimeConsuming.setText("用时:");
                }
             //随机产生加减法
                for(int i = 0;i < 10;i++){
                        int tempCh = (int)(Math.random()*2+1);
                        switch(tempCh)
                        {
                        case 1:
                             questions[i] = new Add();
                             lQuestions[i].setText(questions[i].printProblem());
                            break;
                        case 2:
                             questions[i] = new Reduce();
                             lQuestions[i].setText(questions[i].printProblem());
                            break;
                    }

                    
                }
            }
}
package hnzj;
public class TheFormTest {

    public static void main(String[] args) {
        TheForm tf=new TheForm();
    }
}

 

hnzj;
/**
 * 四则运算
 * @author fang
 *
 */
public abstract class Operation {
    protected int num1;//第一个随机数
    protected int num2;//第二个随机数
    protected int userAnswers;//用户答案
    protected int rightAnswers;//正确答案
    protected String symbol;//运算符号 
    public Operation(String symbol) {
        this.symbol=symbol;    
    }
    //产生随机数
    public void randomNum() {
        num1=(int) (Math.random()*100);
        num2=(int) (Math.random()*100);
    }
    //打印题目
    public String printProblem(){
        randomNum();
        isRight();
        return num1+symbol+num2+"=";
    }
    //输出正确答案
    public String printrightAnswers()
    {
        problemAnswers();
        return "答案:"+num1+" "+symbol+" "+num2+" = "+rightAnswers;
    }
    //获取用户答案
    public void setUserAnswers(int userAnswers) {
        this.userAnswers = userAnswers;
    }
    //判断用户回答的对错
    public String userRightOrWrong() {
        if(userAnswers==rightAnswers) {
            return "回答正确";
        }else {
            return "回答错误";
        }
    }
    //判断随机数生成是否合法
    public abstract void isRight();
    //生成正确答案
    public abstract void problemAnswers();

}
package hnzj;
/**
 * 加法运算
 */
public  class Add extends Operation {
    static String symbol="+";
         public Add() {
        super(symbol);
    }
@Override
public void isRight() {
}
@Override
public void problemAnswers() {
    rightAnswers=num1+num2;
}
}

 

7,代码复审

8,测试

记录用时

测试报告

计算工作量

事后总结

  整个项目下来在开发当中所花费的时间最多,遇到了自己没有掌握到的知识点,尤其时代码生成和修改当中所花费的时间诸多,让我遇到自己很多不足的地方

提出过程改进计划

优化代码的定义,尽量避免重复性代码,尽量向开闭原则靠拢

 

PSP阶段

实际花费时间百分比

估计花费时间百分比

计划

8

6

明确需求和其他相关因素,估计每个阶段的时间成本

8

6

开发

84

86

需求分析

6

8

生成设计文档

4

8

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

4

4

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

2

3

具体设计

12

13

具体代码

32

30

代码复审

12

10

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

12

10

报告

8

8

测试报告

3

3

计算工作量

2

2

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

3

3

 

posted on 2021-05-31 21:27  第三学习小组  阅读(119)  评论(0编辑  收藏  举报