【四则运算】软件工程个人项目实践
1、实验目的与要求
(1)掌握软件项目个人开发流程。
(2)掌握Coding.net上发布软件项目的操作方法。(使用的GitHub)
2、实验内容和步骤
任务1:
使用JAVA编程语言,独立完成一个3到5个运算符的四则运算练习的软件。(由于本人对Java的学习不够,所以选择了使用JavaScript来作为编程语言)
软件基本功能要求如下:
- 程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。(完成)
- 每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,你所出的练习题在运算过程中不得出现负数与非整数,比如不能出 3÷5+2=2.6,2-5+10=7等算式。(完成,但是由于自身算法的缺陷的缘故出现除法的几率很小)
- 练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。
- 当程序接收的参数为4时,以下为一个输出文件示例。
2018010203
13+17-1=29
11*15-5=160
3+10+4-16=1
15÷5+3-2=4
软件附加功能要求如下:(请有余力的同学完成)
- 支持有括号的运算式,包括出题与求解正确答案。注意,算式中存在的括号数必须大于2对,且不得超过运算符的个数。(未完成)
扩展程序功能支持真分数的出题与运算(只需要涵盖加减法即可),例如:1/6 + 1/8 + 2/3= 23/24。注意在实现本功能时,需支持运算时分数的自动化简,比如 1/2+1/6=2/3,而非4/6,且计算过程中与结果都须为真分数。(未完成)
3.psp时间表
PSP2.1 |
任务内容 |
计划共完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
8 |
15 |
· Estimate |
· 估计这个任务需要多少时间,并规划大致工作步骤 |
8 |
6 |
Development |
开发 |
300 |
490 |
· Analysis |
· 需求分析 (包括学习新技术) |
30
|
60 |
· Design Spec |
· 生成设计文档 |
10 |
12 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
4 |
6 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
3 |
3 |
· Design |
· 具体设计 |
10 |
15 |
· Coding |
· 具体编码 |
100 |
120 |
· Code Review |
· 代码复审 |
20 |
30 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
15 |
30 |
Reporting |
报告 |
15 |
20 |
· Test Report |
· 测试报告 |
3 |
2 |
· Size Measurement |
· 计算工作量 |
5 |
4 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
3 |
3 |
4.测试用例
5.部分method的介绍:
①随机生成运算符
// 生成j个运算符,存入数组中
function operatorArr(j){
var arr=[];
for ( i = j; i >= 0; i--) {
//随机生成一个k=0、1、2或3
var k=Math.ceil(Math.random()*10/2);
while(k>4){
k=Math.ceil(Math.random()*10/2);
}
//k为不同数字返回对应不同运算符
switch (k) {
case 1:arr[i] = "+";break;
case 2:arr[i] = "-";break;
case 3:arr[i] = "*";break;
case 4:arr[i] = "÷";break;
default:
break;
}
}
return arr;
}
②随机生成一个存放了计算数字的数组
//创建一个数组用于每隔一个数组单位放一个1-100的数字,一共放j个数字
function numberArr(j){
var numberArray=[];//数组存储随机生成的计算数字
//向numberArray填充随机数
for (var i = 1; i <= j; i++) {
numberArray[2*i-1]=Math.ceil(Math.random()*100);
}
return numberArray;
}
③判断所出的题是否符合每一步都没有负数和分数的情况,分两个函数分别判断
// 判断是否会有计算后为负数(如果有则重新出题)
//arr为判断的数组,i为数组开始的位置,只要有某一次不符合不是负数或分数的要求,就return -1,到最后都依然符合要求就返回1
function judgePositive(arr,i){
var array=[];//存储每次计算的两个数与一个计算符
var arr1=[];//用于浅拷贝arr[]
var equation;//用与存储算式
arr1=arr.concat();
//取值次数=计算次数=计算符的个数=arr.length/2-1,如果有一次计算结果为负,则返回-1
var r=0;
for(var i=0;i<arr1.length/2-1;i++){
var equation="";
//equation第一次取123号元素,第二次取12345号元素,1234567...
for (let j = 1; j <= r+3; j++) {
equation=equation+arr1[j];
}
if (eval(equation)<0) {
return -1;
}
r=r+2;
console.log(equation);
}
return 1;
}
//判断是否能除尽(无余数),如果有一次不能除尽则返回-1
//arr是判断的数组
function judgeDivision(arr){
var array=[],j=0;//array用于每次储存 "÷"出现的下标
var arr1=arr.concat();//用于浅拷贝数组参数arr
//储存 "÷"出现的下标
for(var i=0;i<=arr1.length;i++){
if(arr1[i]=="÷"){
array[j]=i;
j++;
}
}
//判断每次相除能否除尽,先判断是否有除号再判断能否除尽
if(array.length==0){
return 1;
}
for(var i=0;i<=array.length;i++){
var a=array.slice(arr1[i])[0];//a用于存储被除数
var b=array.slice(arr1[i+1])[0];//b用于存储除数
if(a%b!=0){
return -1;
}
}
return 1;
}
④计算出算式的答案
//计算
//arr[]为存放了运算符+数字的数组,j为数字的个数,
function count( arr, j) {
var ans=arr[1];
//运算j-1次
for(var i=1;i<=j*2;i++){
switch (arr[i+1]) {
case "+":
ans+=arr[i+2];
break;
case "-":
ans-=arr[i+2];
break;
case "*":
ans*=arr[i+2];
break;
case "÷":
ans/=arr[i+2];
break;
default:
break;
}
}
return ans;
}
⑤在html中生成题目
submitButton.onclick=function(){
//删除提交的按钮,防止后面又添加其进入数组answerArray中
problemAmoun.parentNode.removeChild(problemAmoun);
//判断出题数目是否是1-100,如果不是则变红
if (problemAmoun.value<1 || problemAmoun.value>100) {
problemAmoun.className="form-control warm";
}
else{
problemAmoun.className="form-control";//颜色变回正常
makeProblem.style.display="none";
solveProblem.style.display="block";
var n=problemAmoun.value;//题目数量为n
//生成n道题目并添加进html
for(let i=0;i<n;i++){
var j=opeNumber();//运算符数量为j
var numberArray=numberArr(j+1);//用于存储运算的数字,数字的个数等于运算符+1,生成数组,按1,3,5...顺序放入
var opeArray=operatorArr(j);//生成储存运算符的数组
//添加运算符到运算的数字中形成运算式
for (let i = 1; i <= j; i++) {
numberArray[2*i]=opeArray[i];
}
//判断是否同时满足无负数且无分数,如果不是则重新生成numberArr数组;
while(judgeDivision(numberArray)!=1 || judgePositive(numberArray,1)!=1) {
j=opeNumber();//运算符数量为j
numberArray=numberArr(j+1);//用于存储运算的数字,数字的个数等于运算符+1,生成数组,按1,3,5...顺序放入
opeArray=operatorArr(j);//生成储存运算符的数组
for (let i = 1; i <=j; i++) {
numberArray[2*i]=opeArray[i];
}
}
//向做题界面添加html
var divW=document.createElement("div");
var divI=document.createElement("div");
var label=document.createElement("label");
var input=document.createElement("input");
divW.className="form-group";
divI.className="col-sm-12";
label.className="col-sm-6 control-label";
input.className="form-control";
divW.appendChild(divI);
divI.appendChild(label);
divI.appendChild(input);
title.appendChild(divW);
//取出数组中的值,放入html中
numberArray.forEach(function (item,index) {
label.innerHTML = label.innerHTML + item;
});
console.log("计算出的答案为"+eval(label.innerHTML));
}
}
}
window.onload=function(){
solve.onclick=function () {
var answerArray=document.getElementsByClassName('form-control');//存放用户输入的答案的数组,之后用于与正确答案相比较
var titleArray=document.getElementsByClassName('control-label');//存放题目
for(var i=0;i<answerArray.length;i++){
var b=titleArray[i].innerHTML;
if(eval(b)!=answerArray[i].value){
answerArray[i].className="form-control warm";
}
else{
answerArray[i].className="form-control";
}
}
}
}
6.心得体会:
本次作业完成得非常的晚,之前由于本人的一些个人原因而耽误了课程与学习感到非常难受与愧疚,即使此次作业不会再录入成绩,也希望能够尽力完成他。
此次的作业是本人自己单独完成的,没有查阅和参考别人的作业或者资料,所以代码在有些地方可能不够好,还存在一些缺陷。比如,在生成的题目当中几乎没有除法出现,因为我的算法设置的是随机出现运算符和数字相结合而成一道题,然后再对这道题进行检验,如果在计算的某一步骤当中如果出现负数或者分数则重新生成一个新的算式,而又很难出现刚好能整除的除法在算式中,于是几乎没有除法出现。
在上传到git中的过程也让我十分困惑,最开始以为会和bb平台一样只要选择文件就能上传,没想到居然会这么复杂甚至会需要用cmd命令行,而网上的博客教程都非常简洁,几乎没有完整的一套上传到git远程仓库的介绍,这又给我造成了更大的困惑,后来在慕课网上找到了****跟着教程一点点的做才得以完成上传。
github:https://github.com/fishingNow/Homework----four-fundamental-operations-of-arithmetic