作业五

作业五: 结对项目-四则运算 "软件"之升级版

作业要求来自https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2232

提交作业的github远程仓库的地址:https://github.com/codeforsome/proTwo

结对同伴的学号姓名:黄曼金

结对同伴的博客地址 :http://www.cnblogs.com/manjin666

  1. 开发及调试环境:Eclipse

___________________________________________________________________________________________

 

二、四个扩展要求:

___________________________________________________________________________________________

  1. 程序可以出带括号的正整数四则运算,支持分数,除法保留两位小数,如:(1/3+1)*2 = 2.67,特别注意:这里是2.67而非2.66,或保持分数形式:8/3

 

  1. 可以出表达式里含有负整数(负整数最小不小于-100)的题目,且负数需要带括号,用户输入的结果不用带括号。如: 2*(-4) = -8

 

 

  1. 用户可以选择出题的个数(最多不能超过5个题目),答题结束可以显示用户答错的题目个数和答对的题目个数

 

  1. 程序可以设置皮肤功能,可以改变界面的颜色即可

 

 

三、源代码

___________________________________________________________________________________________

工具:Eclipse

 

语言:Java

 

  1 package test;
  2 
  3 import java.io.IOException;
  4 import java.util.*;
  5 //产生题目和答案的一个类
  6 public class Exercises {
  7     public static void main(String[] args) {
  8     }
  9     private int minNumber=-100; //题目出现的最小数字
 10     private int maxNumber=100;  //题目出现的最大数字
 11     private int count=2;  //题目初始化的题目数量
 12     private String result=""; //题目的字符串量
 13     private  float resultNumber=0; //题目的正确答案
 14     //用来保存每一道题目和题目答案
 15     private Map<Integer, Result> exercisesMap=new HashMap<Integer, Result>();
 16     //用来保存要用到的运算符号
 17     private char operations[]=new char[]{'+','-','*','/'};
 18     //    该类用来保存结果的答案
 19     public class Result{
 20         public String result;
 21       public   float resultNumber;
 22     }
 23 //获得题目数量
 24     public int getCount() {
 25         return count;
 26     }
 27 
 28     public Map<Integer, Result> getExercisesMap() {
 29         return exercisesMap;
 30     }
 31 
 32     public void setCount(int count) {
 33         this.count = count;
 34     }
 35 //    获得随机数
 36     private int getRandomNumber(){
 37        return  (int)(minNumber+Math.random()*(maxNumber-minNumber+1));
 38     }
 39     private char getRandomOperation(){//获得随机运算符号
 40         int random=(int)(Math.random()*operations.length);
 41         return operations[random];
 42     }
 43 //    计算四则结果
 44     private float getOperationResult(char operation,float x,float y){
 45         float result=0;
 46         switch (operation){
 47             case '+':
 48                 result=x+y;
 49                 break;
 50             case '-':
 51                 result=x-y;
 52                 break;
 53             case '*':
 54                 result=x*y;
 55                 break;
 56             case '/':
 57                 result=x/y;
 58                 break;
 59         }
 60         return result;
 61     }
 62     public void  arithmetic(){//每次产生一道题目
 63         int number[]=new int[3]; //运算数量
 64         char []operation=new char[2]; //符号数量
 65         while (true){
 66            for(int i=0;i<number.length;i++){
 67                number[i]=getRandomNumber(); //给变量赋值
 68            }
 69            operation[0]=getRandomOperation(); //给符号位赋值
 70            operation[1]=getRandomOperation();
 71            if(operation[0]=='*' || operation[0]=='/'){ //判断第一个是否为*,/ 是,则直接计算
 72               if(number[1]==0)continue;
 73                resultNumber=getOperationResult(operation[0],number[0],number[1]);
 74                if(operation[1]=='/' && number[2]==0)continue;
 75                resultNumber=getOperationResult(operation[1],resultNumber,number[2]);
 76           }else {
 77                //如果第一个符号位不是* ,/那就先算第二个数和三个数的值后,再与第一个值计算
 78               if(operation[1]=='/'&& number[2]==0)continue;
 79               if(operation[0]=='-'){
 80                   resultNumber=getOperationResult(operation[1],-number[1],number[2]);
 81                   operation[0]='+';
 82               }
 83               else{
 84                   resultNumber=getOperationResult(operation[1],number[1],number[2]);
 85                   operation[0]='-';
 86               }
 87                resultNumber=getOperationResult(operation[0],number[0],resultNumber);
 88           }
 89           break;
 90        }
 91         //              将数字和符号串联起来 作为输出题目的字符
 92         result=parseNumber(number[0])+operation[0]+parseNumber(number[1])
 93                 +operation[1]+parseNumber(number[2])+"=";
 94 //        resultNumber=
 95     }
 96 //    转化负数带有中括号
 97     private String parseNumber(int number){
 98       return   number<0 ? "("+number+")" : number+"";
 99     }
100     public  Map<Integer, Result> showArithmetic(){//产生题目,答案并保存和输出
101         int countExercise=0;
102         while (countExercise<count){
103             arithmetic();
104             Result result=new Result();
105             result.result=this.result;
106             result.resultNumber=this.resultNumber;
107             exercisesMap.put(countExercise,result);
108             countExercise++;
109         }
110         return exercisesMap;
111     }
112 
113 }
Exercises.java
  1 package test;
  2 
  3 import javax.swing.*;
  4 
  5 import java.awt.*;
  6 import java.awt.event.*;
  7 import java.util.ArrayList;
  8 import java.util.HashMap;
  9 import java.util.List;
 10 import java.util.Map;
 11 import java.util.regex.Pattern;
 12 
 13 public class ExercisesSwing implements ActionListener {
 14     private JLabel jlabelExercise,jlabelTip;
 15     private JFrame jfrm;
 16     private JTextField jtfInput;
 17 //    第一个题目的初始位置和距离
 18     private  int startX=20,startY=20,distance=220;
 19     private Map<Integer,Exercises.Result> map; //保存所有的题目
 20     private Map<Integer,JTextField> mapJtfInput; //保存用户输入框
 21     private  Exercises exercises; //题目类
 22     private static class Score{ //保存答错题数和答题总数
 23       public static  int errorCount=0;
 24       public static int   num=0;
 25     }
 26     private JMenuBar menubar;   //菜单条
 27     private JMenu menuSet,menuColor; //菜单
 28     private JMenuItem  itemColorCYAN, itemColorYELLOW,itemColorPICK;  //颜色菜单项
 29     private JMenuItem itemCount;
 30     private JPanel jPanel;
 31 
 32     public static class Constant{//程序用到的数据常量
 33 //        以下三个常量是试题所在的宽度和高度以及字体大小
 34         private static final int  JLABEl_WIDTH=220;
 35         private static final int  HEIGHT=25;
 36         private static final int  JLABEl_FONTSIZE=20;
 37         private static final int  JTF_INPUT_WIDTH=100;
 38         private  static final int  STRATY=20;
 39 //        菜单栏中可以选择的题目最大数字
 40         private static final int EXERCICESCOUNT=5;
 41     }
 42     ExercisesSwing(){
 43         init(); //程序的加载和初始化
 44     }
 45     private  void init(){
 46         exercises=new Exercises();
 47         jfrm=new JFrame("四则运算");
 48         jPanel=new JPanel();
 49         jPanel.setBounds(0,0,600,6000);
 50         jPanel.setBackground(Color.CYAN);
 51         jPanel.setLayout(null);
 52         jfrm.setLayout(null);
 53         jfrm.setSize(600,600);
 54         jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 55         jfrm.setLocation(100,100);
 56         initMenu();
 57         jlabelTip=new JLabel();
 58         jPanel.add(jlabelTip);
 59         jPanel.setVisible(true);
 60         showExercises();
 61         jfrm.add(jPanel);
 62         jfrm.setVisible(true);
 63     }
 64     private void showExercises(){
 65         map=exercises.showArithmetic();
 66         mapJtfInput=new HashMap<Integer, JTextField>();
 67         Score.errorCount=0;
 68         Score.num=0;
 69         startY=20;
 70         for (int i=0;i<exercises.getCount();i++){
 71             startY+=Constant.HEIGHT;
 72             jlabelExercise=new JLabel(map.get(i).result);
 73             jlabelExercise.setFont(new Font("宋体",Font.BOLD, Constant.JLABEl_FONTSIZE ));
 74             jlabelExercise.setBounds(startX,startY,Constant.JLABEl_WIDTH,Constant.HEIGHT);
 75             jtfInput=new JTextField(10);
 76             jtfInput.addKeyListener(new KeyAdapter() {
 77                 @Override
 78                 public void keyTyped(KeyEvent e) {
 79                     int key = e.getKeyChar();
 80                     // 只能输入数字
 81                     char keyCh = e.getKeyChar();
 82                     if ((keyCh < '0') || (keyCh > '9')) {
 83                         if(keyCh=='-'||keyCh=='.'){
 84 
 85                         }
 86                         else if(keyCh != KeyEvent.VK_ENTER ){
 87                             e.setKeyChar('\0');
 88                         }
 89                     }
 90 
 91                     if (key == KeyEvent.VK_ENTER) {
 92                         String sub="JTextField[,"+(distance+startX)+",";
 93                         int indexOf=e.toString().indexOf(sub)+sub.length();
 94                         int lastOf=e.toString().indexOf(Constant.JTF_INPUT_WIDTH+"x"+Constant.HEIGHT);
 95                         String inputNumber = e.toString();
 96                         if(lastOf<indexOf)
 97                             return;
 98                         String targetY=e.toString().substring(indexOf,lastOf-1);
 99                         int count= (Integer.parseInt(targetY)-Constant.STRATY ) /Constant.HEIGHT-1;
100                         mapJtfInput.get(count).setEditable(false);
101                     }
102                 }
103             });
104             mapJtfInput.put(i,jtfInput);
105             jtfInput.setBounds(startX+distance,startY,Constant.JTF_INPUT_WIDTH,Constant.HEIGHT);
106             jtfInput.addActionListener(this);
107             jPanel.add(jlabelExercise);
108             jPanel.add(jtfInput);
109 
110         }
111 
112     }
113 //    初始化菜单内容
114     private void initMenu(){
115         menubar = new JMenuBar();
116         menuSet = new JMenu("选择题目数量");
117         for(int i=0;i<Constant.EXERCICESCOUNT;i++){
118             itemCount=new JMenuItem((i+1)+"");
119             itemCount.addActionListener(this);
120             menuSet.add(itemCount);
121         }
122         menuColor = new JMenu("颜色设置");
123         itemColorCYAN=new JMenuItem("深加蓝");
124         itemColorYELLOW=new JMenuItem("天然黄");
125         itemColorPICK=new JMenuItem("少女粉");
126         menuColor.add(itemColorCYAN);
127         menuColor.add(itemColorYELLOW);
128         menuColor.add(itemColorPICK);
129         menubar.add(menuSet);  //将菜单添加到菜单条上
130         menubar.add(menuColor);
131         jfrm.setJMenuBar(menubar);
132         setMenuItemEvent();
133     }
134 //    设置菜单颜色按钮事件
135     private void setMenuItemEvent(){
136         itemColorCYAN.addMouseListener(new MouseAdapter() {
137             @Override
138             public void mousePressed(MouseEvent e) {//只能检测到mousePressed事件
139                 super.mouseClicked(e);
140                 jPanel.setBackground(Color.CYAN);
141             }
142         });
143         itemColorYELLOW.addMouseListener(new MouseAdapter() {
144             @Override
145             public void mousePressed(MouseEvent e) {//只能检测到mousePressed事件
146                 super.mouseClicked(e);
147                 jPanel.setBackground(Color.YELLOW);
148             }
149         });
150         itemColorPICK.addMouseListener(new MouseAdapter() {
151             @Override
152             public void mousePressed(MouseEvent e) {//只能检测到mousePressed事件
153                 super.mouseClicked(e);
154                 jPanel.setBackground(Color.pink);
155 
156             }
157         });
158     }
159     public void repaintJPanel(int number){
160          jPanel.removeAll();
161          jPanel.repaint();
162          exercises.setCount(number);
163           showExercises();
164           return;
165     }
166     public static boolean isInteger(String str) {  
167         Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");  
168         return pattern.matcher(str).matches();  
169   }
170 //  对所有组件进行监听事件
171     public void actionPerformed(ActionEvent e) {
172 //        获取组件值
173         String targetNumber=e.getActionCommand();
174 //        如果用户按下的组件是菜单的选择数字 则对页面进行重绘
175         if(!targetNumber.equals("")|| !isInteger(targetNumber)){
176 
177             int number=Double.valueOf(targetNumber).intValue();
178 //                    Integer.parseInt(targetNumber);
179             if( number>0 && number<=Constant.EXERCICESCOUNT)
180             repaintJPanel(number); //重绘页面上的试题 即对试题进行刷新
181         }
182 //        以下是对用户输入答案后 对用户答案进行判断 和输出文字
183 
184 //        首先获取用户输入框的位置 然后再输入框的位置右边输出要显示的信息
185         String sub="JTextField[,"+(distance+startX)+",";
186         int indexOf=e.toString().indexOf(sub)+sub.length();
187         int lastOf=e.toString().indexOf(Constant.JTF_INPUT_WIDTH+"x"+Constant.HEIGHT);
188         String inputNumber = e.getActionCommand();
189         if(lastOf<indexOf)
190             return;
191         String targetY=e.toString().substring(indexOf,lastOf-1);
192         int count= (Integer.parseInt(targetY)-Constant.STRATY ) /Constant.HEIGHT-1;
193         jlabelTip=new JLabel();
194         if(inputNumber.equals(""))
195             inputNumber="-1";
196         float result=map.get(count).resultNumber-Float.parseFloat(inputNumber);
197         if(Math.abs(result)<0.01){
198             jlabelTip.setText("你答对了");
199         }else{
200             jlabelTip.setText("答错了,正确答案:"+
201                             String.format("%.2f", map.get(count).resultNumber));
202             Score.errorCount++;
203         }
204         jPanel.add(jlabelTip);
205         jlabelTip.setBounds(startX+(int)(distance*1.5),Integer.parseInt(targetY),Constant.JTF_INPUT_WIDTH*2,Constant.HEIGHT);
206 //        以下是判断用户答错的题目和总的答题数目 在用户答题后  输入框便不能使用了
207         Score.num++;
208         if(Score.num==exercises.getCount()){
209             jlabelTip=new JLabel();
210             jPanel.add(jlabelTip);
211             jlabelTip.setText("你答对了"+(Score.num-Score.errorCount)+"道题  "
212             +"答错了"+Score.errorCount+"道题");
213             jlabelTip.setBounds(100,Integer.parseInt(targetY)*2,Constant.JTF_INPUT_WIDTH*2,Constant.HEIGHT);
214         }
215     }
216 
217     public static void main(String[] args) {
218         ExercisesSwing  exercisesSwing=new ExercisesSwing();
219     }
220 }
ExercisesSwing.java

 

 

四、结对软件过程耗时估计与统计表

___________________________________________________________________________________________

 

PSP2.1

Personal Software Process Stages

Time Senior Student

Time

minute

Planning

计划

8

9

· Estimate

估计这个任务需要多少时间

12

25

Development

开发

90

50

· Analysis

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

20

30

· Design Spec

生成设计文档

0

0

· Design Review

设计复审

3

15

· Coding Standard

代码规范

0

10

· Design

具体设计

10

25

· Coding

具体编码

35

30

· Code Review

代码复审

10

25

· Test

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

15

15

Reporting

报告

9

9

·

测试报告

0

0

·

计算工作量

5

5

·

并提出过程改进计划

0

0

 

五、项目的分工与工作照片:

_________________________________________________________________________________________

黄曼金同学负责代码的主要测试和编写,代码功能的构思和编写,程序的总体布局,

而我负责复审代码及优化代码。例如:选择题目数量时,不能在点击题目数量的时候立即更改到相应数量的题目数,经检查调试,我加入了repaint()方法的使用,就可以做到,立马改题目数量,立马显示的效果。同伴在修改背景颜色时,有遇到一些小问题,例如再改颜色时,有些颜色无法更改,更改完没显示之类的问题。经检查发现是改颜色的地方出错,不应该改到主面板,要改到副面板,副面板是覆盖到主面板上面的,当副面板有颜色时,对主面板修改背景颜色,是无法看见其修改的。

 

六、项目运行截图

___________________________________________________________________________________________

1:题目的选择

2:背景颜色的选择:

3:题目的提示和输入:

 

 

七、项目感想

___________________________________________________________________________________________

在结对项目中,两个人做一件事情,速度会快很多,当一个人卡住,想不到解决办法的时候,或许另一个人就会有好的解决办法,有时候,一个人想出的编写思路,说出来之后另一个人又有可能给出更好的编写思路,两个人不断进步,程序不断优化。需要注意的是,写代码时一定要注意代码的规范,写好注释,不然有时候回看代码的时候,效率会降低。

posted @ 2018-10-29 09:10  TicTac1  阅读(206)  评论(1编辑  收藏  举报