Math practice sheet in HTML and JavaScript

Update 10/15/09
I’ve made this page to list all the math practice sheets I’ve made. And I’ll update it if and when I make more.

The second grade teachers at my younger son’s school sent home a letter to all the parents suggesting that we help our kids practice their “math facts” (addition and subtraction) every night. I will resist the tempation to suggest that in my day teachers actually taught the subjects themselves and did not outsource their job to the parents. That would be cranky and wrong.

As I mentioned a few months ago, I wrote a Python program that my son can run to drill himself. (I’ll ask you to resist the temptation to suggest that this constitutes outsourcing my parenting duties to a seven-year-old.) The program still works well, but I have noticed three deficiencies with the computer-based approach:

  1. He often spends more time looking for the right keys to press that he does thinking about the addition or subtraction problem.
  2. Since he does this work on his own, I don’t know which problems he has more difficulty with and don’t know what he needs extra help on.
  3. The program presents the problems in a horizontal format, while his schoolwork presents them in a vertical format.

Paper-based problem sets would fix all of these deficiencies, but I hate the idea of writing up a new set of problems every day. It’s not just laziness—the problems I think of tend to follow a pattern and don’t cover the whole range of problems my son should be practicing. So I decided to rewrite it as an (X)HTML file with JavaScript and CSS. The JavaScript uses its random number generator to create a new set of 25 problems each time the file is opened or refreshed. The CSS formats the problems the way the homework and test problems are formatted and spaces them out to fit nicely on a sheet of paper.

Here it is. I call it “math-practice.html” and my plan is to print several new versions every week so he can practice on one or two every night. I’ll check his work and see where he tends to make mistakes.

 1:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 2:    "">
 3:  <html>
 4:  <head>
 5:    <title>Math Practice</title>
 6:    <style type="text/css">
 7:    h1 {
 8:      text-align: center;
 9:      font-family: Sans-Serif;
10:      font-weight: bold;
11:      font-size: 36px;
12:      margin: 20px 0 0 0;
13:      padding: 0;
14:    }
15:    #whole {
16:      margin-left: auto;
17:      margin-right: auto;
18:    }
19:    table.problem {
20:      font-family: Sans-Serif;
21:      font-size: 24px;
22:      text-align: right;
23:      border-bottom: solid;
24:      margin: 40px;
25:    }
26:    </style>
27:    <script>
28:    function single_problem() {
29:      var operator = "+";
30:      if (Math.random() < .6) {
31:        operator = "&#8722;";
32:      }
33:      var a = Math.floor(Math.random()*10 + 10);
34:      var b = Math.floor(Math.random()*(a-1) + 1);
35:      var c = a - b;
36:      if (operator == "+") {
37:        var top = b;
38:        var bottom = c;
39:      } else {
40:        var top = a;
41:        var bottom = b;
42:      }
43:      return '<table class="problem">' +
44:                     '<tr><td></td><td>' + top + '</td></tr>' +
45:                     '<tr><td>' + operator + '</td><td>' + bottom + '</td></tr>' +
46:                     '</table>';
47:    }
48:    </script>
49:  </head>
50:  <body>
51:    <h1>Math Practice</h1>
52:    <table id="whole">
53:      <script>
54:      for (i=0; i<5; i++){
55:        document.write("<tr>");
56:        for (j=0; j<5; j++) {
57:          document.write('<td>' + single_problem() + '</td>');
58:        }
59:        document.write('</tr>');
60:      }
61:      </script>
62:    </table>
64:  </body>
65:  </html>

This is a self-contained file with the markup, CSS, and JavaScript all together. The guts of the logic is in the single_problem function defined on lines 29-47. Three numbers are generated, called a, b, and c, such that:

Unlike some other languages, JavaScript doesn’t have a built-in function for generating random integers, just the Math.random() function that returns a floating point value between 0 (inclusive) and 1 (exclusive). This random floating point number is converted to a random integer over a particular range through multiplication, addition, and truncation

Another random number is generated to determine whether the problem is going to be addition or subtraction. This is done on lines 29-32. I’m giving a 60/40 bias to subtraction problems because my son needs more subtraction practice. When the problem is subtraction, the operator variable is given the value &#8722;, which is the (X)HTML entity for the minus sign. It matches the width of the plus sign and looks better than the hyphen.

If the problem is addition, it’s presented as b + c; if it’s subtraction, it’s presented as a - b. The numbers and operator are laid out in a 2 by 2 table with the numbers in the right column, the operator in the lower left corner, and an empty upper left corner. The table is given the “problem” class so it can be identified and formatted by CSS.

The page is laid out as a 5 by 5 table of problems (see lines 52-62). This outer table is given the id “whole” and the CSS centers it in the page (lines 15-17). The individual problems are given an all-around margin of 40 pixels to keep them from running into one another and give room on the page for the answers. The CSS for the “problem” class (lines 19-25) also right-aligns the numbers and draws a line under each problem.

A typical page looks like this:

To assuage my guilt for wasting paper, I’ll be printing these practice sheets on the backs of previously printed pages that are headed for the recycling bin.

(Tenuously related fact: My wife and I went to the Field Museum last week to see the map exhibit that’s been in place for the past couple of months. One section of the exhibit is devoted to maps of imaginary places and they have a few pages from Tolkien’s Lord of the Rings notes. As he was writing in the middle of WWII with its material shortages, his drawing of Minas Tirith was written on the back of a student’s exam paper, ensuring that student a lasting place in literary history.)

I’ve tried to make “math-practice.html” easy to adapt to other situations. With a few simple changes, you could, for example,

I’ve changed the font specification from Helvetica to Sans-Serif to make the file more cross-platform.

Further update
My son is now a Subtraction Superstar in his class, a designation clearly due to his superior genes and his use of this practice sheet.