3.7.2 Carla's Classroom:算术课

我们能够使用已经学习的技能为Carla's Classroom网站创建一个适合小孩能力的数学练习。本节只开发要求学生做整数加法的练习部分。一旦完成这个程序,你将会看到增加简单的数学运算(减法、乘法和除法)甚至复杂的数学计算是多么容易。在这个程序中,学生将尝试解决容易的加法问题。一旦学生正确完成了一定数量的问题,程序将会增加难度级别。目前,现在我们将每级加法问题的数量限制在5题以节省空间。在第4章,你将学习如何改进这个程序,以便学生能够做数学问题的数目没有限制。我们把这个练习称为It All Adds Up。

3.7.2.1 开发程序

这个程序有一点儿复杂,因此在编码之前,我们将创建一些伪代码详细制定程序的流程。我们将按三级难度编写程序:第一级(容易)、第二级(中等)和第三级(高级)。

我们将使用Math.random()方法生成一些随机整数,并且使用这些数向学生提问每个加法问题。对于第一级,学生将加两个在1~10之间的数(包含1、10);第二级将提高难度,给出使用两个在1~99之间的数(包含1、99)的加法问题;第三级将要求学生加3个在1~99之间的数(包含1、99)。

3.7.2.2 return语句

return语句让你在执行所有代码之前退出函数。在每一级中,如果学生正确回答了3个问题,或者已回答这个级别中的所有问题,那么学生将退出这一级,因此我们需要使用这条语句。这条语句的语法是很简单的:

3.7.2.3 计数器

计数器常用于程序设计的许多目的。计数器在后续章节中起着重要作用,尤其是当我们开始使用循环和重复结构时。对于这个程序,我们需要一个计数器记录学生在每个级别录入正确答案的次数。计数器一定是整数变量,并且在整个或者部分程序中增加或减少。要使计数器加1,我们把1加到计数器的现值。假定把我们的计数器命名为count,那么计数器加1的语法如下:

如果你正好学过代数,那么这可能看起来很奇怪(某个东西如何能够等于它本身加上1呢)。但是在程序设计方面,这条语句意味着取出表达式右边(count+1)的值,然后存储在左边变量(count)中。用这种方法,我们按1递增count的值。

3.7.2.4 编写代码

首先,我们让学生通过单击网页内容区的一个按钮开始这个数学练习。你可以使用Student Data Files中的模板在内容区包括以下代码:

你的页面现在将会看起来像这样:

用文件名carla_adding.html保存这个页面,并且在math.html页面中添加一个到这个页面的链接。math.html页面现在将会看起来像这样:

3.7.2.5 计划

当学生单击这个按钮时将启动一个函数,该函数将产生简单的加法问题。对于每个加法问题,我们要生成两个随机数(在1~10之间),然后提示学生把这些数加起来。学生的回答将与正确的答案比较,如果回答不正确,那么将出现警示对话框显示这个信息,生成下一个问题并展示给学生。但是,如果回答是正确的,我们就要记录它,在正确回答3个问题之后程序跳到下一级。为了实现这个效果,我们需要一个计数器。

计数器将记录正确回答的次数,每次学生正确回答问题时计数器就加1。在每个问题之后,我们查看计数器是否到达3。当发生这种情况时,程序就跳过函数中的任何语句,并且移到下一级。

如果学生答对了3个问题,就调用为第二级编写的函数。现在,我们生成两个在1~99之间的随机数,而且重复第一级使用的处理过程:要求学生将这些数加起来,测试答案是否正确,如果答对了就递增计数器,查看计数器是否已经到达3,等等。

当到达第三级时,就生成三个在1~99之间的随机数,其他事情与第一级完全相同。

当发生以下事情之一时,程序将会结束:

·学生回答了第一级的所有问题,但是没有答对3个题。

·学生答对了第一级的3个问题而且回答了第二级的所有问题,但是在第二级没有答对3个题。

·学生答对了第一级的3个问题和第二级的3个问题,而且回答了第三级的所有问题,但是在第三级没有答对3个题。

·学生答对了第一级的3个问题、第二级的3个问题和第三级的3个问题。

你可能已经注意到,虽然这个程序可能变成冗长,但是将会有很多的重复。除了生成随机数的代码不同之外,为第一级编写的函数与第二级完全相同。类似地,除了要加3个随机数不同之外,第三级函数与第二级完全相同。我们将把所有这些函数放在一个主函数之内。我们将根据以下伪代码编写第一级函数,然后把它用做一个模板来编写另外两个函数。

一旦编写了符合这个伪代码的JavaScript代码,我们就能够重复第4~15行的代码,并且重复的次数可以和我们想要的一样多。每次重复将生成新的加法问题,要求学生解答。

3.7.2.6 代码片段

第一级代码 在本节末尾,通过多次重复每个级别的问题,我们将把整个程序放在一起。然而,为了节省空间,这里只展示重复的第一个问题。符合上面展示的伪代码的代码如下:

在这个程序中,表示随机数、计数器和总数的变量在命名时为变量名附加了一个“1”,这样命名的好处是在以后更容易识别哪个变量是属于哪个级别的。我们将在函数levelTwo()中命名变量num2a、num2b、sum2和count2,并且在函数levelThree()中使用相似的名字。因为许多代码将会重复使用,所以找到容易识别不同元素的方法是有益的,以备调试需要。

最后,在最后一个问题结束时,如果学生仍然还没有答对3个题,将显示一条信息告诉学生需要多多练习。为此编写的代码应该放在最后一个if子句(查看计数器是否已经到达3)的后面,如下所示:

第二级代码 第一级和第二级的主要不同在于要编写一条新语句为每个加法问题生成随机数。我们现在想要的数是在1~99之间,在第二级生成一个加法问题的代码如下:

注意,这里需要使用一个新的计数器。否则,若要在这个函数中重新使用相同的变量,必须把这个计数器在新函数的顶端设置为0。记住:一个学生将到达第二级的唯一方法是函数levelOne()的计数器到达3。除非这个计数器重新设定为0,否则由于这个计数器的值没有改变,还是3,表示已答对了3题,所以这个学生很有可能在第二级没有回答任何问题就直接进入第三级!

这个函数的其他改变是基于个人偏爱重新命名变量,以及当新的count2到达3时调用函数levelThree()。

正如第一级一样,在最后一个问题结束时,如果学生没有答对3个题,将显示一条信息告诉学生需要多多练习。其代码将与第一级完全相同。

第三级代码 对于第三级,要添加少量代码告知学生已经成功完成了这几关。除此之外,这个代码与第二级的主要不同是增加的第3个变量保存第3个在1~99之间的随机数,然后提示学生把3个数而不是2个数加起来。所有其他程序逻辑与前两级保持一样。

这个时候,如果学生回答了第三级的所有问题而且没有答对3个题,那么程序将会结束而且给出信息。在第三级的最后问题之后添加如下代码:

关于检查计数器的注释 由于学生在只回答一个或两个问题之后不可能答对3题,所以你会奇怪程序为什么要在前两个问题时检查这个计数器。如果愿意,你可以除去这个检查。然而,通过使用重复结构可以有更容易和更有效的方法处理这个程序。我们将会在第4章学习这种技术,从而改进这个程序。使用重复结构,能够更简单地为每个重复结构编写相同的代码。为了处理问题“计数器是否等于3”,计算机要花费极短的额外时间,但是通过在所有问题中包括这个检测可以使其他代码更为清晰。

3.7.2.7 将所有代码放在一起

现在我们将整个程序与HTML代码放在一起。在本章练习中,你可以修改这个代码来创建用于减法、乘法和除法的数学练习,或者为加法增加难度级别。

3.7.2.8 完成

这里是学生使用这个页面后的一些可能的结果。

输出:

学生以答对3题的成绩完成了第一级并且开始第二级。

输出:

学生以答对3题的成绩完成了第一级,但是在第二级没有答对3题。

输出:

学生成功完成了所有三级问题(也就是,在每级都答对了3题)。