Snyder 7 April ’99

Project 1

Astrological Toys

In this project a series of window applications will be written that look up and display astrological signs and dates. The applications that will make up the project are as follows:

The projects are written in Visual Basic 6.0 and serve as the initial foray into algorithmic thinking, program design and the characteristics of VB6.

It is suggested you create a new folder for each project. This will assist you in keeping track of all of the various files produced as well as simplifying saving your work to the floppy disk.

This Time. This is a simple digital clock program with the date on the window bar. The goal in writing the digital clock program is to create an initial VB6 program. The essential features are

Each of these features will be discussed below. The ThisTime application has the following window interface:

Open Visual Basic 6.0 (accessed as an element of Visual Studio 6.0), and click on the Standard.exe

application that is highlighted. This will open a project, probably called Project 1, with a new form, called Form1.

  1. Form Name Change. Revise the name of the form to frmClock by editing the (Name) entry in the form’s property list.
  2. Change Caption. The caption on the form’s window bar is to be assigned the current date at the time the window is loaded. Therefore, the "Form_Load" event should be customized to assign the date to the caption. The following code should suffice:
  3. Private Sub Form_Load()

    frmClock.Caption = Date

    End Sub

    Date is a built in global variant object that returns the date as set on the computer in the form mm/dd/yy. When the form is loaded, the current date will appear on the window bar.

  4. Place Label. A label control is placed on the form, and the name of the label revised to be lblTime. Select a better font, and enlarge it to approximately 20 points.
  5. Place Timer. A timer control is placed on the form (it can be hidden), and the name of this control should be revised to be tmrTime. Set the interval property to be 1000, i.e. the timer should "go off" every 1000 milliseconds = 1 second. That time event should cause the caption on the label to be set to the time. Code along the following lines should suffice:
  6. Private Sub tmrTime_Timer()

    lblTime.Caption = Time

    End Sub

    Time is like Date, a built in global variant that returns time in hh:mm:ss xM format. What happens is this: The timer "goes off" every second. That event causes the procedure "tmrTime" to be called. It changes the caption of the label to the current time. Whenever anything on the form is changed, the window is "repainted," i.e. redisplayed. Since most of the information is unchanged and remains in a fixed position, the clock appears to be ticking.

  7. Customize. Change the properties of the window to be attractive. This includes …
    1. Change the form’s background color.
    2. Shrink the window so that it nicely frames the time symbols.
    3. Revise the background color of the label to match the background of the window.
    4. Revise the color of the font of the label to be attractive and to contrast pleasantly with the window’s background.
    5. Set the starting position property of the form to be the center of the screen.
  1. Icon. Select an icon for the form. This is done by clicking on the icon property, finding the VB Common directory (it may be higher in the hierarchy) à Graphics à Icons à Elements, and selecting an icon from those shown. A moon symbol would be "astrological" but any icon will do.
  2. Save. Save the project as ThisTime. This will create a file called ThisTime.vbp with a multicolored project icon to go with it, and ThisTime.vbw with the standard window icon. You should also save the form, which will produce the file, frmClock.frm with the form icon and frmClock.frx, which has the standard windows icon. There may also be a file with a .scc extension in the same directory, which you can ignore.

When completed, compile your program by going to Make ThisTime.exe in the File menu. That operation will make another file in the directory you. This is the ThisTime.exe file, which has the icon that you selected. To run your program, double click on the ThisTime.exe.

To save your work you will have to move these files to your floppy disk or to your Dante directory. And to work on them again, you’ll have to bring them back from Dante to a PC.


Sign Finder:
The SignFinder program will be discussed in class. Sign Finder has the following graphic interface

Zodiac Range: The goal is to present the user with a set of 12 radio buttons corresponding to the Zodiac signs, and when one is pressed, to print out the starting and ending dates of that sign. The main task is to construct the form to have the 12 radio buttons, one command button and five labels. Zodiac Range has the following graphic interface

The initial window for the Zodiac application.

The window resulting from clicking "Leo" and "OK"

The overall logic is as follows. The window contains all of the structures shown in both windows above. For the initial window, the "You were born" text, the dates and the "and" are all hidden. When the command (OK) button is pushed, the command button is hidden, and the "You were born" text etc. is made visible.

How to proceed:

  1. Initiate a project and a form template.
  2. Revise the form’s name to "frmZodiac". The ".frm" extension will be added automatically.
  3. Save the form and the project, selecting "Zodiac" as the project name. The ".vbp" extension will be added automatically.
  4. Adopt a new background color, and any other form-based customization, like a decent font and font color, that you think is appropriate.
  5. Double click on the form to bring up the code window. If at the top of the code window it does not say "Option Explicit" then in the Tools window, select "Options …" and in the Editor tab, check "Required Variable Declarations". This will tell the VB6 system that all you intend to declare all variables explicitly, which saves making accidental typos into program bugs.
  6. After the Option Explicit line, enter the variable declarations,
  7. Dim loMo, hiMo As String

    Dim loDate, hiDate As Integer

    Notice how the word completion tries to assist after the "As" is entered. The two string variables will represent the two months that the astrological sign spans, and the two integer variables will represent the starting and ending days. So, for Leo loMo will be assigned the value "July " and hiMo will be assigned "August ". The loDate variable will be assigned 23 and the hiDate will be assigned 22.

    Sign

    Start Date

    End Date

    Aries

    March 21

    April 19

    Taurus

    April 20

    May 20

    Gemini

    May 21

    June 20

    Cancer

    June 21

    July 22

    Leo

    July 23

    August 22

    Virgo

    August 23

    September 22

    Libra

    September 23

    October 22

    Scorpio

    October 23

    November 21

    Sagittarius

    November 22

    December 21

    Capricorn

    December 22

    January 19

    Aquarius

    January 20

    February 18

    Pisces

    February 19

    March 20

     

    Table 1. Listing of astrological signs

  8. In the form, place the 12 option or radio buttons, naming each with a new name. The name should begin with the letters "cmd" and be followed by the first three letters of the sign. The name for the Aries button will be cmdAri. Change the caption on the button to the intended Zodiac sign. Correct the background color, font and any other features of the button.
  9. Once the buttons are defined, place labels for the text lines on the form:
  10. "Enter your Zodiac sign"

    "You were born between"

    "starting date"

    "and"

    "ending date"

    Name the labels lblHead, lblBorn, lblSDate, lblAnd, lblEDate, respectively. Correct the fonts, background colors and any other needed properties. The last four labels should be hidden, i.e. have their visibility property set to "false".

    Click on each radio button to bring up the "click event" subroutine for that button. Customize that Sub by setting the loMo to the starting month (followed by a space) in quotes, hiMo to the ending month (followed by a space) in quotes, loDate to the starting day for the sign, and hiDate for the ending day for the sign. The extra space is included so the day doesn’t smash into the month when printed out

    There is one further trick that can be used to make the text appear more natural when it is printed. Assume that the start date precedes the " and ", which is followed by the end date. If these are all printed on the same line, and the start date is right justified, then the two dates will "hug" the "and" and make the text appear without spaces.

    Start date right justified à

    " and "

    ß End date left justified

  11. Finally, add a command button, renamed cmdOK and captioned &OK. Modify its visual properties appropriately. Click on the OK command button to bring up the cmdOK_Click procedure. Set the start and end dates by changing the captions as follows:

lblSDate.Caption = loMonth & loDay

lblEDate.Caption = hiMonth & hiDay

Further, set the visibility of the lblBorn, lblSDate, lblAnd, lblEDate, to True, and visibility of cmdOK to be False.

The program should now run. Give it an icon, and save it. Compile it. Try it out. Show it to your friends, and notice their utter amazement that a computer could be made to do such an amazing feat, a skill once reserved only for astrologers!

Day Finder: The Day Finder, though a small extension to the Zodiac program, is significant because it introduces a powerful algorithm, binary search, and introduces a fundamental component of algorithmic thinking, procedures.

Searching for a day. The Day Finder is an extension of the Zodiac application, in which the user is asked questions that enable the program to say what day he or she was born on. So, Leo’s are known by the Zodiac application to be born between July 23 and August 22. (Remember this includes both the starting and ending dates.) The task is to ask the user questions to determine which day was his or her actual birthday. One strategy would be to ask, "Were you born after July 23?" If the answer was "no", then the program could say, "You were born on July 23", but if the answer were "yes", the program would have to try another question, like "Were you born after July 24?" If the person were born on August 22, this strategy would take 30 questions to cover the 9 days in July (23-31) and the 22 days in August (1-22), which is actually 31 days, but we don’t have to ask about the last day, since a "no" to "Were you born after August 21" implies an August 21 birthday, while a "yes" implies an August 22 birthday.

The Day Finder will use an intelligent searching strategy, called the binary search algorithm. Binary search can be used on any ordered objects, like letters or the dates of a Zodiac sign. It uses a series of questions, sometimes called probes, to eliminate half of the remaining possibilities with each question. For example, suppose I’m thinking of a letter, you may ask, "Is the letter between N and Z?", a question that is equivalent to asking if it is in the last half of the alphabet. Regardless of which answer is given, half of the alphabet is eliminated. The binary search for the letter "L" goes as follows:

Question

Ans

Letters Eliminated

Is the letter after M?

N

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Is the letter after G?

Y

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Is the letter after J?

Y

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Is the letter after L?

N

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Is the letter after K?

Y

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

The letter is L.

 

Notice three points about the example: First, the questions always ask if the letter is after the probe letter. It is possible to ask before and after questions, but always asking the same type simplifies the algorithm. Second, the intervals sometimes have an odd number of letters and sometimes an even number. When it is an odd number, then the middle letter is the probe. When it is an even number, e.g. H-M, then the probe is the last element of the first half of the interval. This is because of the "after formulation" of the questions. If the questions had been formulated as before questions, then the first element in the second half would be used. Third the binary search scheme requires only five questions to find any letter. Scientifically, and only for those interested in such things, the binary search takes log2 n probes to find an item among n items, which is the minimum. The thing to remember is that this is the best way to find an item among an ordered sequence.

Finding a birthday works in the just the same way. The only complication is that the sequence of days changes months under the sign, e.g. Leo goes from July to August. This is not really a problem, however, since it is possible to imagine looking for the birthday from July 23rd through July 53rd. Of course, there is no July 53; that’s what August 22 would be if the month didn’t change. The 53 can be found by adding the number of days in July, 31, to the last day of the sign, the 22nd, giving 31 + 22 = 53. This means that the search can look for the birthday between 23 and 53, and whenever a question must be asked about a date larger than 31, the day gets 31 subtracted from it and the month becomes August.

For example, to figure out the first question to ask, we find the mid point between July 23 and July 53 by subtracting the smaller endpoint from the larger:

53 – 23 = 30

and dividing by 2

30 / 2 = 15

If the number had been odd, the 0.5 would have been truncated (or rounded down). Then this number is added to the start of the Leo sign, the 23rd

23 + 15 = 38

which is a day in August since it is larger than the largest day in July, the 31st. Thus, July 38 is really August 7th, since 38-31 = 7. And, it can be checked that this is the middle of the Leo range, just by counting out the days. The result of this computation would be to ask the question:

Were you born after August 7?

which to us is July 38. If the answer is "no," then the interval is 23 to 38. Remember, August 7 (= July 38) is still a possibility. If the answer is "yes" then the interval is 39 to 53. By repeatedly shrinking the interval we can reduce the interval size to one day, say 32 to 32. And that must be the person’s birthday.

The questions to find the birthday August 1 are as follows, where Lo is the lower end of the interval, Hi is the upper end of the interval, Mid is the computed midpoint and Size is the size of the interval.

Lo

Hi

Size

Mid

Question

Ans

NewLo

NewHi

23

53

30

38

Were you born after August 7?

No

23

38

23

38

15

30

Were you born after July 30?

Yes

31

38

31

38

7

34

Were you born after August 3?

No

31

34

31

34

3

32

Were you born after August 1?

No

31

32

31

32

1

31

Were you born after July 31?

Yes

32

32

32

32

0

You were born on August 1

 

Notice that when the endpoints are the same, then they must be for the birthday being sought.

Window asking the first question for the Day Finder application.

Encoding the Binary Search. The Day Finder will be an extension of the Zodiac program, so making a copy of that form is the way to begin. Use Save As in the File menu. Next, add two more variables to the integer declarations at the start of your program

Dim loDate, hiDate, midPt, lastDay As Integer

The midPt will be used to represent the probe point in the interval, and lastDay will be the number of days of the month in which the sign begins.

The process described above is to be encoded in a procedure. Procedures, also known as subroutines in Basic, are simply programs that perform a useful operation, and so have been encapsulated and given a name. A good way to formulate the process above is in terms of making a guess, so the procedure will be called Guess. The Guess procedure will need some data, called parameters, to compute a guess. When a procedure is defined, names are chosen for the parameters. Guess needs to know the lower end of the interval (loend), the upper end (hiend), the midpoint (middle, not strictly needed as a parameter, but included to simplify the programming), the number of days in the month that the interval begins in (numdays), and the names of the two months of the sign (lmonth and hmonth). These make the procedure’s header, which defines its name and lists the (formal) parameters, have the form

Public Sub Guess (loend, hiend, middle, numdays, lmonth, hmonth)

<The instructions of the procedure go here>

End Sub

The "Public" designation allows the private procedures corresponding to the events to use the Guess procedure. The parameters have been given names suggestive of their meaning. The first guess discussed in the previous section would be generated by the Guess procedure call

Call Guess (loDate, hiDate, midPt, lastDay, loMo, hiMo)

where the (actual) parameters have the following values: loDate = 23, hiDate = 53, midPt doesn’t matter, lastDay = 31, loMo = "July " and hiMo = "August ".

How do these variables get these values? For each radio button, some of these values such as loDate, loMo and hiMo are already set correctly for the sign corresponding to that button. It is a simple matter to add a setting for lastDay to each radio button. The variable hiDate is set for each radio button, but not to the right value. The correct value can be set in the cmdOK procedure with the statement

hiDate = hiDate + lastDay

Finally, the midPt parameter doesn’t have to set.

The only remaining task is to reason through the logic of making a guess. The steps were described in the last section for making the first guess for Leo. The instructions for the procedure are simply the same sequence of operations, only they are expressed using the names of the parameters. So, for example, finding the midpoint is expressed

middle = (hiEnd – loEnd) \ 2

where the backslash is the integer division operator, which has the affect of truncating or dropping off any decimal fraction digits. The details of these computations are left to the student.

Overall Logic The overall logic of Day Find follows the Zodiac application in that all of the text items needed for the application are hidden in the initial request, except for the OK command button. When the OK button is clicked, it is hidden, the text is made visible, new "Y" and "N" buttons are made visible for replying to the probes, and the first guess is made. The guesses will use the Guess procedure and so the first call to the Guess procedure will occur in the command OK button. After that, all of the guesses will be computed in connection with the "Y" and "N" button clicks. Of course, the terminating assertion "You were born on …" is printed from the "Y" or "N" buttons.