Monday, 15 September 2008

User Interfaces and MathML

An article on linguistic user interfaces caught my attention the other day. I like Jono DiCarlo's theory about what makes for a good user interface: easy to learn; efficient; expressive.

It struck me later that DiCarlo's theory helps to explain what I see as the main difficulty in working with MathML. If you are someone who wants to construct equations in MathML to display on your website, in all likelihood you have been using some tool, probably a WYSIWYG one with a drag-and-drop or palette-based interface, to construct the equations which then generates the MathML for you. You then need to transplant this into your website.

So what's wrong with this? While these tools and their interfaces meet the criteria of easy to learn (usually) and expressive (usually), they are definitely not efficient. GUI-based interfaces are easy to learn and use, but they are also comparatively slow next to keyboard-based input methods. And having to move the generated MathML to your webpage is another bottleneck.

But thankfully there appears to be some light on the horizon. Peter Jipsen of Chapman University has created a javascript script (called ASCIIMathML) that converts structured text to presentation MathML. So you can type `x=(-b +- sqrt(b^2-4ac))/(2a)` into your webpage and what appears is the quadratic formula. If the ASCIIMathML script is missing, the expression is still reasonably comprehensible. Compare that to the following MathML for the same formula:
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mi>x</mi>
<mo>=</mo>
<mfrac>
<mrow>
<mo>−</mo>
<mi>b</mi>
<mo>±</mo>
<msqrt>
<msup>
<mi>b</mi>
<mn>2</mn>
</msup>
<mo>−</mo>
<mn>4</mn>
<mi>ac</mi>
</msqrt>
</mrow>
<mrow>
<mn>2</mn>
<mi>a</mi>
</mrow>
</mfrac>
</math>

ASCIIMathML in my opinion represents a huge step forward. It begins to address the efficiency problem by allowing the user to enter equations without needing another tool, or having to open up and click on palettes, or having to copy the MathML from one place to another.

I've added ASCIIMathML to my school's Moodle server - my students can now enter equations simply by typing. They can mouse over equations that I've placed in pages on Moodle and copy the ASCIIMath expression and then change it as they need to. And all this without sacrificing ease of learning or expressiveness. The basic syntax is very easy to learn, but extends in a logical manner to cover even extremely complicated expressions.

Now all that's needed is for the makers of all browsers to include support for MathML, including the requisite fonts, by default.

Saturday, 19 January 2008

The Pluses Problem

On his blog, Rational Mathematics Education, Michael Goldenberg mentions this problem by way of one Maria Miller (her blog here.)
How many addition signs should be put between digits of the number 987654321 and where should we put them to get a total of 99?
Michael finished his blog entry with "It would also be great if anyone has other extension ideas for this ... The one I'd suggest right away is: What happens if we change 99 to other values?"

This got me thinking along a slightly different line - what other totals have multiple solutions and could I write a program to find them?

It turns out that there are 209 possible totals (including 987654321), of which 31 can be formed in more than one way. Four totals (153, 171, 180, 189) can be formed in four different ways, seven totals can be formed in three different ways, and the rest in two different ways.

The program to find this is conceptually quite simple... if you can get your head around recursion.

The logic: for a given number, take the first n digits (where n is progressively a number from 1 to the total number of digits), convert to a single value, then with the remainder, do the same thing again.

Programming this in Python ended up being simple, but not before I went down a few blind alleys:

def Chunkit(x,p=[]):
for i in range(len(x)):
p.append(int(x[:i+1]))
if i == len(x)-1:
print p, sum(p)
print
else:
Chunkit(x[i+1:])
p.pop()
return p

num = raw_input("Enter a number: ")
Chunkit(str(num))

The sticking point was line 9:
p.pop()
At first, it's not obvious why this is necessary, but if you leave it out (as I initially did), you soon see the consequences.

With the program written and working correctly (with a few additions to produce the list of totals and how often they occur), exploring the original problem led to the results given above. It also allowed me to examine different number sequences, such as 123456789, which can be made to total 99 three different ways rather than two. (And totals of 153 and 162 can be made five different ways.) Or 123454321, which can be made to total 97 in eight different ways.

Of course, having posted here what I think is a fairly neat solution (only 13 lines of code), no doubt some script-kiddy will pop up with a four line solution in Ruby or OCaml or whatever is the trendy language this week. But at least I now have another interesting problem to discuss with my students.

Friday, 28 September 2007

A lattice for multiplication

When I was in Year 5, our teacher showed us an interesting way of multiplying. The image at left shows the lattice or gelosi method for mutipying 35 x 76. You put the numbers to multiply along the top and the right sides, with sufficient rows and columns for each digit. Each box is divided diagonally. You multiply (in any order) and the result goes in the appropriate box, with the tens above the diagonal and the units below. Once all the multiplications are done, you add along the diagonals (the red arrows in my pic), starting from the bottom right corner, working to the left and carrying where necessary.

As a method for long multiplication, it works very nicely, and is probably a little simpler to learn than the more usual columnar approach. It is certainly worth showing to students - some will no doubt prefer the standard columnar approach, but others will like the lattice (at least until they get calculators).

But the other day I found another use for the lattice. I was introducing a Year 10 class to multiplying polynomials. I used a lattice (minus the drawn diagonals) as shown at left. We collected the like terms (which conveniently lie diagonally). My students found this approach very accessible. While I did not suggest it on the day, an obvious way to speed up this approach is to omit the variables and work with only the coefficients.

Then I happened to look at a blog I've been occasionally reading, and the lattice was mentioned there as well. But in this case, it was about someone arguing against using the lattice method in the classroom. Say what? Sadly, it is true - there are those who would have teachers confine themselves to teaching only one way (in this case, the standard columnar approach), and who disparage any other approach and denigrate anyone who would teach any other approach.

I can't even begin to fathom the mental bankruptcy necessary to say to someone else "there is only one way that students should do it". For me, part of the beauty of Mathematics is that there is always more than one way. Some ways will be faster or more elegant. Some ways will be slow wandering paths, but you may learn other things along the way.

The person who insists that students do things only one way is no educator.

Tuesday, 14 August 2007

Magic squares? Mind-reading? High school maths, and nothing more.

I've come across an interesting site (which was advertised on another site I found through StumbleUpon), featuring a supposedly mind-reading magic square.

This site gets the user to choose a two digit number at random, and then subtract from this number the values of its digits, e.g. if you chose 87, you would then subtract 8 and 7 from 87 to get 72. You then look at a grid showing numbers and symbols, and find the symbol corresponding to your result.

The site tells you it will guess your symbol correctly three times, then if you pay $2 via PayPal, you can get five more guesses and a presentation about the "Secret to Life". And you can pay $20 to have the secret of the magic square explained to you.

Of course, there is no magic, and no mind-reading, and a bit of elementary maths can quickly reveal what's going on. This is actually a good exercise for both Mathematics and Computer Studies classes - construct a spreadsheet or computer program that shows all the numbers from 10 to 99 and the result after subtracting the number's digits from itself. Once you've done that, the trick is obvious.

What about the "Secret to Life"? I didn't pay to find out, but I suspect it might be that a fool and his money are soon parted.

Monday, 2 July 2007

Get me the poll position, stat!

The stirring stuff for the media this weekend, especially the News Ltd. outlets, was the Galaxy poll that shows the Government slipping behind again. The key points for the talking heads and their opinion-column analogues in the papers were the poll results showing most Australians were skeptical of the Government's motives for the current intervention in the NT, and the fact that voters were largely unconcerned about the influence of the Unions on the ALP.

The media love to make a big deal of polls. This would appear to be consistent with Ehrlich’s Law: “People pay way too much attention to things that are easily quantified.” But does this poll really tell us much?

For one thing, the sample was only 1000 people out of the 10 million in this country who can vote. I have some doubts about how much we can assume from so small a sample (~0.01%). (I'd love to see the pollsters publish the details about their sampling methods and confidence levels.)

Apart from the polling itself, the way that the results are presented in the media is worth a closer look. Let's consider the data about how the bad behaviour of union officials is likely to affect support for the ALP. On various TV news programs, the data was reported in a very simplistic manner: 46% of respondents indicated that the union officials' behaviour would not influence their vote, 43% said it would, 11% unsure. On two of those TV programs, this was cast as a bad result for the Government. Really? The 46% whose votes would not change are hardly the voters we should be looking at - they represent the voters who are already polarised on their choice of party. It's the other two categories that are of interest. 43% said it would influence their vote - but in which way? If a large chunk of the 43% are voters who might vote for the ALP but who may not because of the union officials, this is good news for the government, not bad. But of course, no breakdown of the data was given.

A column in the Herald Sun gives a different set of figures (which don't seem to entirely line up with what was appearing on the news programs mentioned above), specifically:
...20 per cent of voters said they were now less inclined to vote Labor because of [union official Joe McDonald's] actions, 9 per cent said they were more inclined to vote for the party, and 67 per cent said they would not be influenced either way...

and the overall interpretation in that column was "voters also said they were largely unconcerned by the bullying actions of union officials".

Again, the columnist is looking at the largest number in the figures and drawing a conclusion from that, but the interesting numbers are the small ones - 20% of the respondents indicated that they would be less inclined to vote Labor. What proportion of those respondents would otherwise vote Labor? How significant is their change in resolve? Could this represent an increase in the proportion of swinging voters who have previously come down on the left side of the political spectrum but who may now be leaning to the right? Again, there is no breakdown and thus no way to answer these questions.

What this does illustrate is the generally poor way that polls and statistical measures are handled by the media. They are interpreted in the most simplistic terms (and some columnists are clearly happy to interpret them in line with their own political leanings). What are the viewing public to make of these statistics and the interpretations doled out by the media?

Mark Twain quipped about "lies, damn lies and statistics", a response to the spurious use of surveys and statistics by the politicians of his day. If Twain were alive today, he'd no doubt use the same line, the difference being that now newspaper columnists would figure more prominently in the list of perpetrators.

But given that news has become like takeaway food, with an emphasis on speedy delivery of something palatable without too much attention to quality, should we be surprised?

Thursday, 28 June 2007

Going Back

Reversing the digits of a number is a time-honoured exercise for student programmers. It gets the student to think about integer division and modulo operations, and about iterative processes.

An exercise I've often give to my students is to write a recursive procedure for reversing an integer's digits, even though I know that it can be done more simply as a loop. This is a good way to have the students think about parameter passing and variable scope. But up till now, I've only had students doing this in Pascal.

So when I went to do it in Python, I found myself momentarily stopped by the fact that Python does not have an exact equivalent to Pascal's variable parameters. So how do I get a recursive procedure for integer reversal in Python?

I came up with two solutions.

Solution 1:
revers(n):
global q #tell Python to use the global variable, not a local one
if n > 0:
q=q*10+n%10
revers(n/10)
return q

q = 0
x=int(raw_input("Enter a number: "))
print revers(x)

Here, I simply made the function calculate the reversed integer in a global variable. Now, when I was learning Pascal programming, all my reference works said the same thing: don't change a global variable inside a function/procedure. Since old habits die hard, I found myself looking for a different solution to the one above, one that didn't require the global variable inside the function.

Solution 2:

revers(n,q=[0]):
if n > 0:
q[0]=q[0]*10+n%10
revers(n/10)
return q[0]

x=int(raw_input("Enter a number: "))
print revers(x)

This solution uses the fact that arguments to Python functions are object references, so passing a mutable object (a list being an obvious example) allows you to progressively alter the value in that object with each subsequent recursive call to the function.

Python also allows you to declare a default value for an argument and thereby omit it from the function call. The default value is evaluated only once, so setting using q=[0] as an argument only affects the first call to the function, and subsequent recursive calls do not reset the list.

As a solution, I prefer this (since it doesn't violate the rules about variable scope I learned so long ago), but I wonder how well my students will understand how the mutability of an object relates to the scope of a recursive function.

Wednesday, 20 June 2007

Getting Keith Backwards

I stumbled over an interesting number sequence the other day - Keith numbers (named for mathematician Mike Keith) are found as follows: starting with a number, separate the digits, then add them to form another number; continuing to sum the last n numbers in the sequence (where n is the number of digits in the original number), if the original number appears in the sequence, it is a Keith number.

For example, starting with 14, we get 1+4 = 5, 4+5=9, etc. to form the sequence 1, 4, 5, 9, 14 - since the original (14) appears in the sequence, 14 is a Keith number.

It turns out that Keith numbers are very rare (Wikipedia's article states that there are only 71 Keith numbers below 1019).

I wondered about similar number sequences, in particular numbers that produce the original number with its digits reversed. Wolfram's MathWorld site has an article on Keith numbers that also mentions these Reversed Keith numbers, but prefers the ugly term revrepfigits (and also calls Keith numbers repfigits, from 'repetitive fibonnaci-like digits').

Before I read the Wolfram MathWorld article, I had written a small Python program to find Reverse-Keith numbers (which I had decided should be called Feek numbers), and generated all the numbers up to 10 000 000.

This turns out to be a nice little programming exercise, requiring one to think about how to manage both integer reversal and splitting an integer into its separate digits prior to building the resulting number sequence. If someone wants an interesting exercise for their students, I think this is worth a look.