I want to produce number squares (10 x 10 grids of numbers up to 100) and highlight different sequences of numbers to help in my maths teaching. For example: what sequence is highlighted in the number square below?
I could make these in a spreadsheet, but why not program it so that I can quickly produce a range of number squares?
I've been playing with the Racket programming language (http://racket-lang.org/) and given that it has graphics primitives built in to the basic language it seems like a good choice.
Here's an example of what it can do with graphics, try each line in turn...
(text "21" 50 "black")
(rectangle 70 70 "solid" "yellow")
(overlay (text "21" 50 "black") (rectangle 70 70 "solid" "yellow"))OK, so we have a yellow square with 21 in it. So from these basics we can build some number squares:
(define NUMBERS-PER-LINE 10)
(define NUMBER-SIZE 30)
(define BOX-SIZE 60)
(define (number-in-box n pred)
(overlay (text (number->string n) NUMBER-SIZE "black")
(if (pred n)
(rectangle BOX-SIZE BOX-SIZE "solid" "pink")
(rectangle BOX-SIZE BOX-SIZE "outline" "black"))))
(define (number-block n pred)The first procedure number-in-box draws one number and colours it (or not) depending on the predicate pred, which is a test for the number. Try these:
(define numbers (rest (build-list (+ n 1)
(λ (x) (number-in-box x pred)))))
(define (number-lines l)
(cond [(= (length l) NUMBERS-PER-LINE)
(apply beside (take l NUMBERS-PER-LINE))]
(apply beside (take l NUMBERS-PER-LINE))
(number-lines (drop l NUMBERS-PER-LINE)))]))
(number-in-box 5 odd?)
(number-in-box 5 even?)
The second procedure number-block draws the block of numbers, again with the predicate (which it simply passes on to number-in-box. Try these:
(number-block 100 odd?)
(number-block 100 prime?)
(number-block 100 square-number?)
Making times tables with curryTo make tables for times tables you need to add a predicate to test for multiples of a number, e.g.:
(define (multiple-of-3? n)Now you can run:
(zero? (remainder n 3)))
(number-block 100 multiple-of-3?)However, it's a bit of work to have to define a new procedure each time we want a new times table. What about a predicate like this?
(define (multiple-of? m n)
(zero? (remainder n m)))
This takes two parameters like this: (multiple-of? 3 9)
in this example, is 9 a multiple of 3?
However, our predicate that we want to pass to number-block expects a single argument: the number in the number square. How can we adapt this procedure to accept a single argument? The answer: with currying.
(curry multiple-of? 3) is a new version of our procedure with the three already passed, so this version is ready to accept the number from the number square. Try these examples:
(number-block 100 (curry multiple-of? 4))
(number-block 100 (curry multiple-of? 5))
(number-block 100 (curry multiple-of? 6))