A Modest Program to Calculate Age

By Welopez, with snide remarks from Worbles

 

 

Sometimes I wonder if it's worth all the trouble of having Worbles assist me when I'm writing code.  Sure, they know what they're doing, but do they have to be so darned smug about it?

 

Last week I was filling out some of those dratted government forms.  For some reason, I always have difficulty remembering my age, until I figure it out.  You see, I was born in December, and if you subtract my birth year from 2005, well, it just don't come out right.  So I decided to write a basic program that would figure it out for me any time I need it, and get the dratted age correct too!

 

The first thing I had to do was to set up a GUI.  I knew I wanted two buttons, one to repeat the calculation using another birth date, and one to quit the program.  I decided to OPEN a WINDOW FOR DIALOG, which would allow me to use a default button and, when the user presses ENTER, the remainder of the program executes.

 

"Hide it!" Mike shouted at me!

 

"Yeah, hide it!" Pablo shouted, "Then I won't need to paint it!"  Egads, he's getting lazy!

 

Could I do that?  My program will get the birth date from a text box, but a default requires a branch label, which buttons have but textboxes do not.  Okay, I must have a button in existance, but does it actually have to be in the window?  I thought I'd give it a try and see if I could locate the button outside the window.  This is my code:

 

'Program to display current age in days, weeks, months, and years

 

NOMAINWIN

WindowWidth=400

WindowHeight=300

UpperLeftX=INT((DisplayWidth-WindowWidth)/2)

UpperLeftY=INT((DisplayHeight-WindowHeight)/2)

 

BUTTON #curAge.default,"",[enter], UL, 0,  0, 0, 0  'Hides the button

BUTTON #curAge.btn1, "QUIT", [quit], UL, 225, 235, 70, 25

BUTTON #curAge.btn2, "AGAIN", [getInp], UL, 115, 235, 70, 25

STATICTEXT #curAge.stx1, "Your birth date? (mm/dd/yyyy)", 10, 20, 250, 25

TEXTBOX #curAge.txt, 265, 18, 115, 30

STATICTEXT #curAge.stx2, "", 10, 50, 350, 25   'days

STATICTEXT #curAge.stx3, "", 10, 80, 350, 25   'weeks

STATICTEXT #curAge.stx4, "", 10, 110, 350, 25  'months

STATICTEXT #curAge.stx5, "", 10, 140, 350, 25  'years

STATICTEXT #curAge.stx6, "", 10, 170, 350, 25  'years and months

STATICTEXT #curAge.stx7, "", 10, 200, 350, 25  'Msg to user

 

'Window for DIALOG allows using ENTER to capture input

OPEN "Calculate Your Current Age" FOR DIALOG AS #curAge

PRINT #curAge, "trapclose [quit]"

PRINT #curAge, "font Times_New_Roman 14"  'Sets font for entire window

 

Since the program doesn't have to be complete before I test it, I went ahead and pushed RUN!

 

Holy smoke, Batman!  It works!  The default button is hidden off screen!  How cool!

 

Next I had to get the birth date from the user.  By setting focus to the textbox, all the user has to do is type in the mm/dd/yyyy and press ENTER.  OK, let's add a few more lines of code.

 

[getInp]  'Return to this point if doing again

PRINT #curAge.txt, ""  'Clears the textbox if doing again

PRINT #curAge.txt, "!setfocus"

INPUT #curAge.txt, bday$

 

WAIT  'Wait to get input from TEXTBOX

[enter]

PRINT #curAge.txt, "!contents? bday$"  'Get birth date

IF bday$="" then [getInp]

    bday=DATE$(bday$)  'Gets the days of your birth since 1/01/01

    today=DATE$("days")  'Gets the days of current date since 1/01/01

    age=(today-bday)  'Age is today minus birth date

    wks=age/7

    months=(age/365.25)*12

    years=(age/365.25)

 

Practically all the math is shown above.  Months are pesky things.  Sometimes they have 28 days, or 29, and other times they have 30 or 31.  What a silly way to calibrate a yardstick!  For once, my cheering section was not anxious to lend a hand and suggest a method for me to solve my dilemma, they seemed more anxious to have a good laugh if my program bombed!  Okay, Welopez, put on the thinking cap and get to work.  You can't let a bunch of silly Worbles poke fun at you!

 

One thing that does not change is the number of days between dates.  The DATE$() function appears to be a string, yet it actually returns a numeric variable using the computer clock.  The first thing I did was to get the birth date from the textbox and check to see if anything had been entered.  Aha!  I remembered to type in my birthday!  One point for the good guy!

 

PRINT #curAge.stx2, "You are "; age; " days old today."

PRINT #curAge.stx3, "You are "; USING("####.#", wks); " weeks old today."

PRINT #curAge.stx4, "You are "; USING("####.#", months); " months old today."

    months=(years-INT(years))*12  'Get fractional part of year remaining

        IF months<2 THEN mo$= " month" _

        ELSE mo$=" months"  'Formats text string, singular or plural

PRINT #curAge.stx5, "You are "; USING("###.#", years); " years old today."

PRINT #curAge.stx6, "You are "; USING("###", years); " years and "; _

    USING("##.#", months); mo$; " old today."

 

IF age>18262 THEN msg$="You are eligible to join AARP!" _

    ELSE msg$="You are not yet old enough to join AARP."

PRINT #curAge.stx7, msg$

 

WAIT

[quit]

    CLOSE #curAge

    END

 

Set bday=DATE$(bday$) and I get a value for my birth date.  Next I check today's date using today=DATE$("days"), then I subtract bday from today and now I have my age in days.  Oh, my God!  Am I really that old?  I run it through the debugger to see if I've made a goof.  (I've had lots of practice goofing.)

 

No, that seems to be correct.  Okay, lets print age to #curAge.stx2.  Now divide age/7 and we'll print weeks to #curAge.stx3.  I don't need 8 decimals in my result, so I'll print USING("####.#", wks).  RUN again, hey that works too!  My Worbles seem to be disappointed… no major problems yet.

 

Calculating months is the tricky part.  No one has yet invented a metric system for the calendar.  Okay, the best I can do is divide the total number of days by 365.25, because every year has 365 and a smidgin days.  Total days, age/325.25=months, will be printed USING("####.#", months) to #curAge.stx4.  RUN again.  There!  Take that you sniveling Worbles!  Welopez can figure some things out too!

 

In the next STATICTEXT, I'll simply print USING("###.#", age/365.25) to #curAge.stx5.  If I live to be 999.9 years old, I won't have to update this program.  (You write your program your way, I'll do it mine!)

 

To be even more professional, I'm going to print the years and months to #curAge.stx6.  I want to appear to be grammatically correct, so I'm going to use mo$ twice.  In one case, it will be month, singular, and in the other it will be months, plural.  I'll use an IF/THEN comparison to see if months < 2.  The hard part is trimming the months off the total years.  So far, the only constant we have used is age.  Years=(age/365.25), so if I set months=years-INT(age/365.25)*12, what remains is the decimal fraction of the remaining year.  After the IF/THEN statement decides whether to print month or months, we'll print the result to #curAge.stx6.  Press RUN again and…

 

 

Gee, whilickers, Welopez!  That works too!  Oh, be still my beating heart!  "See, fellas?  I can write a program too!  Even if it is sort of simple, and sort of obvious.  But I did use the INT() function to extract the decimal part of a year, and I did format those numbers with PRINT USING("###.#") to suit what I needed, I set an invisible button off screen so I could use the [branchTo] label as the default action, and I even printed a message depending whether the user could or could not join AARP!"

 

"You done good, Welopez!" my cheering section cried.  "We weren't hoping to see you fail, we wanted to see how much you had learned.  Why, you've done so well, we might just make you an honorary Worble!"