SECTION(5, Tutorial 5)
m5_question(BO(Question 5.1:) Study the following code and then compile and
run it to verify that it prints out the lyrics to a popular song:
m4_begin_indent
NU()CLASS CLSS(BeerSong) EOL
BEGIN EOL
PD BEGIN_MAIN EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("Five bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("Five bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("If one bottle of beer should accidentally COMMA(fall)")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("there'd be four bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("Four bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("Four bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("If one bottle of beer should accidentally COMMA(fall)")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("there'd be three bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("Three bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("Three bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("If one bottle of beer should accidentally COMMA(fall)")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("there'd be two bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("Two bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("Two bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("If one bottle of beer should accidentally COMMA(fall)")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("There'd be one bottle of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("One bottle of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("One bottle of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("If one bottle of beer should accidentally COMMA(fall)")); EOL
PD PD SYSTEM_OUT_PRINTLN(STRI("there'd be no bottles of beer on the wall.")); EOL
PD PD SYSTEM_OUT_PRINTLN(); EOL
PD END_MAIN EOL
END EOL
m4_end_indent
)
m5_question(BO(Question 5.2:) The following is the first attempt
to make the code smaller but to keep the same output: If you compile
and run the following code you will notice that it counts up from one
rather than down from TT(n). Change the EM(for) loop so that it runs
down rather than up. For information about how to write the for loop,
please consult TUTE_FOR_LOOPS.
m4_begin_indent
NU()CLASS CLSS(BeerSong) EOL
BEGIN EOL
PD FUNCTION FUNC(song)(INT VARI(n)) EOL
PD BEGIN EOL
PD PD FUR (VAR INT VARI(i)=NUMB(1); LTEQ(i,n); i=i+NUMB(1)) EOL
PD PD BEGIN EOL
PD PD PD SYSTEM_OUT_PRINTLN(i + STRI(" bottles of beer on the wall")); EOL
PD PD PD SYSTEM_OUT_PRINTLN(i + STRI(" bottles of beer on the wall")); EOL
PD PD PD SYSTEM_OUT_PRINTLN(STRI("If one bottle of beer should accidentally COMMA(fall)")); EOL
PD PD PD SYSTEM_OUT_PRINTLN(STRI("there'd be ") + (i-NUMB(1)) + STRI(" bottles of beer on the wall")); EOL
PD PD PD SYSTEM_OUT_PRINTLN(); EOL
PD PD END EOL
PD END EOL
EOL
PD BEGIN_MAIN EOL
PD PD song(NUMB(5)); EOL
PD END_MAIN EOL
END EOL
m4_end_indent
)
m5_question(BO(Question 5.3:) Finish the TT(number2string)
function below and add a new function call to this function in the
song function so that it print textual numbers rather than digits.
m4_begin_indent
NU()FUNCTION STRING FUNC(number2string)(INT VARI(n)) EOL
BEGIN EOL
PD ASSERT GTEQ(n,NUMB(0)) : n; EOL
PD ASSERT LTEQ(n,NUMB(10)): n; EOL
PD IF (n == NUMB( 0)) THEN RETURN STRI("no"); EOL
PD IF (n == NUMB( 1)) THEN RETURN STRI("one"); EOL
PD IF (n == NUMB( 2)) THEN RETURN STRI("two"); EOL
PD COMM(/* rest of code goes here */) EOL
PD IF (n == NUMB( 9)) THEN RETURN STRI("nine"); EOL
PD IF (n == NUMB(10)) THEN RETURN STRI("ten"); EOL
PD ASSERT FALSE; EOL
END EOL
m4_end_indent
)
m5_question(BO(Question 5.4:) Add a new function STRING
FUNC(capitalise)(INT VARI(n)) that capitalises words and call this
function from the song function so that the first words in each
sentence are capitalised. You should find the function
CLSS(Character)TT(.toUpperCase) and the methods STRING(TT(.charAt))
and STRING(TT(.substring)) helpful for writing this function. See
m4_begin_center
TT(http://java.sun.com/j2se/1.5.0/docs/api)
m4_end_center
NU()for more details.)
m5_question(BO(Question 5.5:) Add new function call TT(STRING
FUNC(plural)(INT VARI(n))) that returns the string STRI(TT("s")) if
TT(n) is not equal to 1 and the empty string STRI(TT("")) otherwise.
Then call this function from the TT(song) function so that the phrase
STRI(TT("bottle")) is pluralised when it should be. )
m5_question(BO(Question 5.6:) Write a function called
TT(number2string2) that can handle values up to but not including 100.
Note that you will need multiple IF statements to achive this. Note
that if TT(n) is a number then the following expressions are useful:
m4_begin_itemize
m4_item TT(VAR INT VARI(temp1) = n / NUMB(10) PERCENT NUMB(10)) results in
TT(temp1) holding the tens digit of TT(n) and is zero in the case
that TT(LT(n,10)).
m4_item TT(VAR INT VARI(temp2) = n PERCENT NUMB(10)) results in TT(temp2) holding
the ones digit of TT(n).
m4_end_itemize
Also make it print out STRI(TT("one hundred or more")) in the case
that TT(GTEQ(n,100)) )
m5_question(BO(Question 5.7:) Change the song function so that the
following function call: TT(song(5,STRI("rum"));) in the MAIN function
results in the following printout:
m4_begin_indent
NU()Five bottles of rum on the wall. EOL
EOL
... EOL
EOL
there'd be no bottles of rum on the wall. EOL
m4_end_indent
)
m5_question(BO(Question 5.8:) Once all the code is working, add the
following line to the MAIN function: TT(song(100,STRI("gin"));) so
that it prints out the following:
m4_begin_indent
NU()One hundred bottles of gin on the wall. EOL
EOL
... EOL
EOL
there'd be zero bottles of gin on the wall. EOL
m4_end_indent
)
m5_question(BO(Question 5.9) Write a new function
TT(number2string3) that works like TT(number2string2) and
TT(number2string) execpt that it handles numbers up to 999.
Internally TT(number2string3) should call TT(number2string2). You
might find the following function useful:
m4_begin_indent
NU()FUNCTION STRING FUNC(textand)(STRING VARI(a), STRING VARI(b)) EOL
BEGIN EOL
PD IF (a.equals(STRI("")) OR b.equals(STRI(""))) THEN RETURN a + b; EOL
PD ELSE RETURN a + STRI(" and ") + b; EOL
END EOL
m4_end_indent
)
m5_question(BO(Question 5.10) HARDQ Write a new function
TT(number2string4) that works like TT(number2string3) execpt that it
handles numbers up to nine hundred and ninety-nine million nine
hundred and ninety-nine thousand nine hundred and ninety-nine,
i.e. 999,999,999. The function TT(number2string4) should internally
call TT(number2string3) like so:
m4_begin_itemize
m4_item TT(VAR STRING VARI(ones) = number2string3(n PERCENT NUMB(1000));)
m4_item TT(VAR STRING VARI(thousands) = number2string3(n / NUMB(1000) PERCENT NUMB(1000));)
m4_item TT(VAR STRING VARI(millions) = number2string3(n / NUMB(1000) / NUMB(1000) PERCENT NUMB(1000));)
m4_end_itemize
Note that the variables above will have values from 0 to 999
inclusive.)