Monday, October 26, 2009

hacking perl to help my kids at school

So I have three kids, and they are all in elementary school. And right now all three of them are still trying to memorize their multiplication tables. Apparently the schools these days teach the kids to start by "counting up" (3, 6, 9, 12 ... etc for 3's) rather than going straight towards memorization as I recall we were taught.

So now they're still counting up, and have not memorized these basic facts.

So I had the idea that we need to give them sheets with practice problems, like the timed ones they do in school. I figure if they have to do this a lot, then eventually the facts will just "sink in".

This is when the wife pipes up: "hey can you write a program to do that?" (If only I had a nickel for every time the wife asked "can you write a program to do that?"...)

Well, this one was easy, took me about 20 minutes in perl. I wrote a script, "problems.pl" that dumps text file of some 144 problems suitable for sending to the printer. Here's sample output:


gdamore@pepper{18}> perl ~/problems.pl -r
Practice: (# 650)
Times tables from 1 to 12.
All mixed up!


4 x 7 = 5 x 7 = 1 x 10 = 2 x 9 = 10 x 9 = 6 x 7 =

12 x 10 = 1 x 4 = 2 x 5 = 6 x 3 = 5 x 12 = 11 x 8 =

2 x 12 = 1 x 1 = 7 x 4 = 3 x 10 = 9 x 10 = 6 x 11 =


Command line switches: "-r" to randomize the problems a bit (although every problem is given), "-s " to set the numbers to start from, and "-e " to set the ending problem (note that the second values are constrained from 1..12, because that's what the kids in school need), "-S " to set a seed (so can regenerate a previous sheet) and "-a" for an "answers sheet" (which is really only useful if you want the child to use it to check her own work. Because you should know all these facts so cold that you can check without an answer key, right? Right?)

Here's the code. Feel free to pass it around, give it away, modify it, whatever. It can be adapted to other kinds of problems pretty easily, I expect. Maybe you know a teacher or parent who could use this dumb little script. Maybe you just need to practice your multiplication tables on your own? I won't tell!



#!/usr/bin/perl

use Getopt::Std;

my $start = 1;
my $end = 12;

my @problems;

sub usage() {
print STDERR basename($0), ": usage\n";
print STDERR "problems: [ -r ] [ -a ] [ -s ] [ -e ]\n";
exit(2);
}

srand();
$seed = int(rand(1000));

my $s, $e, $i, $j;
getopts('rs:e:aS:', \%opt) || usage;
$dorand = exists($opt{'r'});
$doans = exists($opt{'a'});
$start = $opt{'s'} if exists($opt{'s'});
$end = $opt{'e'} if exists($opt{'e'});
$seed = $opt{'S'} if exists($opt{'S'});

srand($seed);

$i = 0;
$s = $start;
$idx = 0;
foreach $i (1..12) {
foreach $j (1..12) {
$problems[$idx]->{'problem'} =
sprintf("%2d x %2d = ", $s, $j);
$problems[$idx]->{'answer'} =
sprintf("%2d x %2d =%3d " , $s, $j, $s * $j);
$problems[$idx]->{'defined'} = 1;
$idx = $idx + 1;
}
$s = $s + 1;
if ($s > $end) {
$s = $start;
}
}

@new = ();
if ($dorand) {
for( @problems ){
my $r = rand @new+1;
push(@new,$new[$r]);
$new[$r] = $_;
}
} else {
@new = @problems;
}

if ($doans) {
printf("\tAnswers: %s\n", $dorand ? "(# $seed)" : "");
} else {
printf("\tPractice: %s\n", $dorand ? "(# $seed)" : "");
}

printf("\tTimes tables from $start to $end.\n");
if ($dorand) {
printf("\tAll mixed up!\n");
}
printf("\n\n");
foreach $x (0 .. 1) {
$idx = $x * (72);
for $y ( 1 ..12) {
if ($doans) {
printf("%s%s%s%s%s%s\n",
$new[$idx]->{'answer'},
$new[$idx + 12]->{'answer'},
$new[$idx + 24]->{'answer'},
$new[$idx + 36]->{'answer'},
$new[$idx + 48]->{'answer'},
$new[$idx + 60]->{'answer'},
$new[$idx + 72]->{'answer'});
printf("\n");
} else {
printf("%s%s%s%s%s%s\n",
$new[$idx]->{'problem'},
$new[$idx + 12]->{'problem'},
$new[$idx + 24]->{'problem'},
$new[$idx + 36]->{'problem'},
$new[$idx + 48]->{'problem'},
$new[$idx + 60]->{'problem'},
$new[$idx + 72]->{'problem'});
printf("\n");
}
$idx = $idx + 1;
}
}



No comments: