四则运算


1、代码地址和博客地址

领航员的博客

codding


2、题目:四则运算

  • 能够自动生成四则运算练习题
  • 可以定制题目数量
  • 用户可以选择运算符
  • 用户设置最大数(如十以内,百以内)
  • 用户选择是否有括号、是否有小数
  • 用户选择输出方式
  • 最好能提供图形用户界面

3、设计思路

3.1 生成表达式


  四则运算的最基础的部分就是随机生成数字和运算符。所以我利用随机数的函数随机生成一定范围内的数值,可以是整数也可以是小数。运算符的选取也是通过随机数的值取出存放运算符数组的的值。

function createExpression(number,symbol,maxnumber,braket,decimal,out)    //生成表达式
{
    var n = 0;
    var flag = 0;
    var question = new Array(0);
    var Question = new Array(0);
    var answer = 0;
    var num = 0;
    var i;
    if(out == 1)  //判读输出方式
    {
        var f1 = fileQuestion();
        var f2 = fileAnswer();
    }
    else
    {
        var button = document.getElementById("button");
        button.style.display = 'block';
    }
    while(num != number)  //题目数量
    {
        n = Math.floor(Math.random()*(4-2+1)+2);
        for(i = 0;i < 2*n-1;i++)
        {
            if(i%2 == 0)
            {
                if(decimal == 1)  //可以有小数
                {
                    flag = Math.floor(Math.random()*(1-0+1)+0);
                }
                if(flag != 0)  //有小数
                {
                    question[i] = toFixed(Math.random()*(maxnumber-0+1)+0,2);
                }
                else
                {
                    if(question[i-1] == '/')  //除数不为0
                    {
                        question[i] = Math.floor(Math.random()*(maxnumber-1+1)+1);
                    }
                    else
                    {
                        question[i] = Math.floor(Math.random()*(maxnumber-0+1)+0);
                    }
                }
            }
            else    //运算符
            {
                question[i] = symbol[Math.floor(Math.random()*(symbol.length))];
            }
        }
        if(braket == 1)    //添加括号
        {
            question = addBraket(question,n);
        }
        if(out == 1)    //文件输出
        {
             for(i = 0;i < question.length; i++)
            {
                if(question[i] == '/')
                {
                    f1.write('÷');
                }
                else if(question[i] == '*')
                {
                    f1.write('x');
                }
                else 
                {
                    f1.write(question[i]);
                }
            }
            answer = solve(question,num);
            f2.write(answer);
            f2.write('\r\n');
            question.length = 0;
            f1.write("="+'\r\n');
        }
        else    在线输出
        {
            var content = document.getElementById("operation");
            for(i = 0;i < question.length; i++)
            {
                if(question[i] =='/')
                {
                    Question[i] = '÷';
                }
                else if(question[i] == '*')
                {
                    Question[i] = '×';
                }
                else
                {
                    Question[i] = question[i];
                }
            }
            Question[i] = '=';
            AddEle(Question,num);
            solve(question,num);
            Question.length=0;
            question.length=0;
        }
        num++;
    }
}    

3.2 计算表达式


  在基本满足要求的前提下,我和领航员又添加一个功能。在生成表达式后,可以计算出该表达式的答案。计算四则运算的表达式采用的是后缀表示法。

function isPra(c)  //判断是否为括号
{
    if (c == '(' || c == ')')
    {
        return true;
    }
    else
    {
        return false;
    }
}

function getPri(c)    //判断操作符优先级
{
    switch (c)
    {
    case '+':
    case '-':
        return 0;    
        break;
    case '*':
    case '/':
        return 1;    
        break;
    case '(':
    case ')':
        return -1;  //注意,这里将括号设为最低优先级,因此括号不会被弹出,除非遇到右括号
        break;
    }
}

function check(c,coll2,coll3)    //处理操作符生成后缀表达式
{
    if (coll2.length == 0 && (!isPra(c)))
    {
        coll2.push(c);
        return;
    }

    if (isPra(c))
    {
        if (c == '(')
        {
            coll2.push(c);
        }
        else
        {
                while(1)
                {
                    var ch = coll2.pop();
                    if(ch!='(')
                    {
                        coll3.push(ch);
                    }
                    else
                    {
                        break;
                    }
                }
                
        }
    }
    else    //如果不是括号
    {
        var sym = coll2.pop();
        if (getPri(c) <= getPri(sym))
        {
            coll3.push(sym);
            check(c, coll2, coll3);
        }
        else
        {
            coll2.push(sym);
            coll2.push(c);
        }
    }
}

function allocate(coll1,coll2,coll3)    //生成后缀表达式
{
    while (coll1.length != 0)
    {
        var c = coll1.shift();
        if (!isNaN(c))
        {
            coll3.push(c);
        }
        else
        {
            check(c, coll2, coll3);
        }

    }

    //如果输入结束,将coll2的元素全部弹出,加入后缀表达式中
    while (coll2.length!=0)
    {
        var c = coll2.pop();
        coll3.push(c);
    }
}

function calculate(coll3, coll4)    //计算后缀表达式
{
    while (coll3.length != 0)
    {
        var c = coll3.shift();
        //如果是操作数,压入栈中
        if (!isNaN(c))
        {
            coll4.push(c);
        }
        else     //如果是操作符,从栈中弹出元素进行计算
        {
            var op1 = parseFloat(coll4.pop());
            var op2 = parseFloat(coll4.pop());
            switch (c)
            {
            case '+':
                coll4.push(op2 + op1);
                break;
            case '-':
                coll4.push(op2 - op1);
                break;
            case '*':
                coll4.push(op2*op1);
                break;
            case '/':
                coll4.push(op2 / op1);  
                break;
            }
        }
    }
}

function solve(question,number)        //算出答案
{
    var x = 0;
    coll1 = question;
    allocate(coll1, coll2, coll3);
    calculate(coll3, coll4);
    x = coll4.pop();
    answer[number] = toFixed(x,2);
    return toFixed(x,2);
}

3.3 用户界面


  在读了邹欣老师的构建之法时,书中有一个例子就是关于四则运算的。受这个例子影响,我们计划用网页作为用户的界面。界面是根据学校的CG平台的外观进行设计。

网页架构

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>在线作业</title>
<link href="style/math.css" rel="stylesheet" type="text/css">
</head>

<body>
    <header class="header">
        <div class="logo">
            <img src="images/logo.jpg"/>
        </div>
        <div class="middle">
            <div class="title">&nbsp;&nbsp;</div>
            <div class="nav-header">
            <ul>
                <li>&nbsp;<a href="#">首页</a>&nbsp;|</li>
                <li>&nbsp;<a href="#">课程信息</a>&nbsp;|</li>
                <li>&nbsp;<a href="math.html"><font color="red">在线作业</font></a>&nbsp;|</li>
                <li>&nbsp;<a href="#">在线考试</a>&nbsp;|</li>
                <li>&nbsp;<a href="#">在线答疑</a>&nbsp;|</li>
                <li>&nbsp;<a href="#">成绩查询</a></li>
            </ul>
        </div>
        </div>
        <div class="rigth">
            <div class="per">欢迎你&nbsp;&nbsp;&nbsp;小学生!</div>
            <select class="select">
                <option>数学</option>
                <option>英语</option>
                <option>英语</option>
                <option>语文</option>
                <option>书法</option>
                <option>绘画</option>
                <option>音乐</option>
            </select>
        </div>
    </header>
    <hr>
    <article class="main">
        <nav class="nav">
            <div>
                <img src="images/作业.png"/>
                <span>当前作业</span>
                <ul>
                    <li class="home_work"><a href="#">四则运算</a></li>
                    <li class="home_work"><a href="#">二元一次方程</a></li>
                </ul>
            </div>
        </nav>
        <section class="homework">
            <h2>四则运算</h2>
            <h3>条件选择</h3><br/>
            <div class="number">
                题目数量:
                <input  type="text" name="number" placeholder="请输入题目数量(1~99)" maxlength="2" id="number" />
            </div>
            <div class="symbol">
                请选择运算符:
                +&nbsp;<input  id="symbol" type="checkbox" name="symbol" value="+" checked/>
                -&nbsp;<input  type="checkbox" name="symbol" value="-"/>
                ×&nbsp;<input  type="checkbox" name="symbol" value="*"/>
                ÷&nbsp;<input  type="checkbox" name="symbol" value="/"/>
            </div>
            <div class="maxnumber">
                设置最大数:
                十以内&nbsp;<input type="radio" name="maxnumber" value="9" checked/>&nbsp;&nbsp;
                百以内&nbsp;<input type="radio" name="maxnumber" value="99"/>
            </div>
            <div class="bracket">
                括号:
                有&nbsp;<input  type="radio" name="bracket" value="1"/>&nbsp;&nbsp;
                没有&nbsp;<input type="radio" name="bracket" value="0" checked/>
            </div>
            <div class="decimals">
                小数:
                有&nbsp;<input type="radio" name="decimals" value="1"/>&nbsp;&nbsp;
                没有&nbsp;<input  type="radio" name="decimals" value="0" checked/>
            </div>
            <div class="out">
                输出:
                在线&nbsp;<input  type="radio" name="out" value="0"  checked/>&nbsp;&nbsp;
                文件&nbsp;<input  type="radio" name="out" value="1" />
            </div>
            <input class="button" type="button" value="确&nbsp;&nbsp;定" onclick="ensure()"/> 
            <input class="button" type="button" value="清&nbsp;&nbsp;空" onclick="cancel()"/>
        </section>
        <section class="subject">
            <div class="time" id="time"></div>
            <div id="operation" class="operation"></div>
        <button class="button submit" id="button" onClick="submit()">&nbsp;&nbsp;</button>
        </section>
    </article>
    <footer class="footer">
        <div class="bg">
             小智慧
        </div>
    </footer>
        <script type="text/javascript" src="javascript/math.js"></script>
</body>
</html>

网页样式

@charset "utf-8";
/* CSS Document */

*{
    padding: 0;
    margin: 0;
}

.body{
    position: relative;
}

li a:link{
    text-decoration: none;
}

li a:visited{
    color:inherit;
}

.header{
    width: 100%;
    height: 100px;
}

.logo{
    width: 20%;
    height: 100px;
    float: left;
}


.logo img{
    width: 80px;
    height: 80px;
    margin: 10px 80px;
    
}

.middle{
    width: 60%;
    height: 100px;
    float: left;
}

.title{
    text-align: center;
    color: #283FF0;
    font-weight: bold;
    padding: 10px;
    font-family: "黑体";
    font-size: 20px;
}

.nav-header li{
    list-style: none;
    float: left;
    color: #161AEC;
    margin-top: 20px;
    font-size: 14px;
}

.rigth{
    width: 20%;
    height: 100px;
    float: left;
}

.per{
    margin-top: 10px;
    color: red;
    font-size: 14px;
    font-weight: bold;
    font-family: "微软雅黑";
    margin-left: 40px;
}

.select{
    width: 200px;
    margin-top: 30px;
}

hr{
    border-color:cornflowerblue;
    margin-bottom: 5px;
    border-width: 1px;
}

.main{
    width: 100%;
    height: auto;
    position: relative;
}

.nav{
    width: 20%;
    height: auto;
    position: absolute;
    left: 0;
}

.nav img{
    margin-top: 10px;
    margin-left: 10px;
    width: 15px;
    height: 15px;
}

.nav span{
    font-size: 12px;
}

.home_work{
    font-family: 微软雅黑;
    font-size: 12px;
    margin-left: 50px;
    margin-top: 5px;
    color: #161AEC;
}

.homework{
    width: 80%;
    height: auto;
    position: absolute;
    left: 20%;
    background-color:rgba(71,155,243,0.1);
    font-family: 黑体;
}

.homework h2{
    text-align: center;
    padding: 10px;
    color: #5669FB;
    
}

.number{
    width: 30%;
    margin-bottom: 10px;
    margin-left: 10px;
    float: left;
}

.symbol{
    width: 30%;
    margin-bottom: 10px;
    margin-left: 10px;
    float: left;
}

.maxnumber{
    width: 30%;
    margin-bottom: 10px;
    margin-left: 10px;
    float: left;
}

.bracket{
    width: 30%;
    margin-bottom: 10px;
    margin-left: 10px;
    float: left;
}

.decimals{
    width: 30%;
    margin-bottom: 10px;
    margin-left: 10px;
    float: left;
}

.out{
    width: 30%;
    margin-bottom: 10px;
    margin-left: 10px;
    float: left;
}

.button{
    width: 50px;
    height: 30px;
    float: right;
    margin-top: 20px;
    margin-right: 50px;
    margin-bottom: 10px;background-color: cornflowerblue;
    color: white;
    font-weight: bold;
    border-radius: 8px;
}

.subject{
    width: 80%;
    height: auto;
    position: absolute;
    left: 20%;
    top: 207px;
    background-color:rgba(14,47,244,0.2);
}

.span{
    margin-top: 5px;
    margin-left: 10px;
    width: 30%;
    display: inline-block;
    position: relative;
}

.span input{
    position: absolute;
    right: 85px;
}

.tips{
    position: absolute;
    right: 60px;
    display: none;
}

.submit{
    display: none;
    margin-bottom: 30px;
}

.time{
    color: red;
    margin: 5px;
    font-weight: bold;
    font-family: 黑体;
    font-size: 20px;
    text-align: center;
}

.footer{
    width: 100%;
    height: 30px;
    position: fixed;
    bottom: 0px;
}

.bg{
    text-align: center;
    line-height: 30px;
    color: white;
    font-family: 微软雅黑;
    font-size: 14px;
    width: 100%;
    height: 100%;
    background-color: rgba(9,9,9,0.6);
}

 


4、新增功能

4.1 在线答题


  在可以生成题目和正确解决题目的前提上,我们设计了在线答题功能,即在生成题目后,用户可以在该页面上进行答题,在提交后系统自动进行判断用户的答案是否正确,再统计出用户答题正确的数量和错误的数量,最后计算出用户的正确率。

4.2 计时功能


  用户选择在线答题后,系统会根据题目的生成的条件来预计用户答题所需的时间,从而进行倒计时。在时间结束前,用户需要解出所有问题的答案,否则在时间结束时,系统自动提及所有题目,未解答的题目视为错误。但对于答题时间的设定并不是很完善。


5、使用方法

5.1 在线答题


  用户在进入使用界面时,可以根据提示选择表单元素的内容(如题目数量、最大数、运算符、小数等),在选择输出方式时,选择在线。在选择完成后,点击确定按钮,会在下方自动生成四则运算,并生成答题时间。用户在每道题目后面的文本框内作答,在作答结束后点击题目又下角的提交即可。

5.2 更改题目


  用户在选择题目条件,点击确定后,发现部分条件选择错误,需要做出更改时,可以更正错误的条件,然后再次点击确定,即可重新生成满足条件的表达式。

5.3 清空题目


  在生成题目后,用户不想作答时,点击清空按钮,题目会被系统清空。

5.4 生成文件


  在选择输出方式时,选择文件后,点击确定,此时页面会弹出问题文本已创建,答案文本已创建两个提示框。生成的文本默认在桌面。
注意:此功能只有IE浏览器支持,且允许浏览器执行ActiveX控件。


6、界面展示

6.1在线答题界面


6.2提交答案后界面


 

6.3超时后界面


 

6.4文本输出界面结果


 

 


7、总结


  这是我和我领航员正真意义上的第一次合作,上一次只是互相复审了一下代码。俗话说:一个篱笆三个桩,一个好汉三个帮。有个一好的合作伙伴可以事半功倍。在编程初期,我们一起讨论题目的要求和基本思路。在基本功能完成后,我们又商讨的一些新增的功能,以丰富我们的作品。
  在我编程工作中,小伙伴即使不在学校,也不时的对我的工作进行监督并提出意见,我也随时向他汇报工作进程,以便安排接下来的任务。
  在编程结束后,领航员对代码进行认真的复审,并且认真的检查程序是否可以完全实现题目的要求和我们新增的一些功能。
  不识庐山真面目,只缘身在此山中。无论是在编写程序时,还是在设计界面时,领航员都有着至关重要的作用。