const _isNumber = require(‘../share/utils‘).isNumber
const getRandom = require(‘../share/utils‘).getRandom
const getResult = require(‘./stack‘)
const print = require(‘../share/utils‘).printf
const _ = require(‘underscore‘)
const operator = [‘+‘, ‘-‘, ‘*‘, ‘÷‘]
const _toString = Object.prototype.toString
/**
* 随机获得一个运算符
* @returns {string}
*/
function getOperator() {
return operator[Math.floor(Math.random() * (3 + 1))]
}
/**
*
* @param qus 提交的答案
* @param ans 正确的答案
* @returns {*}
*/
function verifyAnswer(qus, ans) {
let statistic
if (_toString.call(qus) !== ‘[object Array]‘ || _toString.call(ans) !== ‘[object Array]‘) {
throw new Error(‘Please dont set the poison for my code‘)
}
return statistic
}
//判断运算式子结果是否大于0
const _positive = function (expression) {
return getResult(expression) >= 0
}
/**
* 生成答案
* @param qus 传入生成计算式子返回的数组
* @returns {[‘1‘, ‘2‘, ...]}
*/
const answer = function (qus) {
if (_toString.call(qus) !== ‘[object Array]‘) {
throw new Error(qus + ‘is not a Array‘)
}
let answer = []
for (let i = 0; i < qus.length; i++) {
let temp = qus[i].split(‘=‘)[0]
temp = temp.substring(0, temp.length - 1)
answer.push(getResult(temp))
}
return answer
}
/**
* 生成计算表达式
* @param number 传入你要生成多少条式子的数量
* @returns {[‘1 + 1 =‘, ...]}
*/
const createExpression = function(number) {
if(!_isNumber(number)) {
throw new Error(`The ${number} is not a number type, please check again!`)
}
let result = []
let operands = null
let output = ‘‘
let index = 0
while(index !== number) {
operands = Math.floor(Math.random()* 3 + 1)
switch(operands) {
case 1: {
output = `${getRandom()} ${getOperator()} ${getRandom()}`
if(_positive(output)) {
result.push(`${output} = `)
index++
}
break
}
case 2: {
output = `${getRandom()} ${getOperator()} ${getRandom()} ${getOperator()} ${getRandom()}`
if(_positive(output)) {
result.push(`${output} = `)
index++
}
break
}
case 3: {
output = `${getRandom()} ${getOperator()} ${getRandom()} ${getOperator()} ${getRandom()} ${getOperator()} ${getRandom()}`
if(_positive(output)) {
result.push(`${output} = `)
index++
}
break
}
default: {
throw new Error(‘operands is not in the range of 3‘)
}
}
}
return result
}
module.exports = {
createExpression: createExpression,
answer: answer
}
//判断是假分数还是带分数
const bandFraction = function (fraction) {
let temp = fraction.split(‘/‘)
let result = Number(temp[0]) / Number(temp[1])
if (result > 1) {
return `${Math.floor(result)}^${Number(temp[0] - Number(Math.floor(result)) * temp[1] + 1)}/${temp[1]}`
} else if (result === 1){
return `1`
} else {
return fraction
}
}
//随机返回分数或者是整数
//Math.floor(Math.random()*(m-n+1)+n)
const getRandom = function() {
//随机决定是生成整数还是分数1表示整数,0表示分数
let isZ = Math.round(Math.random())
if(isZ) {
return Math.floor(Math.random() * 9 + 1)
} else {
let Molecule = Math.ceil(Math.random() * 9 + 1)
let Denominator = Math.ceil(Math.random() * (Molecule * 10 - 1 + 1) + 1)
return bandFraction(`${Denominator}/${Molecule}`)
}
}
产生思路说明:getRandom函数是决定随机生成分数还是自然数,使用一个随机产生0和1的变量决定产生哪一个,0产生分数,1产生自然数。生成计算表达式的时候也使用一个产生1-3的随机变量,决定该计算式子的长度,1表示两个操作数一个计算符号,2表示三个操作数两个运算符,3以此类推。生成一条计算式子的每一个操作数都调用一次getRandom产生随机操作数。整体思路就是这样。
/**
* 符号优先级比较
* @param operator_one
* @param operator_two
* @returns {boolean}
*/
const operatorRank = function (operator_one, operator_two) {
if(operator_one === void 0) {
throw new Error(‘you not have a expression‘)
}
if (operator_two === undefined) {
return true
}
if (operator_one === ‘/‘ || operator_one === ‘*‘) {
return !(operator_two === ‘/‘ || operator_two === ‘*‘);
} else if (operator_one === ‘+‘ || operator_one === ‘-‘){
return operator_two === ‘)‘ || operator_two === ‘(‘;
} else if (operator_two === ‘)‘ || operator_two === ‘(‘) {
return false
}
}
const changeFormat = function (array) {
let freeback = array.slice(0)
for (let i = 0; i < array.length; i++) {
if (array[i] === ‘÷‘) {
freeback[i] = ‘/‘
}
if (array[i].length > 1 && array[i].indexOf(‘/‘) !== -1) {
if (array[i].indexOf(‘^‘) !== -1) {
let temp = freeback[i].split(‘/‘)
let one = temp[0].split(‘^‘)
freeback[i] = Number(one[0]) + Number(one[1] / temp[1])
} else {
let temp = freeback[i].split(‘/‘)
freeback[i] = temp[0] / temp[1]
}
}
}
return freeback
}
/**
* 计算器
* @param expressionArray
* @returns {[]}
*/
const counter = function (expressionArray) {
expressionArray = changeFormat(expressionArray.split(‘ ‘))
let outStack = []
let operatorStack = []
for (let i = 0; i < expressionArray.length; i++) {
if (typeof Number(expressionArray[i]) == "number"
&& !isNaN(Number(expressionArray[i]))) {
outStack.push(expressionArray[i])
} else if (expressionArray[i] === ‘(‘) {
operatorStack.push(expressionArray[i])
} else if (expressionArray[i] === ‘+‘
|| expressionArray[i] === ‘-‘
|| expressionArray[i] === ‘*‘
|| expressionArray[i] === ‘/‘) {
if (operatorRank(expressionArray[i], operatorStack[operatorStack.length-1])) {
operatorStack.push(expressionArray[i])
} else {
outStack.push(operatorStack.pop())
while (!operatorRank(expressionArray[i], operatorStack[operatorStack.length-1])) {
outStack.push(operatorStack.pop())
}
operatorStack.push(expressionArray[i])
}
} else if (expressionArray[i] === ‘)‘) {
while (operatorStack[operatorStack.length-1] !== ‘(‘) {
outStack.push(operatorStack.pop())
}
if (operatorStack[operatorStack.length-1] === ‘(‘) {
operatorStack.pop()
}
}
if (i === expressionArray.length - 1) {
while (operatorStack.length !== 0) {
outStack.push(operatorStack.pop())
}
}
}
return outStack
}
/**
* 答案产生器
* @param suffix
* @returns {[]}
*/
const getResult = function (suffix) {
suffix = counter(suffix)
let resultStack = []
for (let i = 0; i < suffix.length; i++) {
if (typeof Number(suffix[i]) == "number"
&& !isNaN(Number(suffix[i]))) {
resultStack.push(Number(suffix[i]))
} else {
switch (suffix[i]) {
case ‘+‘: {
resultStack.push(Number(resultStack.pop()) + Number(resultStack.pop()))
break
}
case ‘-‘: {
let reduce = Number(resultStack.pop())
let beReduce = Number(resultStack.pop())
resultStack.push(beReduce - reduce)
break
}
case ‘*‘: {
resultStack.push(Number(resultStack.pop()) * Number(resultStack.pop()))
break
}
case ‘/‘: {
let reduce = Number(resultStack.pop())
let beReduce = Number(resultStack.pop())
resultStack.push(beReduce / reduce)
break
}
default: {
throw new Error(‘illegal symbol ‘)
}
}
}
}
return resultStack[0]
}
module.exports = getResult
其中题目中的^代表带分数,我手动做了10题,其中有三题随便写了个答案看系统是否能够自动校验。发现检验结果是正确的。
最后的统计结果和界面题目的完成情况一致,正确7题,错误3题。
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 1440 | 1500 |
· Estimate | · 估计这个任务需要多少时间 | 1440 | 1500 |
Development | 开发 | 1000 | 1100 |
· Analysis | · 需求分析 (包括学习新技术) | 60 | 40 |
· Design Spec | · 生成设计文档 | 0 | 0 |
· Design Review | · 设计复审 (和同事审核设计文档) | 60 | 80 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 60 | 60 |
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 1000 | 1100 |
· Code Review | · 代码复审 | 200 | 250 |
· Test | · 测试(自我测试,修改代码,提交修改) | 200 | 250 |
Reporting | 报告 | 0 | 0 |
· Test Report | · 测试报告 | 0 | 0 |
· Size Measurement | · 计算工作量 | 1400 | 1200 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 60 | 60 |
合计 | 1400 | 1500 |
原文:https://www.cnblogs.com/wsg1111/p/12675194.html