Programs producing questions about arithmetic.

William Overington

Copyright 2001 William Overington

Wednesday 18 July 2001

This document is a case history of preparing web based simulations of several small programs for Astrolabe Channel.

These programs are all very similar. The first program is a program to generate, using random numbers, addition questions and to present them to the viewer. The four coloured buttons are used for this program. The viewer pushes the green button in order for a question to be generated and displayed. The viewer may then take as long as he or she chooses in order to obtain an answer and then press the yellow button on the hand held infra-red control device and view the answer. Pressing the green button again produces another question. Questions start off as relatively easy and gradually get harder. Pressing the red button or the blue button can make the questions easier or harder as desired.

The other programs are variations on the first program to provide questions about subtraction, multiplication and division.

I am hoping that these four programs will one day be converted to run on a DVB-MHP platform and possibly broadcast as part of Astrolabe Channel. Accordingly I shall try to separate those parts of the application programs that differ amongst the set of four programs from those parts of the application programs that are common amongst the set of four programs so that a conversion to DVB-MHP format may be carried out by first producing a DVB-MHP format version of the addition questions program and then copying that program three times and converting the thus produced copies into subtraction questions, multiplication questions and division questions programs, rather than have to convert all four programs directly and individually from their web based format to a DVB-MHP format.

I begin by generating a file ast00701.java as a copy of the file ast00601.java that I used in the "Programming with a mouse unit." document. I change the name of the class to become ast00701 and change the date.

Firstly I shall take out those parts of the copied program that relate to the application program within the ast00601 program, so as to leave a simulation of a DVB-MHP terminal that has activated buttons and mouse capability, yet having no application program simulated as running upon it.

Now, this set of four programs do not use a mouse. However, I shall leave all of the mouse simulation capability in the simulation parts of the program.

I shall also leave the part where the application tests for whether there is a mouse attached to the particular simulated DVB-MHP system. This may not be necessary, but I have left it in so as to provide for the possibility that this software might be adapted to some later program and so it will be clearer as to how the question of whether a mouse is attached to the DVB-MHP terminal is determined.

In the event, by taking care how I wrote the program, the only changes necessary to a copy of the addition questions program to produce the subtraction questions program are to change the name of the class of the program, change the title string and to change the generateaquestion (that is the "generate a question") function. In view of the fact that the title string is within the polyglot compatibility section, a comment in the body of the program is also changed.

Copies of the addition questions program intended to be modified so as to produce the multiplication questions and division questions programs need the above changes and also need a smaller value of the maximumupperlimitpossible variable (that is, the "maximum upper limit possible" variable) in order to avoid problems with two huge numbers being multiplied together and causing overflow.

An interesting feature is if these programs are to be translated so that the strings that are presently presented on the screen in English are presented on the screen in some other natural language, then, once the strings for the addition program have been translated, then only one string needs to be translated for each of the subtraction questions, division questions and multiplication questions programs.

Here are links to viewing the web based simulations. A Java enabled browser is required.

The web based simulation of the addition questions program.

The web based simulation of the subtraction questions program.

The web based simulation of the multiplication questions program.

The web based simulation of the division questions program.

Here is the source code of the Java applet for the addition questions program. Following this full listing are listings of the changes that need to be made in order to produce the subtraction questions, multiplication questions and division questions programs. In relation to the generateaquestion function for each of the three later programs, the source code of the whole function is presented for ease of constructing the source code of each of the three later programs rather than just the changes to the generateaquestion function of the addition questions program that are needed.

import java.awt.*;
import java.awt.event.*;
 
public class ast00701 extends java.applet.Applet implements
                               ActionListener,MouseListener
 
// Software written by William Overington
// WOverington@ngo.globalnet.co.uk
// 18 July 2001
// Copyright 2001 William Overington
//
 
  {
    int obeycode;
    int storedobeycode;
    int pressx,pressy;
 
    boolean SIMULATION_DVB_MHP_MOUSE_ATTACHED=false;
// this is what the simulation management environment knows
 
    boolean mouseattached;
// this is what the simulated program knows
 
    Button colourButton1  = new Button("");
    Button colourButton2  = new Button("");
    Button colourButton3  = new Button("");
    Button colourButton4  = new Button("");
    Button digitButton0   = new Button("0");
    Button digitButton1   = new Button("1");
    Button digitButton2   = new Button("2");
    Button digitButton3   = new Button("3");
    Button digitButton4   = new Button("4");
    Button digitButton5   = new Button("5");
    Button digitButton6   = new Button("6");
    Button digitButton7   = new Button("7");
    Button digitButton8   = new Button("8");
    Button digitButton9   = new Button("9");
    Button upButton       = new Button("^");
    Button downButton     = new Button("v");
    Button leftButton     = new Button("<");
    Button rightButton    = new Button(">");
    Button enterButton    = new Button("E");
    Button teletextButton = new Button("T");

    Font buttonsfont,displayfont;
 
// polyglot compatibility section starts
    String title="Addition questions.";
    String messageaboutred="Make the questions easier please.";
    String messageaboutgreen="New question please.";
    String messageaboutyellow="Please give the answer.";
    String questionneeded="No answer without a question!";
    String messageaboutblue="Make the questions harder please.";
    String messageeasiestalready="The questions are the easiest available.";
    String messagehardestalready="The questions are the hardest available.";
    String messageeasiest="The questions are now the easiest available.";
    String messagehardest="The questions are now the hardest available.";
    String messageeasier="The questions will now be easier.";
    String messageharder="The questions will now be harder.";
// polyglot compatibility section finishes
 
    String operator=" ? ";
    String equals=" = ";
 
    int first=2;
    int second=2;
    int third;
    int maximumupperlimitpossible=999999;
    int minimumupperlimitpossible=8;
    int upperlimitinuse=8;
 
    boolean questionexists=false;
 
    public void init()
      {
        setLayout(null);
        setBounds(0,0,512,400);
 
        buttonsfont = new Font("SansSerif", Font.PLAIN, 18);
        displayfont = new Font("SansSerif", Font.PLAIN, 24);
        setFont(buttonsfont);
 
        colourButton1.addActionListener(this);
        colourButton1.setLocation(16,327);
        colourButton1.setSize(25,25);
        colourButton1.setBackground(Color.red);
        add(colourButton1);
        colourButton2.addActionListener(this);
        colourButton2.setLocation(48,327);
        colourButton2.setSize(25,25);
        colourButton2.setBackground(Color.green);
        add(colourButton2);
        colourButton3.addActionListener(this);
        colourButton3.setLocation(80,327);
        colourButton3.setSize(25,25);
        colourButton3.setBackground(Color.yellow);
        add(colourButton3);
        colourButton4.addActionListener(this);
        colourButton4.setLocation(112,327);
        colourButton4.setSize(25,25);
        colourButton4.setBackground(Color.blue);
        add(colourButton4);
        digitButton0.addActionListener(this);
        digitButton0.setLocation(16,359);
        digitButton0.setSize(25,25);
        digitButton0.setBackground(Color.lightGray);
        add(digitButton0);
        digitButton1.addActionListener(this);
        digitButton1.setLocation(48,359);
        digitButton1.setSize(25,25);
        digitButton1.setBackground(Color.lightGray);
        add(digitButton1);
        digitButton2.addActionListener(this);
        digitButton2.setLocation(80,359);
        digitButton2.setSize(25,25);
        digitButton2.setBackground(Color.lightGray);
        add(digitButton2);
        digitButton3.addActionListener(this);
        digitButton3.setLocation(112,359);
        digitButton3.setSize(25,25);
        digitButton3.setBackground(Color.lightGray);
        add(digitButton3);
        digitButton4.addActionListener(this);
        digitButton4.setLocation(144,359);
        digitButton4.setSize(25,25);
        digitButton4.setBackground(Color.lightGray);
        add(digitButton4);
        digitButton5.addActionListener(this);
        digitButton5.setLocation(176,359);
        digitButton5.setSize(25,25);
        digitButton5.setBackground(Color.lightGray);
        add(digitButton5);
        digitButton6.addActionListener(this);
        digitButton6.setLocation(208,359);
        digitButton6.setSize(25,25);
        digitButton6.setBackground(Color.lightGray);
        add(digitButton6);
        digitButton7.addActionListener(this);
        digitButton7.setLocation(240,359);
        digitButton7.setSize(25,25);
        digitButton7.setBackground(Color.lightGray);
        add(digitButton7);
        digitButton8.addActionListener(this);
        digitButton8.setLocation(272,359);
        digitButton8.setSize(25,25);
        digitButton8.setBackground(Color.lightGray);
        add(digitButton8);
        digitButton9.addActionListener(this);
        digitButton9.setLocation(304,359);
        digitButton9.setSize(25,25);
        digitButton9.setBackground(Color.lightGray);
        add(digitButton9);
        upButton.addActionListener(this);
        upButton.setLocation(372,327);
        upButton.setSize(25,25);
        upButton.setBackground(Color.lightGray);
        add(upButton);
        downButton.addActionListener(this);
        downButton.setLocation(372,359);
        downButton.setSize(25,25);
        downButton.setBackground(Color.lightGray);
        add(downButton);
        leftButton.addActionListener(this);
        leftButton.setLocation(340,343);
        leftButton.setSize(25,25);
        leftButton.setBackground(Color.lightGray);
        add(leftButton);
        rightButton.addActionListener(this);
        rightButton.setLocation(404,343);
        rightButton.setSize(25,25);
        rightButton.setBackground(Color.lightGray);
        add(rightButton);
        enterButton.addActionListener(this);
        enterButton.setLocation(439,359);
        enterButton.setSize(25,25);
        enterButton.setBackground(Color.lightGray);
        add(enterButton);
        teletextButton.addActionListener(this);
        teletextButton.setLocation(471,359);
        teletextButton.setSize(25,25);
        teletextButton.setBackground(Color.lightGray);
        add(teletextButton);
 
        addMouseListener(this);
 
        setBackground(Color.black);
 
        obeycode=1;
        storedobeycode=1;
 
      }
 
    public void actionPerformed(ActionEvent event)
      {
        Object source = event.getSource();
 
        if (source == colourButton1)
          {
            obeycode=51;
            repaint();
          }
        else
        if (source == colourButton2)
          {
            obeycode=52;
            repaint();
          }
        else
        if (source == colourButton3)
          {
            obeycode=53;
            repaint();
          }
        else
        if (source == colourButton4)
          {
            obeycode=54;
            repaint();
          }
        else
        if (source == digitButton0)
          {
            obeycode=20;
            repaint();
          }
        else
        if (source == digitButton1)
          {
            obeycode=21;
            repaint();
          }
        else
        if (source == digitButton2)
          {
            obeycode=22;
            repaint();
          }
        else
        if (source == digitButton3)
          {
            obeycode=23;
            repaint();
          }
        else
        if (source == digitButton4)
          {
            obeycode=24;
            repaint();
          }
        else
        if (source == digitButton5)
          {
            obeycode=25;
            repaint();
          }
        else
        if (source == digitButton6)
          {
            obeycode=26;
            repaint();
          }
        else
        if (source == digitButton7)
          {
            obeycode=27;
            repaint();
          }
        else
        if (source == digitButton8)
          {
            obeycode=28;
            repaint();
          }
        else
        if (source == digitButton9)
          {
            obeycode=29;
            repaint();
          }
        else
        if (source == upButton)
          {
            obeycode=61;
            repaint();
          }
        else
        if (source == downButton)
          {
            obeycode=62;
            repaint();
          }
        else
        if (source == leftButton)
          {
            obeycode=63;
            repaint();
          }
        else
        if (source == rightButton)
          {
            obeycode=64;
            repaint();
          }
        else
        if (source == enterButton)
          {
            obeycode=91;
            repaint();
          }
        else
        if (source == teletextButton)
          {
            obeycode=92;
            repaint();
          }
 
      }
 
    public void mousePressed(MouseEvent e)
      {
        pressx=e.getX();
        pressy=e.getY();
 
        if ((pressy > 300) & (pressy < 311))
// then a command to the simulation environment management is intended
//
// the 300 is used in the test rather than 288 so as to give a blank area below
// the simulated display screen just in case a click intended for the bottom
// of the simulated display screen is clicked a few pixels low in error 
          {
            if (pressx < 256) // simulated no DVB-MHP mouse
              {
                SIMULATION_DVB_MHP_MOUSE_ATTACHED=false;
              }
            else // simulated DVB-MHP mouse present
              {
                SIMULATION_DVB_MHP_MOUSE_ATTACHED=true;
              }
            obeycode=1;
            repaint();
          }
        else if (pressy <= 287)
// then a click within the simulation on the simulated display screen is intended
          {
            if(SIMULATION_DVB_MHP_MOUSE_ATTACHED)
              {
                obeycode=41;
                repaint();
              }
            else
              {
                donothing();
              }
          }
        else
// the mouse press is on the simulated hand held infra-red control device
// or the upper part of the white area and is disregarded
          {
            donothing();
          }
 
      }
 
    public void mouseReleased(MouseEvent e)
      {
 
      }
 
    public void mouseClicked(MouseEvent e)
      {
 
      }
 
    public void mouseEntered(MouseEvent e)
      {
       
      }
 
    public void mouseExited(MouseEvent e)
      {
        
      }
 
    public void paint(Graphics screen)
      {
 
        storedobeycode=obeycode;
 
        screen.setFont(displayfont);
 
        if(obeycode == 1)
          {
// start up for the simulation management
            screen.setColor(Color.black);
            screen.fillRect(0,0,512,288);
            screen.setColor(Color.white);
            screen.fillRect(0,288,512,112);
            screen.setColor(Color.gray);
            screen.fillRoundRect(0,311,512,89,20,20);
            screen.clipRect(0,0,512,288);
// start up for the program that is being simulated
            mouseattached=SIMULATION_FOR_MOUSE_getInputDeviceSupported();
            screen.setColor(Color.cyan);
            screen.drawString(title,20,50);
// title in English is "Addition questions."
            screen.setColor(Color.green);
            screen.fillRect(15,110,20,20);
            screen.setColor(Color.yellow);
            screen.fillRect(15,150,20,20);
            screen.setColor(Color.red);
            screen.fillRect(15,190,20,20);
            screen.setColor(Color.blue);
            screen.fillRect(15,230,20,20);
            screen.setColor(Color.cyan);
            screen.drawString(messageaboutgreen,40,130);
// messageaboutgreen in English is "New question please."
            screen.drawString(messageaboutyellow,40,170);
// messageaboutyellow in English is "Please give the answer."
            screen.drawString(messageaboutred,40,210);
// messageaboutred in English is "Make the questions easier please."
            screen.drawString(messageaboutblue,40,250);
// messageaboutblue in English is "Make the questions harder please."
          }
        else
        if(obeycode == 51) // red button pressed
          {
// make the questions easier
            screen.setColor(Color.black);
            screen.fillRect(0,185,512,103);
// only the bottom part of the screen is cleared, so as not to
// over write the text in the upper part of the screen.
            if(upperlimitinuse == minimumupperlimitpossible)
              {
            screen.setColor(Color.cyan);
            screen.drawString(messageeasiestalready,20,240);
// messageeasiestalready in English is "The questions are the easiest available."
              }
            else
              {
                upperlimitinuse=upperlimitinuse/5;
                if(upperlimitinuse <= minimumupperlimitpossible)
                  {
                    upperlimitinuse=minimumupperlimitpossible;
                    screen.setColor(Color.cyan);
                    screen.drawString(messageeasiest,20,240);
// messageeasiest in English is "The questions are now the easiest available."
                  }
                else
                  {
                    screen.setColor(Color.cyan);
                    screen.drawString(messageeasier,20,240);
// messageeasier in English is "The questions will now be easier."
                  }
              }
          }
        else if(obeycode == 52) // green button pressed
          {
// generate a new question
            generateaquestion();
            screen.setColor(Color.black);
            screen.fillRect(0,0,512,288);
            screen.setColor(Color.green);
            screen.drawString("" + first + operator + second + equals,20,170);
          }
        else if(obeycode == 53) // yellow button pressed
          {
// display the answer to the present question
            screen.setColor(Color.black);
            screen.fillRect(0,0,512,185);
// only the top part of the screen is cleared, in case any messages have
// been added lower down
            screen.setColor(Color.yellow);
            if(questionexists)
              {
                screen.drawString("" + first + operator + second + equals + third,20,170);
              }
            else
              {
                screen.drawString(questionneeded,20,170);
// questionneeded in English is "No answer without a question!"
              }
          }
        else if(obeycode == 54) // blue button pressed
          {
// make the questions harder
            screen.setColor(Color.black);
            screen.fillRect(0,185,512,103);
// only the bottom part of the screen is cleared, so as not to
// over write the text in the upper part of the screen.
            if(upperlimitinuse == maximumupperlimitpossible)
              {
            screen.setColor(Color.cyan);
            screen.drawString(messagehardestalready,20,240);
// messagehardestalready in English is "The questions are the hardest available."
              }
            else
              {
                upperlimitinuse=upperlimitinuse*5;
                if(upperlimitinuse >= maximumupperlimitpossible)
                  {
                    upperlimitinuse=maximumupperlimitpossible;
                    screen.setColor(Color.cyan);
                    screen.drawString(messagehardest,20,240);
// messagehardest in English is "The questions are now the hardest available."
                  }
                else
                  {
                    screen.setColor(Color.cyan);
                    screen.drawString(messageharder,20,240);
// messageharder in English is "The questions will now be harder."
                  }
              }
          }
        else if(obeycode == 41) // response to pressing the mouse button
          {
            donothing();
          }
 
        obeycode=1;      
      }
 
    public void update(Graphics screen)
      {
        paint(screen);
      }
 
    private void donothing()
      {
//      does nothing
      }
 
    private boolean SIMULATION_FOR_MOUSE_getInputDeviceSupported()
      {
        return SIMULATION_DVB_MHP_MOUSE_ATTACHED;
      }
 
    private void generateaquestion()
      {
        int a,b,c;
        double r;
        operator=" + ";
        r=Math.random();
        a=(int)(((upperlimitinuse - 1) * r) + 2);
        r=Math.random();
        b=(int)(((upperlimitinuse - 1) * r) + 2);
        c=a + b;
        first=a;
        second=b;
        third=c;
// using a and b as the random numbers then copying is done so that division
// questions can be easily produced by producing a multiplication and then
// copying it to produce a division.
        questionexists=true;
// this is so that pushing the yellow button before pushing the green button
// will not give an incorrect result
// it is done this way rather than build in a question to the program by declaring
// an initial value for operator and for third so that only this function needs to
// be changed for producing versions of this program for subtraction, multiplication
// and division.
        upperlimitinuse=upperlimitinuse+1;
        if(upperlimitinuse > maximumupperlimitpossible)
          {
            upperlimitinuse=maximumupperlimitpossible;
          }
      }
 
  }

Here are the versions of the title string and the generateaquestion function for the subtraction program, which is the ast00702 program.

    String title="Subtraction questions.";

and

// title in English is "Subtraction questions."

and

    private void generateaquestion()  // subtraction question
      {
        int a,b,c;
        double r;
        operator=" - ";
        r=Math.random();
        a=(int)(((upperlimitinuse - 1) * r) + 2);
        r=Math.random();
        b=(int)(((a - 2) * r) + 2);
        c=a - b;
        first=a;
        second=b;
        third=c;
// using a and b as the random numbers then copying is done so that division
// questions can be easily produced by producing a multiplication and then
// copying it to produce a division.
        questionexists=true;
// this is so that pushing the yellow button before pushing the green button
// will not give an incorrect result
// it is done this way rather than build in a question to the program by declaring
// an initial value for operator and for third so that only this function needs to
// be changed for producing versions of this program for subtraction, multiplication
// and division.
        upperlimitinuse=upperlimitinuse+1;
        if(upperlimitinuse > maximumupperlimitpossible)
          {
            upperlimitinuse=maximumupperlimitpossible;
          }
      }

Here are the title string, the value of maximumupperlimitpossible, the comment and the generateaquestion function for the multiplication program, which is the ast00703 program.

    String title="Multiplication questions.";

and

    int maximumupperlimitpossible=9999;

and

// title in English is "Multiplication questions."

and

    private void generateaquestion()  // multiplication question
      {
        int a,b,c;
        double r;
        operator=" x ";
        r=Math.random();
        a=(int)(((upperlimitinuse - 1) * r) + 2);
        r=Math.random();
        b=(int)(((upperlimitinuse - 1) * r) + 2);
        c=a * b;
        first=a;
        second=b;
        third=c;
// using a and b as the random numbers then copying is done so that division
// questions can be easily produced by producing a multiplication and then
// copying it to produce a division.
        questionexists=true;
// this is so that pushing the yellow button before pushing the green button
// will not give an incorrect result
// it is done this way rather than build in a question to the program by declaring
// an initial value for operator and for third so that only this function needs to
// be changed for producing versions of this program for subtraction, multiplication
// and division.
        upperlimitinuse=upperlimitinuse+1;
        if(upperlimitinuse > maximumupperlimitpossible)
          {
            upperlimitinuse=maximumupperlimitpossible;
          }
      }

Here are the title string, the value of maximumupperlimitpossible, the comment and the generateaquestion function for the division program, which is the ast00704 program.

    String title="Division questions.";

and

    int maximumupperlimitpossible=9999;

and

// title in English is "Division questions."

and

    private void generateaquestion()  // division question
      {
        int a,b,c;
        double r;
        operator=" / ";
        r=Math.random();
        a=(int)(((upperlimitinuse - 1) * r) + 2);
        r=Math.random();
        b=(int)(((upperlimitinuse - 1) * r) + 2);
        c=a * b;
        first=c;
        second=b;
        third=a;
// using a and b as the random numbers then copying is done so that division
// questions can be easily produced by producing a multiplication and then
// copying it to produce a division.
        questionexists=true;
// this is so that pushing the yellow button before pushing the green button
// will not give an incorrect result
// it is done this way rather than build in a question to the program by declaring
// an initial value for operator and for third so that only this function needs to
// be changed for producing versions of this program for subtraction, multiplication
// and division.
        upperlimitinuse=upperlimitinuse+1;
        if(upperlimitinuse > maximumupperlimitpossible)
          {
            upperlimitinuse=maximumupperlimitpossible;
          }
      }

These four programs together with the previous programs now constitute a collection of programs giving sufficient content for Astrolabe Channel to become broadcast on an experimental basis.

 

Astrolabe Channel

Copyright 2001 William Overington

This file is accessible as follows.

http://www.users.globalnet.co.uk/~ngo/ast00700.htm