GIT地址 点一下
GIT用户名 Mretron
学号后五位 62517
博客地址 点一下
作业链接 点一下

在征得陈老师的同意下,使用java面向对象语言+IDEA工具完成本次作业

一、前期配置

虽然说VS是宇宙最好的集成开发编程软件,但是咱们的IDEA也不是等闲之辈,她的美丽唯有心人耐心发现,方能觉察此番美景。

话不多说,咱么直接一探究竟。

首先官网下载好IDEA,以及Git。

以及准备好自己github的项目(我已经在助教的github上fork到自己的账号了)

打开IDEA。

请注意,咱们现在需要去配置Git->然后克隆项目到本地。

IDEA面板中->File->Setting->Version Control -> Git->如图配置

现在咱们已经配置了git,那么现在就开始clone一个项目到本地,进行开发

File->Project from version Control... -> Git

输入你想要克隆的项目URL->点击Clone即可等待完成

克隆完成后,在当前文件夹下创建一个module项目,即可开始在ertron/src文件夹下编写代码:

二、编写代码

在完成了上述配置任务过后,即可开始愉悦地编码了。

咱们先来看看题目:

阿超家里的孩子上小学一年级了,这个暑假老师给家长们布置了一个作业:家长每天要给孩子出一些合理的,但要有些难度的四则运算题目,并且家长要对孩子的作业打分记录。

作为程序员的阿超心想,既然每天都需要出题,那何不做一个可以自动生成小学四则运算题目与解决题目的命令行 “软件”呢。他把老师的话翻译一下,就形成了这个软件的需求:

  • 程序接收一个命令行参数 n,然后随机产生 n 道加减乘除(分别使用符号+-*/来表示)练习题,每个数字在 0100 之间,运算符在 2 个 到 3 个之间。
  • 由于阿超的孩子才上一年级,并不知道分数。所以软件所出的练习题在运算过程中不得出现非整数,比如不能出现 3÷5+2=2.6 这样的算式。
  • 练习题生成好后,将生成的 n 道练习题及其对应的正确答案输出到一个文件 subject.txt 中。
  • 当程序接收的参数为4时,以下为一个输出文件示例。

13+17-1=29

11*15-5=160

3+10+4-16=1

15÷5+3-2=4

我的思路:

既然是随机生成式子,再利用题目的一些规则(不能有分数,运算符在2个到3个之间,数字在0和100之间),可以借鉴后续表达式以及简化版的逆波兰算法(利用两个栈分别存储数字,和运算符,进行及时计算)。

编写代码:

创建了两个类CalculatorMachine和CantCalculateException

  • 类CalculatorMachine:计算机机器类,提供一些方法产生符合题目的式子
  • CantCalculateException:自定义异常类,如果遇到不符合题目的计算(出现了分数,或者除以0),则抛出自定义的这个异常,进行重新生成式子,直到符合题意

CalculatorMachine.java中的私有属性,详情作用请看注释:

    /**
* 用于存储生成的题目,使用Set集合数据结构使得题目不会产生重复
*/
private HashSet<String> problem = new HashSet<>(); /**
* 用于存储数字的栈
*/
private Stack<Integer> numbers = new Stack<>(); /**
* 用于存储符号的栈
*/
private Stack<Integer> operators = new Stack<>(); /**
* 用与生成随机数
* random.nextInt(20) :即可得到20以内不包含20的随机数
*/
private Random random = new Random();

public void getAll()方法:调用其他方法

    /**
* 传入num题目数目
* 即可将题目写入到subject.txt文件中
* @param num 代表需要的题目数量
* @return 没有任何问题,即返回true代表生成成功
*/
public void getAll(int num){ // 循环得到式子直到满足数目
while(problem.size() < num) {
getOne();
}
if(writeToFile()) {
System.out.println("已经根据你的要求生成" + num + "个式子!");
} }

public void getOne()方法:生成一个符合要求的算式并且后续表达式得到结果

    /**
* 用于生成一个符合要求的算式
* 使用后续表达式得到结果
*/
public void getOne() { // 用来保存生成的当前式子
String result = ""; // 运算符的个数为 2 或者 3 个
int operator_count = random.nextInt(2)+2; //数字的个数,根据题意,两个符号,则代表3个计算数,三个符号,则代表4个计算数
int num_count = operator_count == 2 ? 3: 4; // 根据后续表达式就搞定了两个栈的东西 61+47*96=4573
for(int i = 0; i < operator_count + num_count ; i++) {
// 如果是偶数,则代表着数数字
if(i%2==0) {
// 在数字栈中存入一个范围内的随机数
numbers.push(random.nextInt(101));
// 进行符号保存
result += numbers.peek();
// 如果是奇数,则代表着符号位
} else if(i%2!=0) {
// 1:+ , 2:- , 3:* 4:/
int opertor = random.nextInt(4) + 1;
// 如果遇到+ - 准备入栈顶为 * /的话,需要进行计算
while(!operators.empty() && opertor <=2 && operators.peek() >=3) {
result = calculateUtil(result);
}
// 这个符号符合当前栈的规则,则入栈
operators.push(opertor);
// 记录这个符号
if(operators.peek()==1) {
result += '+';
} else if(operators.peek() == 2){
result += '-';
} else if(operators.peek() == 3){
result += '*';
} else if(operators.peek() == 4){
result += '÷';
}
}
} // 根据剩余的栈计算最后的值
while(!operators.empty()) {
result = calculateUtil(result);
}
// 如果最后的计算结果为负数,直接返回,放弃此次的式子
if(numbers.peek()<0){
return;
}
// 最后加上等于符号
result += '=';
// 走到这一步,说明这个式子没有问题,符合题意
// 所以放入到set集合中
problem.add(result+=numbers.pop());
}

private int calculator(int a, int b, int operator):根据符号计算

 /**
* 根据符号计算
*/
private int calculator(int a, int b, int operator) throws ArithmeticException, CantCalculateException { if(operator == 1) {
return a+b;
} else if(operator == 2) {
return a-b;
} else if(operator == 3) {
return a*b;
} else if(operator == 4) {
// 如果不能整除,则抛出我们自定义的Exception
if(a<b || a%b != 0) {
throw new CantCalculateException();
}
return a/b;
}
return 0;
}

private String calculateUtil(String result)方法:进行后续表达式特殊计算

    /**
* 进行后续表达式特殊计算
* + - 入栈顶为 * / 的情况
* 除法带有分数的情况
* @param result
* @return
*/
private String calculateUtil(String result){ int a = numbers.pop();
int b = numbers.pop(); try {
int this_operator = operators.pop();
if(!operators.isEmpty() && this_operator==2 && operators.peek()==2) {
numbers.push(calculator(b,a,1));
}else if (!operators.isEmpty() && this_operator==4 && operators.peek()==4) {
numbers.push(calculator(b,a,3));
}
else {
numbers.push(calculator(b,a,this_operator));
} } catch (CantCalculateException e) { int pr_b = b;
a = random.nextInt(101);
b = random.nextInt(101);
// a除数不能为0,满足b能够整除a,满足b>a
while (a == 0 || b % a != 0 || b < a || b > 100) {
a = random.nextInt(101);
b = random.nextInt(101) + a;
}
numbers.push(b);
numbers.push(a);
operators.push(4);
result = result.substring(0, result.indexOf(pr_b + ""));
result += b;
result += '÷';
result += a;
}
return result; }

private boolean writeToFile():将生成的所有式子写入到subject.txt

    /**
* 将生成的所有式子写入到subject.txt
* @return
*/
private boolean writeToFile() {
File file = new File("subject.txt");
try{
if(!file.exists()) {
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file.getAbsoluteFile());
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
for(String s : problem) {
bufferedWriter.write(s);
bufferedWriter.newLine();
}
bufferedWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}

三、单元测试与回归测试

对于java来说有专门的junit单元测试包,非常方便进行单元测试。

第一步:在需要测试类中Ctrl+Alt+T出现单元测试提示框 -> Create New Test...

第二步:在测试类中调用需要测试的类的方法

第三步:运行测试类,查看测试结果,是否成功

测试完成,上述程序符合题目要求且成功运行

四、调试

单步调试有利于实时看到每一步的代码中变量的值变化。

非常适合用于排错。

五、性能测试

JProfiler是用于分析J2EE软件性能瓶颈并能准确定位到Java类或者方法有效解决性能问题的主流工具,它通常需要与性能测试工具如:LoadRunner配合使用,因为往往只有当系统处于压力状态下才能反映出性能问题。

所以我采用JProfiler进行性能测试。

下载安装JProfiler过后需要在IDEA进行配置,首先File->Setting->Plugins搜索下载JProfiler插件

安装完插件过后,配置JProfiler的启动程序的地址。

配置完毕即可点击左边的JProfiler启动检测

提交代码至源库

首先Commit提交修改的代码到本地仓库

Commit过后push到自己的github账号上面

登录自己的github账号去检查是否push成功

提交到源库

总结:

其实在之前就用过git进行push自己的项目至网站。但是并没有版本控制的意识,只是当做代码仓库罢了。

得益于此次git课程的学习,算是对了一个项目如何利用git协同协作,提交自己的更新代码至源库,对以后的项目管理更为深刻。

想提一下自己完成的这个程序算法,借用了后续表达式,逆波兰算法,后续表达式可以使得计算机更为方便地计算数据,当然实现来说可能会难一点。在完成这个算法的过程中,为了满足题意:不能出现分数,我自己还主观地认为一年级的朋友应该不会负数,所以自己增加了这样的限定。

最后,完成过后,觉得自己的一些编程习惯还是需要改变,比如有些代码太过于重复,进行提炼为一个方法,增加代码的可重用性,使得代码更为简洁。所以,可能整个程序的代码看起来就是一会儿调用另一个方法。

既然有这样的不断调用其他方法的结构,那么代码中的注释一定不能少。自己也在学着写标准的注释结构。使得阅读代码起来更符合规范,且方便。

  • 比如,类上面的注释使用/**

  • 方法内部的注释使用双斜杠,并且内容需要与符号空一格

还需要学习的东西很多,但是在课程的帮助下也算踏实

《构建之法》个人第二次作业之git学习的更多相关文章

  1. 熟悉GitHub、VS工具的使用(《构建之法》第二次作业)

    GIT地址 https://github.com/slothph GIT用户名 slothph 学号后五位    62323 博客地址 https://www.cnblogs.com/slothph/ ...

  2. JAVA第二次作业展示与学习心得

    JAVA第二次作业展示与学习心得 在这一次作业中,我学习了复选框,密码框两种新的组件,并通过一个邮箱登录界面将两种组件运用了起来.具体的使用方法和其他得组件并没有什么大的不同. 另外我通过查阅资料使用 ...

  3. 构建之法助教园地第一次作业--点评<西北师范大学|李晓婷>

    一 博客点评 第一次作业--准备篇:https://www.cnblogs.com/Mookiepiece/p/10464606.html#4192515 点评内容: 首先,你对电脑很感兴趣,兴趣就是 ...

  4. 2015-2016-1 学期《软件工程》学生名单-- PS:教材使用《构建之法》第二版 --邹欣著

    1208053044 王威 男 1313023001 饶阳梅 女 1313023002 应蕾蕾 女 1313023004 袁立萍 女 1313023005 黎洋阳 女 1313023006 蒋欣 女 ...

  5. 第二次作业-熟悉git

    GIT地址 https://github.com/gentlemanzq/yunsuanhomework GIT用户名  gentlemanzq 学号后五位  62320 博客地址 https://w ...

  6. 第二次作业:Git的安装与使用

    ---恢复内容开始--- 本次作业要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2103 1.首先安装git bash软件, ...

  7. 软件工程(GZSD2015)第二次作业文档模板

    题目: (此处列出题目) 需求分析: 基本功能 基本功能点1 基本功能点2 ... 扩展功能(可选) 高级功能(可选) 设计 设计点1 设计点2 ... 代码实现 // code here 程序截图 ...

  8. <<构建之法>>略读感想

    经过对构建之法这本书的快速阅读和学习,我有以下疑问. 1.对软件工程来说是应该更注重结果和功能的实现还是更注重代码的易读和完整? 2.应该怎样平衡不同用户的不同需求以达到使大多数人满意的目的? 3.应 ...

  9. 软件工程(GZSD2015) 第二次作业文档模板

    题目: (此处列出题目) 需求分析: 基本功能 基本功能点1 基本功能点2 ... 扩展功能(可选) 高级功能(可选) 设计 设计点1 设计点2 ... 代码实现 // code here 程序截图 ...

随机推荐

  1. Nginx学习之入门

    1. 概念   (1) 什么是nginx?    Nginx (engine x) 是一款轻量级的Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器.   (2) 什么是反向代 ...

  2. An unexpected exception occurred while binding a dynamic operation 错误的一种情况

    这种错误,出现在dynamic传值的时候,无法动态访问变量. 出错原因是: 使用了嵌套类,class里面又定义了class

  3. Kubernetes 使用 Weave Scope 监控集群(十七)

    目录 一.安装 二.使用 Scope 2.1.拓扑结构 2.2.在线操作 2.3.强大的搜索功能 创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所 ...

  4. SignalR 填坑记

    1.发送文字消息没有问题,如何发送文件消息 SignalR可以将参数序列化和反序列化. 这些参数被序列化的格式叫做Hub 协议, 所以Hub协议就是一种用来序列化和反序列化的格式. Hub协议的默认协 ...

  5. spark sc.textFile() 指定换行符

    直接上代码 package com.jason.spark23 import org.apache.spark.sql.SparkSession import org.apache.spark.Spa ...

  6. 验证Prometheus alertmanager邮件发送

    新环境上配置alertmanager时出现了“Client was not authenticated to send anonymous mail during MAIL FROM”错误,但老环境上 ...

  7. Spring Boot 项目的 API 接口防刷

    首先是写一个注解类 拦截器中实现 注册到springboot中 在Controller中加入注解 说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考 一,技术要点:springbo ...

  8. autocomplete undefined一例解决办法

    项目中一个页面jqueryui与extjs混用.当使用autocomplete时,会报undefined. 解决办法增加 var jq = jQuery.noConflict(true); 然后使用j ...

  9. flask---快速使用

    初识falsk django是大而全面的框架,flask是个轻量级的框架. flask快速开发网站 flask可以使用很少的代码就可以直接完成一个项目(6,7行代码),如下: from flask i ...

  10. Windows10下QT5.13.2安装mingw64/MYSQL8.0驱动

    开始之前,先将编译器的路径添加到系统环境变量. 我的QT所以sql驱动是在下面这个目录中(大家在自己Qt的安装目录找到对应的文件夹就行,下面的路径也是如此), E:\qt\5.13.2\mingw73 ...