结对编程项目总结

前言

本博客对在个人编程的基础上进行的结对编程进行总结,主要包括代码的复用和结对编程中学到的经验教训。

结对编程分工:我负责(验证码注册模块,查重模块,保存账户信息模块,计算模块),队友负责UI界面(登陆界面,出题界面,做题界面,汇报界面,修改密码,弹窗模块)。

一、结对编程要求

1、所有功能通过图形化界面操作,可以是桌面应用,可以是网站(编程语言和技术不限); 2、用户注册功能。用户提供手机号码,点击注册将收到一个注册码,用户可使用该注册码完成注册; 3、用户完成注册后,界面提示设置密码,用户输入两次密码匹配后设置密码成功。密码6-10位,必须含大小写字母和数字。用户在登录状态下可修改密码,输入正确的原密码,再输入两次相同的新密码后修改密码成功; 4、密码设置成功后,跳转到选择界面,界面显示小学、初中和高中三个选项,用户点击其中之一后,提示用户输入需要生成的题目数量; 5、用户输入题目数量后,生成一张试卷(同一张卷子不能有相同题目,题目全部为选择题),界面显示第一题的题干和四个选项,用户选择四个选项中的一个后提交,界面显示第二题,…,直至最后一题; 6、最后一题提交后,界面显示分数,分数根据答对的百分比计算; 7、用户在分数界面可选择退出或继续做题。

二、代码实现

1.验证码注册模块

根据UI界面用户输入的手机号码,通过阿里云的API接口,返回一个随机的code作为验证码,实现验证码发送和接收验证功能。

public static SendSmsResponse sendSms(String tel,String code) throws ClientException {
       //可自助调整超时时间
       System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
       System.setProperty("sun.net.client.defaultReadTimeout", "10000");
       //初始化acsClient,暂不支持region化
       IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
       DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
       IAcsClient acsClient = new DefaultAcsClient(profile);
       //组装请求对象-具体描述见控制台-文档部分内容
       SendSmsRequest request = new SendSmsRequest();
       //必填:待发送手机号
       request.setPhoneNumbers(tel);
       //必填:短信签名-可在短信控制台中找到
       request.setSignName("中小学题目生成器初版");
       //必填:短信模板-可在短信控制台中找到
       request.setTemplateCode("SMS_204106386");
       //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
       request.setTemplateParam("{\"code\":"+code+"}");
       //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
       //request.setSmsUpExtendCode("90997");
       //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
       request.setOutId("yourOutId");
       //hint 此处可能会抛出异常,注意catch
       SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
       return sendSmsResponse;
  }

2.保存账户信息模块/查重模块

用户信息保存在名为account的txt文件里,在程序开始,程序将account信息存入一个ArrayList链表,在程序结束后,将ArrayList里的内容写回account文件,验证account文件即可进行查重判断

public static void SaveToLoc()throws IOException {
       FileOutputStream fos = null;
       fos = new FileOutputStream("src/Frame/"   + "account.txt"); //不覆盖原内容
       for (String s : al) {
           String msg = s + '\n';
           fos.write(msg.getBytes());
      }
       fos.close();
  }
public static void SaveToCur(){
       File file = new File("src/Frame/" + "account.txt");
       if (!file.exists()) {
           try {
               file.createNewFile();
          } catch (IOException e) {
               e.printStackTrace();
          }
      }

       try{
           FileReader fr = new FileReader("src/Frame/"  + "account.txt");
           BufferedReader bf = new BufferedReader(fr);
           String str;
           while ((str = bf.readLine()) != null) {
               al.add(str);
          }
           bf.close();
           fr.close();
      }
       catch (IOException e){
           e.printStackTrace();
      }
  }

3.计算模块

用随机生成二元运算符和运算数,然后把他们拼接成后缀表达式。根据题目的类型,随即插入根号等一元运算符,再通过栈,从后缀表达式中取字符串,根据字符串的内容来决定进行入栈还是出栈的操作,把后缀表达式翻译成中缀表达式。再利用栈,遍历一次后缀表达式,就可以计算出答案。

int num = (int) (0 + Math.random() * (4 - 0 + 1));   //获取0-4个 二元运算符
           ArrayList<String> houzhui = new ArrayList<>();
           int operands = (int) (1 + Math.random() * (100 - 1 + 1)); //操作数的取值范围是1-100
           houzhui.add(Integer.toString(operands));
//将后缀表达式翻译成中缀表达式
           Stack<String> stack = new Stack<>();
           int time=0;
           for (String str:houzhui){
               if (str.equals("sin")||str.equals("cos")||str.equals("tan")||str.equals("√")||str.equals("²")){
                   String popB=stack.pop();
                   if (str.equals("√")){
                       stack.push("√"+"("+popB+")");
                  }
                   if (str.equals("²")){
                       stack.push("("+popB+")"+"²");
                  }
                   if (str.equals("sin")){
                       stack.push("sin"+"("+popB+")");
                  }
                   if (str.equals("cos")){
                       stack.push("cos"+"("+popB+")");
                  }
                   if (str.equals("tan")){
                       stack.push("tan"+"("+popB+")");
                  }
              }
              ......
public static String[] Calculate(ArrayList<String> houzhui) {
      //str是一个后缀表达式
      Stack<Double> stack = new Stack<Double>();
      Double result;

      for (String str:houzhui) {
          if(str.equals("√")||str.equals("²")||str.equals("sin")||str.equals("cos")||str.equals("tan")){
              double popB = stack.pop();
              if (str.equals("√")){
                  if (popB!=0)
                      stack.push(Math.sqrt(popB));
                  else
                      stack.push(1.0);
              }
              if (str.equals("²")){
                  stack.push(Math.pow(popB,2));
              }
              if (str.equals("sin")){
                  stack.push(Math.sin(popB));
              }
              if (str.equals("cos")){
                  stack.push(Math.cos(popB));
              }
              if (str.equals("tan")){
                  stack.push(Math.tan(popB));
              }
          }

三、代码复用

1.生成试卷

根据用户选择的题目类型和数量生成题目(示例): 给函数增加了返回值,函数返回一个字符串数组,每一个字符串代表一个题目,传入的参数分别是题目类型,题目保存的路径和题目数量

2.初始化界面

包括手机号码和验证码输入框、获取验证码按钮和注册按钮等,给按钮添加监听器,点击按钮后发送验证码或启动注册程序,注册成功后将账户信息保存在本地

3.登录界面

用户注册后,跳转到设置用户名和密码界面。界面包括用户名和密码输入框以及确认按钮。有一个按钮,点击可以切换隐藏密码和查看密码,此功能是通过一个JTextField和一个JPasswordField切换实现的

4.选择题目界面

包含一个单选框和一个数字输入框,用户输入题目类型和数量。题目类型为在(小学、初中、高中)三个选项中单选,数量为10-30之间的数字

5.做题界面

从GenerateTest()函数的返回值得到试卷,然后再用Calculate()函数得到备选答案,把备选答案加入单选按钮,放置在面板上。用户可点击”上一题“”下一题“按钮来切换当前的题目,做过的题目答案会保存

6.汇报界面

在用户做完全部题目后,界面显示分数,用户可选择继续做题或者退出

7.用户信息

用户信息保存在名为account的txt文件里,在程序开始,程序将account信息存入一个ArrayList链表,在程序结束后,将ArrayList里的内容写回account文件

posted @ 2020-10-09 19:50  Warma  阅读(268)  评论(0)    收藏  举报