A mathematical graph example -- Descartes' folie
The following example provides the time of day in English.
It is a derivation of Michael Cowlishaw's QT example program.
The example illustrates the object-oriented concept of polymorphism.
The qt class (qt.roo) prepares the time of day, and sends it to an abstract emitter class.
Actual emitter class derivatives can present the time using various alternatives.
One emitter might use a scrolling HTML marquee, another might use a pop-up message box, while yet another may actually use an audio converter to speak the time.
/* qt.roo This is the supporting QT class file for the 'query time' example program from TRL-2 p172 which tells the current time in English. */ local out -- the output text destination local specificTime -- a specific time to display initialize : method parse arg out, specificTime -- set local variables from parameters -- ensure output destination is an instance if \ datatype( out, 'Instance' ) then do ^^ console ~ writeLine( 'The parameter for QT.ROO should be an output destination object instance' ) return 'The parameter for QT.ROO should be an output destination object instance' end return '' settime : method specificTime = arg(1) -- prepare to display a specific time return now telltime : method out ~ writeCharacters( "It's" ) -- start output phrase if specificTime = '' then now = time() -- show current time else now = specificTime -- show specific time -- prepare nearby time clauses near = { , '' , , ' just gone' , , ' just after' , , ' nearly' , , ' almost' } -- get hour, minute, and second parse var now hour ':' min ':' sec -- round minutes if sec > 29 then min = min+1 -- determine REMAINDER of minutes divided by 5 -- emit 'near' phrase out ~ writeCharacters( near[ 1 + ( min // 5 ) ] ) -- round hour if min > 32 then hour = hour + 1 -- increment minutes by nearby interval min = min + 2 -- show exactly noon or midnight if hour // 12 = 0 & min // 60 <= 4 then do if hour=12 then out ~ writeCharacters( 'Noon' ) else out ~ writeCharacters( 'Midnight' ) return '' end -- reduce minutes to 5 minute interval base min = min - ( min // 5 ) if hour > 12 then hour = hour - 12 -- reduce PM times by 12 hours else if hour = 0 then hour = 12 -- 0 hour: is 12 to 1 am -- prepare 5 minute interval clauses roundedMinute = , { , '' , , 'five past' , , 'ten past' , , 'a quarter past' , , 'twenty past' , , 'twenty-five past' , , 'half past' , , 'twenty-five to' , , 'twenty to' , , 'a quarter to' , , 'ten to' , , 'five to' , , '' } -- emit 'rounded' phrase out ~ writeCharacters( ' 'strip( roundedMinute[ 1 + ( min / 5 ) ], 'T' ) ) -- hour numbers hourNumbers = { 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve' } out ~ writeCharacters( ' 'hourNumbers[ hour ] ) -- add current hour if 0 = ( min // 60 ) then out ~ writeCharacters( " o'clock" ) -- it's exactly a specific hour clause -- done ! return ^ self -- return 'qt' instance reference
The main program (qt.rooProgram) allows the user to select a specific emitter to use for presentation of the time.
/* qt.rooProgram
This is a roo!(TM) version
of the 'query time' example program from TRL-2 p172
which tells the current time in English.
usage:
roo qtRoo.rooProgram [emitterClass _ hh:mm:ss]
'emitterClass' is one of:
audiotext console outstream htmlnote htmltext marquee msgbox xmltext
related programs:
qtVoice.rooProgram -- tells the time once, vocally
qtVoiceEndless.rooProgram -- tells the time vocally, endlessly
Alternate output emitters are passed to the supporting qt.roo program.
This program uses the related PICKLIST.EXE program to select an output emitter.
*/
-- validate arguments
arg parm '_' testtime .
outputEmitter = ''
-- 'emitter' is a vector of supported output emitter class names
emitter = { 'AUDIOTEXT', 'CONSOLE', 'OUTSTREAM', 'HTMLNOTE', ,
'HTMLTEXT', 'MARQUEE', 'MSGBOX', 'XMLTEXT' }
select
when parm='?' then
call usagemsg
when wordpos( parm, emitterClasses ) > 0 then
outputEmitter = parm
when parm = '' then do -- let the user pick the emitter type
choices = { 'What output format would you prefer?' , ,
'Audio' , ,
'Console' , ,
'Default output' , ,
'HTML note' , ,
'HTML text' , ,
'Marquee' , ,
'Message box' , ,
'XML note' } ~ toString
trace o
'PICKLIST' choices
if rc = 0 then
exit 1 /* cancel was selected */
outputEmitter = emitter[ rc ]
end
otherwise
call usagemsg 'Invalid argument: 'parm
end
-- note: outputEmitter is a class name,
-- which is the value of a variable.
dest = ^^ outputEmitter -- prepare text destination
-- the 'qt.roo' class prepares the text
^^ qt( dest, testtime ) ~ telltime
-- additional preparations
if outputEmitter <> 'AUDIOTEXT' then
dest ~ writeCharacters( '.' ) -- add trailing period
if outputEmitter = 'HTMLTEXT' then do
dest ~ setTag( 'div' )
dest ~ attribute( 'align', 'center' ) ~ attribute( 'style', 'color:yellow; background-color:navy' )
end
if outputEmitter = 'MSGBOX' then
dest ~ setCaption( 'A message from QT !' ) -- add caption
-- emit the text
-- which is the time of day, in English
dest ~ emit
-- done !
exit 0
usagemsg :
con = ^^ console
con ~ writeLine( arg(1), '', 'Usage:', ' roo QT.rooProgram [ emitterClass [ _ hh:mm:ss ] ]' )
con ~ writeLine( '', 'Supported emitter classes are:', ' 'emitterClasses )
The audiotext class (audiotext.roo) emits the text to a wave program.
The wave program processes each word, in the sentence describing the time, as the name of a wave file.
The time of day is spoken.
/* audiotext.roo a class that collects stream output to a text value */ audiotext : class extends outtext -- text is collected by the 'outtext' class shared text -- 'text' is a shared symbol in the 'outtext' class emit : method ! 'WAVE' text -- text is emitted to the 'wave.exe' program. -- each word within the text symbol is -- considered a .WAV file name, -- with an implicit ".WAV" extension. -- english text is spoken if the wave file -- is a recording of the associated word ! return ^ self -- an audiotext instance context reference