Foreword: This project is a part of pair programming task. We implement an command-line based arithmometer by JavaScript in Node.js environment. ......

Project Elaboration

In this project, We are required to actualize a command line program for automatically generating four arithmetic problems for primary schools.

Now the project is still in progress, we have so far finished exercise judgement, and soon we will update more information.

Team members: Wu Tang Huang, Zhang Guo Jun

GitHub: https://github.com/m8705/Arithmometer

Detail Description

Program usage

Generate problem file:

node e.js -n 10 -r 10

Validate exercise:

node e.js -e exercisefile.txt -a answerfile.txt

Parameter and regulation

  1. Use -n parameter to control the number of generated questions ( 1 ~ 10000 ).
  2. Use -r parameter to control the range of numeric value (natural number, true fraction and true fraction denominator) in the title ( 1 ~ 100 ).
  3. The calculation process in the generated problem does not produce a negative number, that is, if there is a sub-expression in the arithmetic expression, such as e1 - e2, then e1 < e2
  4. If there is a subexpression e1 ÷ e2 in the generated exercise, the result should be true score.
  5. There are no more than 3 operators in each problem.
  6. The problem generated by the program running at one time can not be repeated, that is, any two problems can not be transformed into the same problem by the finite number of exchange + and * arithmetic expressions.The generated problem is stored in the Exercises.txt file under the current directory of the execution program.
  7. At the same time, the answers to all the questions are computed and stored in the Answers.txt file in the current directory of the execution program.
  8. The program should support the generation of ten thousand problems.
  9. Program support for a given question file and answer file, determine the right and wrong answers and statistics, statistics output to the file Grade.txt

Code Preview

Convert fraction

 function convert(str){//将任何数转成真分数(小数不换)

     //整数 2 = 2'1/1
//真分数 3/8
//假分数 5/3
//带分数 1'1/2 //console.log(str) if( str.indexOf("/") >= 0 ){//真分数或带分数 if( str.indexOf("'") >= 0 ){//带分数 first = str.split("'")[0];
second = str.split("'")[1]; up = second.split("/")[0];
down = second.split("/")[1]; if( ( up === down ) || ( down === "1" ) ){//带分数情况下,不可能存在分子分母相同或分母为1的情况
return "ERROR";
} str = ( (+first) * (+down) + (+up) ) + "/" + down; }
else{//真分数
;
} }
else{//整数 str = str + "/1"; } return str
//console.log(str);
}

Fraction calculation

 function calculate(num1,num2,operator){//根据数字和符号进行分数运算

     var n1 = [];
var n2 = []; var result; n1 = convert(num1).split( "/" ); // [ 0分子,1分母 ]
n2 = convert(num2).split( "/" ); // [ 0分子,1分母 ] switch(operator){
case "+":
result = (n1[0]*n2[1]+n2[0]*n1[1]) + "/" + (n1[1]*n2[1]);
break;
case "-":
result = (n1[0]*n2[1]-n2[0]*n1[1]) + "/" + (n1[1]*n2[1]);
break;
case "*":
result = (n1[0]*n2[0]) + "/" + (n1[1]*n2[1]);
break;
case "/":
result = (n1[0]*n2[1]) + "/" + (n1[1]*n2[0]);
break;
} //console.log(result);
return result; }

Produce symbol

 function produceSymbol(){//产生符号

     var symbol = Math.random();
var symbolNum; if( symbol <= 1/3 ){//生成一个符号
symbolNum = 1;
}
else if( symbol <= 2/3 ){//生成两个符号
symbolNum = 2;
}
else{//生成三个符号
symbolNum = 3;
} var symbolChoice = [];
var tmp;
for(var a = 0; a < symbolNum; a++){//用概率决定符号 tmp = Math.random();
if( tmp <= 1/4 ){
symbolChoice.push("+");
}
else if( tmp <= 2/4 ){
symbolChoice.push("-");
}
else if( tmp <= 3/4 ){
symbolChoice.push("*");
}
else{
symbolChoice.push("/");
} } return symbolChoice; }

Produce number

 function produceNumber(symbolNum, range){//产生数字

     var symbolChoice = produceSymbol();

     var numType;
var numChoice = [];
var up, down; for( var b = 0; b < symbolNum + 1; b++ ){//用概率决定数字 numType = Math.random(); if( numType <= 7 / 10 ){//生成整数 numChoice.push( Math.floor(Math.random()*range) + "" ); }
else{//生成分数或1(避免生成分子或分母为0) up = Math.ceil( Math.random() * range );//向上取整
down = Math.ceil( Math.random() * range );//向上取整 if( up === down ){//分子分母相同
numChoice.push("1");
continue;
} var tmp = Math.random();//是否产生带分数
if( tmp <= 1/4 ){//产生带分数 while(up <= down || (up%down === 0) ){//重新产生带分数 up = Math.ceil( Math.random() * range );//向上取整
down = Math.ceil( Math.random() * range );//向上取整 } numChoice.push(
(up - up%down)/down +
"'" +
(up%down / gcd(up%down,down)) +
"/" +
down / gcd(up%down,down)
); }
else{//产生分数 numChoice.push( up + "/" + down ); } } }
return numChoice;
}

Produce array

 function produceRightArray(n, range){//产生n组符合规定的数字和符号

     var rightArray = [];
var flag; for(var a = 0; a < n; a++){//循环n次 flag = ""; symbolChoice = produceSymbol();
numChoice = produceNumber(symbolChoice.length,range); for(var b = 0; b < symbolChoice.length; b++ ){//遍历检查每个符号 if( symbolChoice[b] === "*" || symbolChoice[b] === "/" ){ if(numChoice[b] === "0" || numChoice[b+1] === "0"){ flag = "err";
a--;
break; } } } //console.log(a + flag); if(flag !== "err"){
rightArray.push([
symbolChoice,numChoice
]);
} } //console.log(rightArray);
return rightArray; }

Core computation

 function produceExercise(n,range){//产生n个习题(题目+答案)

     var expression = [];
var tmp = "";//保存用于产生结果的算式
var tmp1 = "";//保存用于产生题目的算式 var rightArray = produceRightArray(n,range); for(var a = 0; a < n; a++ ){//遍历每个产生的结果数组,分别验算结果是否非负 tmp = "";
tmp1 = ""
tmp += "(" + convert(rightArray[a][1][0]) + ")" ;
tmp1 += rightArray[a][1][0]; for(var b = 0; b < rightArray[a][0].length; b++ ){//符号+数字
tmp += rightArray[a][0][b] + "(" + convert(rightArray[a][1][b+1]) + ")";
tmp1 += " " + rightArray[a][0][b] + " " + rightArray[a][1][b+1];
} while( eval(tmp) < 0 ){//不允许产生算式最终值小于0的情况 rightArray[a] = produceRightArray(1,range)[0]; tmp = "";
tmp1 = "";
tmp += convert(rightArray[a][1][0]);
tmp1 += rightArray[a][1][0]; for(var c = 0; c < rightArray[a][0].length; c++ ){//符号+数字
tmp += rightArray[a][0][c] + "(" + convert(rightArray[a][1][c+1]) + ")";
tmp1 += " " + rightArray[a][0][c] + " " + rightArray[a][1][c+1];
} }
//console.log(tmp);
expression.push(tmp1);
} //console.log(expression) //console.log(rightArray); //遍历符号列表,根据优先级(先乘除,后加减)对数进行运算,并更新运算结果(逐一替换)至数组 var tmpArray = rightArray;
var operator; var symIndex;
var numIndex1, numIndex2; var answer = []; for(var d = 0; d < n; d++){ for(var e = 0; e < tmpArray[d][0].length; e++){//先进行乘除运算 operator = tmpArray[d][0][e]; switch(operator){ case "*":
//console.log(tmpArray[d][1][e],tmpArray[d][1][e+1]); replaceNumber(tmpArray[d][1],tmpArray[d][1][e],calculate( convert(tmpArray[d][1][e]),convert(tmpArray[d][1][e+1]),operator ) );
removeOperator(tmpArray[d][0],"*");
e--;
break; case "/":
//console.log(tmpArray[d][1][e],tmpArray[d][1][e+1]); replaceNumber(tmpArray[d][1],tmpArray[d][1][e],calculate( convert(tmpArray[d][1][e]),convert(tmpArray[d][1][e+1]),operator ) );
removeOperator(tmpArray[d][0],"/");
e--;
break; } } //console.log(tmpArray) for(var f = 0; f < tmpArray[d][0].length; f++){//后进行加减运算 operator = tmpArray[d][0][f]; switch(operator){ case "+":
//console.log(tmpArray[d][1][f],tmpArray[d][1][f+1]); replaceNumber(tmpArray[d][1],tmpArray[d][1][f],calculate( convert(tmpArray[d][1][f]),convert(tmpArray[d][1][f+1]),operator ) );
removeOperator(tmpArray[d][0],"+");
f--;
break; case "-":
//console.log(tmpArray[d][1][f],tmpArray[d][1][f+1]); replaceNumber(tmpArray[d][1],tmpArray[d][1][f],calculate( convert(tmpArray[d][1][f]),convert(tmpArray[d][1][f+1]),operator ) );
removeOperator(tmpArray[d][0],"-");
f--;
break; } } answer.push( simplify(tmpArray[d][1][0]) );
} //console.log(answer); return [expression,answer]; }

PSP 2.1

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 120  60

· Estimate

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

 15  15

Development

开发

 360  300

· Analysis

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

 60  60

· Design Spec

· 生成设计文档

 30  30

· Design Review

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

 30  30

· Coding Standard

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

 15  15

· Design

· 具体设计

 60  60

· Coding

· 具体编码

 120  100

· Code Review

· 代码复审

 120  160

· Test

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

 40  40

· Reporting

· 报告

 90  90

· Test Report

· 测试报告

 60  60

· Size Measurement

· 计算工作量

 30  30

· Postmortem & Process Improvement Plan

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

 30  30

合计

  1180  1080

Screenshot

Produce

Judge

Project Summary

[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()

Arithmometer: A Node.js implementation的更多相关文章

  1. Edge.js:让.NET和Node.js代码比翼齐飞

    通过Edge.js项目,你可以在一个进程中同时运行Node.js和.NET代码.在本文中,我将会论述这个项目背后的动机,并描述Edge.js提供的基本机制.随后将探讨一些Edge.js应用场景,它在这 ...

  2. Node.js Web 开发框架大全《中间件篇》

    这篇文章与大家分享优秀的 Node.js 中间件模块.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处 ...

  3. Node.js 入门手册:那些最流行的 Web 开发框架

    这篇文章与大家分享最流行的 Node.js Web 开发框架.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用程序,编 ...

  4. Understanding Asynchronous IO With Python 3.4's Asyncio And Node.js

    [转自]http://sahandsaba.com/understanding-asyncio-node-js-python-3-4.html Introduction I spent this su ...

  5. Node.js timer的优化故事

    前几天nodejs发布了新版本4.0,其中涉及到一个更新比较多的模块,那就是下面要介绍的timer模块. timers: Improved timer performance from porting ...

  6. KoaHub.JS用于Node.js的可移植Unix shell命令程序代码

    shelljs Portable Unix shell commands for Node.js ShellJS - Unix shell commands for Node.js     Shell ...

  7. (译+注解)node.js的C++扩展入门

    声明:本文主要翻译自node.js addons官方文档.部分解释为作者自己添加. 编程环境: 1. 操作系统 Mac OS X 10.9.51. node.js v4.4.22. npm v3.9. ...

  8. Practical Node.js (2018版) 第9章: 使用WebSocket建立实时程序,原生的WebSocket使用介绍,Socket.IO的基本使用介绍。

    Real-Time Apps with WebSocket, Socket.IO, and DerbyJS 实时程序的使用变得越来越广泛,如传统的交易,游戏,社交,开发工具DevOps tools, ...

  9. Practical Node.js (2018版) 第7章:Boosting Node.js and Mongoose

    参考:博客 https://www.cnblogs.com/chentianwei/p/10268346.html 参考: mongoose官网(https://mongoosejs.com/docs ...

随机推荐

  1. fhq treap抄袭笔记

    目录 碎碎念 点一下 注意!!! 模板 fhq treap 碎碎念 我咋感觉合并这么像左偏树呢 ps:难道你们的treap都是小头堆的吗 fhq真的是神人 现在看以前学的splay是有点恶心,尤其是压 ...

  2. 终于在nowcoder爆发了的懒惰

    题目 这类题目我实在忍不了了 Emma,随便做个nowcode比赛题吧,我在oj上也没找到 题意 求\(\sum_{L=1}^{n}\sum_{R=i}^{n}a[k](L<=k<=R)\ ...

  3. 将DevExpress.Utils.ImageCollection变量的image导出

    private void tspBtnExportExcel_Click(object sender, EventArgs e) { //暂时用来导出图片 string filePath = Syst ...

  4. 【第十章】 springboot + logback

    logback是boot默认的日志首选,个人觉得是最好的日志实现(比log4j好) 下边,在之前的代码基础上增加一个功能,该功能要实现mybatis的and or联查功能,并通过logback日志在控 ...

  5. 2018 leetcode

    2018-8-6 Lowest Common Ancestor of a Binary Tree(二叉树) Merge Intervals(排序) 2018-8-7 Maximal Square (动 ...

  6. [loss]Triphard loss优雅的写法

    之前一直自己手写各种triphard,triplet损失函数, 写的比较暴力,然后今天一个学长给我在github上看了一个别人的triphard的写法,一开始没看懂,用的pytorch函数没怎么见过, ...

  7. UVa 11300 分金币

    https://vjudge.net/problem/UVA-11300 题意: 圆桌上有n个人,每个人都有一定的初始金币,每个人可以给他旁边的人一些金币,最终使每个人的金币数相等.计算最少需要转手的 ...

  8. Ubuntu 16.04 kinetic 编译指定包

    编译指定包 catkin_make -DCATKIN_WHITELIST_PACKAGES=baoming 使用上述命令后catkin_make会一直编译上面那个包,想要编译全部包,使用 catkin ...

  9. 棋盘覆盖问题(算法分析)(Java版)

    1.问题描述: 在一个2k×2k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有种情形.因而对任何 k≥0,有4k种不 ...

  10. 监督学习--k近邻算法

    2017-07-20 15:18:25 k近邻(k-Nearest Neighbour, 简称kNN)学习是一种常用的监督学习方法,其工作机制非常简单,对某个给定的测试样本,基于某种距离度量找出训练集 ...