|
~ Introduction to Programming: Pascal ~ Session 13 - Sample Exam and more on Procedures |
During this session, we will work through an example of a practical assignment similar to one that you may get in your final examination for the Pascal section of this course.
At the end, you will be given another task to work through during this Christmas break, so that we can go through it as an example in the first session in the new year.
9531
INTRODUCTORY COMPUTER PROGRAMMING STRUCTURED ASSIGNMENT
Topic: Games and Quizzes
Title of this Assignment: Random Phrase generator
Introduction
The purpose of this assignment is to write a program to generate random phrases from a set of pre-defined phrase parts, and select your favourites.
Write a program, which contains, in three separate arrays, data relating to each of the three phrase types.
One phrase part is then selected randomly from each of these arrays, and put together to form a sentence.
The program should then display the sentence, and prompt the user to ask if they wish to add the phrase to their favourites list. If the user confirms this, then the phrase should be added to a 'favourites' array.
A further prompt should then be displayed asking whether the user wishes to get another phrase.
If the user does wish to get another phrase, another phrase will be generated etc. until the user specifies that he or she does not wish to get another phrase.
At this point, the screen will be cleared, and a heading is displayed, followed by a list of favourites that the user chose, taken from the 'favourites' array.
The user is then invited to press any key to finish the program.
The
list of phrase parts can be divided into three types, and each type has a list
of possible parts, which should contain at least the following data:-
PTO >>
|
First
Part (Subject) |
Second
Part (Verb) |
Third
Part (Object) |
|
I am You are We are They are Who is Am I Are You |
riding eating punching shaving juggling poking painting |
nice thoughts small fluffy lambs pink elephants sick animals motorbikes toadstools Mr. Blobby |
Create these lists as three data files, and list different data items on separate lines within each data file.
Read the three data files into the three arrays that hold the phrase parts within your program. You will need to do this at the start of your program.
a) Describe briefly in writing for a possible user
i) The purpose of your program
ii) The limitations of your program
b) Construct (on paper) a screen layout indicating what will appear on the screen prompts, input, output with annotations, any other messages.
c) Describe (on paper) the main stages of the program - by means of a flowchart or an alternative technique.
d) Produce a listing of the program. This should have adequate comment lines and should demonstrate to the examiner that the program solves the problem set.
e) Include in the program statements to display adequate instruction to the user of the program e.g. prompts for data entry and appropriate error messages for invalid input.
f) Key in and run the program, producing and using simple test data if necessary. Check that the program's output agrees with the expected results and correct any errors.
g) Use appropriate language facilities.
9531
INTRODUCTORY COMPUTER PROGRAMMING STRUCTURED ASSIGNMENT
Topic: Games and Quizzes
Title of this Assignment: Random Phrase generator
Student Name: Simon Huggins
The purpose of this program is to randomly generate various (potentially amusing) sentences composed of three lists of phrase parts.
The program gives you the option of adding any of these phrases to a list, and display them at the end of the program to note down your favourites.
The phrases are held in external files, which can be edited if you wish to add your own phrase parts.
The program is limited by the phrases stored in the three data files, from which it reads its phrase parts. It is also limited to sentences which fit the basic structure of three sections to each sentence a subject, a verb, and an object.
The "favourite phrases" list can only be read on-screen, and not saved, nor printed. The list cannot be viewed, nor items deleted from the list whilst generating phrases.
The program cannot update the phrases the user needs to use an external text editor in order to change the data in the phrase files.
Questions are not suffixed with question marks.
The maximum number of phrase parts is limited by the size of the arrays in the Pascal program.
The pseudo-random number generator algorithm that Pascal provides restricts the randomness of the program.
No checks are made to see if the arrays have filled up to maximum capacity, which could cause a run-time error.
b) Screen Layout Design
When the program is first started, the screen is cleared, and the following displayed:-
Random Phrase Generator Program
-------------------------------
<phrase part 1> <phrase part 2> <phrase part 3>.
Do you wish to store this phrase to your favourites (y/n)? <reply>
Where <phrase part 1/2/3> are the random phrase parts generated by the program from the three arrays e.g. <I am> <juggling> <motorbikes>.
If the <reply> single-key input is y then the phrase will be added to this list, and the following confirmation message displayed:-
The phrase has been added to your favourites list.
Otherwise (i.e any letter other than y pressed), the following message is displayed:-
The phrase has been discarded.
In order to confirm whether the user wants to leave the program, the following prompt is displayed:-
Press A for another phrase, press F to see your favourites and finish.
This is a prompt for an input, which must be either A or F.
If something other than A or F is chosen, the following message is displayed:-
You must press either A or F.
And the computer will again wait for one of the two letters to be pressed.
If A is pressed, then another phrase is generated and displayed etc. Otherwise, the screen is cleared and the following title / list of favourites displayed:-
Your Favourite Phrases
----------------------
They are shaving small fluffy lambs
I am punching Mr. Blobby
Who is poking sick animals
Press any key to finish the program.
When a key is pressed, the program terminates.
c) Design: Main stages of the program
(Using Jackson Structured Programming diagrams) note: could be handwritten.

![]() |
d) Listing of Program
program
RandomPhrases;
uses
WinCrt;
{ Set up possibly changing values as constants }
const MaxPhrases = 20;
MaxFavourites = 20;
PhraseFileName1 = 'c:\temp\phrases1.txt';
PhraseFileName2 = 'c:\temp\phrases2.txt';
PhraseFileName3 = 'c:\temp\phrases3.txt';
{ Set up variables }
var Phrases1,Phrases2,Phrases3:Array[1..MaxPhrases] of String;
Favourites:Array[1..MaxFavourites] of String;
PhraseCount1,PhraseCount2,PhraseCount3,FavouritesCount:integer;
{ Set up procedures }
{ Display title at start of program }
procedure DisplayTitle;
begin
ClrScr;
WriteLn('Random Phrase Generator Program');
WriteLn('-------------------------------');
end;
{ Read phrases from a filename into given array, returning count }
function ReadPhrases(filename:String; arr:integer):integer;
var fp:Text;
i:integer;
begin
Assign(fp,filename); Reset(fp);
i:=0;
while not eof(fp) do
begin
i:=i+1;
if arr = 1 then ReadLn(fp,Phrases1[i])
else if arr = 2 then ReadLn(fp,Phrases2[i])
else ReadLn(fp,Phrases3[i]);
end;
Close(fp);
ReadPhrases:=i;
end;
{ Main part of program for generating phrases }
function MainLoop:char;
var ch:char;
str:String;
r:integer;
begin
{ Generate and display random phrase from three arrays }
r:=random(PhraseCount1)+1;
str:=Phrases1[r]+' ';
r:=random(PhraseCount2)+1;
str:=str+Phrases2[r]+' ';
r:=random(PhraseCount3)+1;
str:=str+Phrases3[r]+'.';
WriteLn; WriteLn(str); WriteLn;
{ Add to favourites list }
WriteLn('Do you wish to store this phrase to your favourites list (y/n)?
');
ch:=UpCase(readKey);
if ch = 'Y' then
begin
FavouritesCount:=FavouritesCount+1;
Favourites[FavouritesCount]:=str;
WriteLn('The phrase has been added to your favourites list.');
end
else
WriteLn('The phrase has been discarded.');
WriteLn;
{ Wait until either A or F is pressed }
WriteLn('Press A for another phrase, press F to see your favourites and
finish.');
repeat
ch:=UpCase(readKey);
if (ch<>'A') and (ch<>'F') then writeLn('You must press
either A or F.');
until (ch='A') or (ch='F');
{ Return the character that was pressed - either A or F }
MainLoop:=ch;
end;
{ Display list of favourites }
procedure DisplayFavourites;
var i:integer;
begin
ClrScr;
WriteLn('Your Favourite Phrases');
WriteLn('----------------------'); WriteLn;
for i:=1 to FavouritesCount do
WriteLn(Favourites[i]);
WriteLn; WriteLn('Press any key to finish the program.');
readKey;
end;
begin
{main part of program }
DisplayTitle;
Randomize; FavouritesCount:=0;
PhraseCount1:=ReadPhrases(PhraseFileName1,1);
PhraseCount2:=ReadPhrases(PhraseFileName2,2);
PhraseCount3:=ReadPhrases(PhraseFileName3,3);
repeat { do nothing other than MainLoop } until MainLoop='F';
DisplayFavourites;
end.
f) Test Results
|
Function |
Expected
Results |
Actual
Results |
|
Does title display correctly? |
Display Random Phrase Gen Program underlined |
As expected. |
|
Check randomness |
First second and third parts are different each
time |
Samples:- Ψ
[Who
is] [riding] [small fluffy lambs]. Ψ
[They
are] [painting] [toadstools] Ψ
[Are
you] [painting] [toadstools] |
|
Check range of values for first part |
One run must produce I am (first), another
Are you (last) |
Results: [Who is] [They are] [Are you] [We are] [Am
I] [You are] [I am] |
|
Check range of values for second part |
One run must produce riding (first), another
painting (last) |
Results: [juggling] [eating] [riding] [eating]
[punching] [shaving] [painting] |
|
Check range of values for third part |
One run must produce nice thoughts (first),
another Mr. Blobby (last) |
Results: [Mr. Blobby] [motorbikes] [nice thoughts]
[nice thoughts] |
|
Check N works by running program, pressing N, then
choosing F for list |
Phrase has been discarded then |
Phrase has been discarded then |
|
See if non-Y works by pressing X instead of N, then
choosing F for list |
Phrase has been discarded then |
Phrase has been discarded then |
|
See if Y works by running program, pressing Y, then
choosing F for list |
Phrase added then list with one phrase in it |
Phrase added list has title, with We
are painting sick animals on one line. |
|
See if can add multiple rows to favourites
press Y then A four times, then F for list. |
Phrase added x4, then list with four phrases
on 4 lines. |
Phrase addedx4 then list title, then
following:- We are shaving Mr. Blobby, Am I Painting
Mr. Blobby, Who is painting toadstools. And I am painting
toadstools. |
|
Does pressing a key finish the program? |
Try letters A, Z, and number 2, and symbol # |
In every instance, window becomes inactive,
indicating program finished |
|
If press F to see favourites and finish, does this
stop the loop and display favourites |
Try with no favourites, and 4 favourites added |
In both instances, shows the title and a list (in
second case) |
|
If press A does another phrase get displayed? |
Try with not adding favourite and also if adding
favourite |
We are eating sick animals then N then A,
then We are poking nice thoughts so this works. Press Y then A, then
You are riding small fluffy lambs so OK. |
Christmas Assignment
See how you do with the following over Christmas well go through a worked
example in the new year:-
9531
INTRODUCTORY COMPUTER PROGRAMMING STRUCTURED ASSIGNMENT
Topic:
Games and
Quizzes
Title of
this Assignment:
Higher or Lower game
Introduction
The
purpose of this assignment is to write a program to generate a number from 1 to
10, then prompt the user to guess whether the next generated number will be
higher or lower, keeping a score which is increased by 1 for a correct guess. A
high score is kept with a name.
Write
a program, which generates a random number between 1 and 10, and prompts the
user to press H for higher or L for lower or X for Exit.
If
the next number generated by the computer is as the user guessed, then increase
a score variable by one. If the guess is wrong, end the game.
Maintain a high score variable (initially set to 0) which, if the score after the game is higher than the current high-score value, is set to the new value, displaying a congratulatory message to the user on the screen, and prompting for the users name.
Thereafter,
at the end of each game, a message is displayed stating what the score for the
last game was, what the high score is, and what the name of the high-score
holder is.
At
this point, ask the user if he or she wishes to play again. If Y is pressed, go
back to the beginning, resetting the score, but maintaining the high score and
high score holder name variables. If N is pressed, show a goodbye message, ask
the user to press a key, wait until a key is pressed, and then exit the program
h)
Describe
briefly in writing for a possible user
i)
The purpose of your program
ii)
The limitations of your program
i)
Construct
(on paper) a screen layout indicating what will appear on the screen
prompts, input, output with annotations, any other messages.
j)
Describe
(on paper) the main stages of the program - by means of a flowchart or an
alternative technique.
k)
Produce a
listing of the program. This should
have adequate comment lines and should demonstrate to the examiner that the
program solves the problem set.
l)
Include
in the program statements to display adequate instruction to the user of the
program e.g. prompts for data entry and appropriate error messages for
invalid input.
m)
Key in
and run the program, producing and using simple test data if necessary. Check
that the program's output agrees with the expected results and correct any
errors.
n) Use appropriate language facilities.
To clarify some of the possibilities for creating procedures and functions, take a look through this selection:-
This procedure can be used to display text on the screen and then a number of hyphens on the next line underneath the number of the hyphens should match the number of characters in the text, so that it gives the appearance of being underlined.
In this example, the value passed into the procedure is copied into and represented by the variable str:-
procedure WriteUnderline( str : String
);
var
i:integer;
begin
WriteLn(str);
for
i := 1 to Length(str) do
Write('-');
WriteLn;
end;
Here are a few examples of how to use the procedure:-
WriteUnderline('Main Menu');
produces the following output:-
Main
Menu
---------
also:-
WriteUnderline('List of useful
things');
WriteLn('1. Safety pin'); WriteLn('2. Paper Clip');
produces the following output:-
List
of useful things
---------------------
1.
Safety
pin
2.
Paper
Clip
Exercise
Add a parameter to the procedure so that you can choose which character to use for the underline. For example, to Underline the text "Main Menu" with tildes, the procedure call would read as follows:-
WriteUnderline('Main Menu','~');
This procedure will take each character in a string variable (which can be treated like an array of characters) and convert them to upper case. This means that the variable passed to the procedure will be changed and converted to upper case, represented within the procedure by the name str.
Note
that using a variable parameter means that a variable must
be passed to the procedure, as the procedure is expecting to be able to change
the contents of the variable. It would be nonsensical to change a constant
string!
procedure UpperStr( var str : String );
var
i:integer;
begin
for
i := 1 to Length(str) do str[i]:=UpCase(str[i]);
end;
Here is an example of how to use the procedure:-
program UpperEg;
uses Crt;
procedure UpperStr( var str : String );
var
i:integer;
begin
for
i := 1 to Length(str) do str[i]:=UpCase(str[i]);
end;
var
myStr:String;
begin
ClrScr;
Write('Enter
Text: '); readLn(myStr);
WriteLn('Before:
', myStr);
UpperStr(myStr);
WriteLn('After
: ',myStr);
Write('Press
a key to finish '); readKey;
end.
And here's some sample output from the program:-
Enter
Text: Hello There!
Before:
Hello There!
After
: HELLO THERE!
and another example:-
Enter
Text: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@!#123456.7890,
Before:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@!#123456.7890,
After
: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ@!#123456.7890,
Thus you can see that when making any character other than a lower case letter upper case, it remains the same.
Exercise
Change
the procedure to work as a function, and return the upper case string instead of
changing an input variable.
Remember
that a function is just another type of procedure, which returns back a value
which you could then assign to a variable, or use in an expression.
In
this example, the function will wait for a key to be pressed, and check to see
if that key is an a list of characters passed to the function, represented by a
string. If a valid key is pressed, then it will be returned from the function,
otherwise the function will continue waiting until a valid key HAS been
pressed.
function CheckKey( keys : String ) :
char;
var
ch:Char;
p:integer;
begin
UpperStr(keys);
repeat
ch:=UCase(readKey);
p:=Pos(ch,keys);
until
p > -1;
CheckKey:=ch;
end;
Here's
how it works. The string of valid characters is passed into the function and is
copied into a new local variable called keys.
The key characters are converted to upper case, so bother upper
and lower case versions of the character are detected (in case the user
has left CAPS LOCK on). Note that this uses a procedure we previously created
called UpperStr.
A
character is read from the keyboard using readKey
and converted to upper case using UCase
and then stored in the ch variable.
A
standard function called Pos is then
used. This looks through the string keys
(containing the list of valid keys e.g. "SKP" if the letters S, K
and P are valid options) and checks whether the string contains the contents of ch
(e.g. 'L' if the user pressed K on the keyboard).
The position of ch within str is returned and placed in the variable p. Thus if K was pressed, then K is the second character within str,
so the value 2 would be stored in variable p.
If the value cannot be found in the keys
string (e.g. X was pressed), then a value of 1 is returned.
Thus,
the loop exit condition is that p must be some value greater than 1 for a
valid value to have been entered.
Finally, to specify which character to return from the function (which must be a char hence the : char at the end of the top line of the function), we assign the return value ie. The key that was pressed to the name of the function, as though it were a variable .
Here is an example of how to use the function:-
{main part of loop here}
Write('Do you wish to do another ([Y]es or [N]o?)');
Until CheckKey('YN')='N'
And another example, choosing from stone, knife, or paper (assuming a variable called ch of type char has been defined at the top of your program):-
Write('Choose
from [S]tone, [K]nife or [P]aper: ');
ch:=CheckKey('SKP');
WriteLn(ch); WriteLn('You chose ');
if ch='S' then WriteLn('Stone')
else if
ch='K' then WriteLn('Knife') else
WriteLn('Paper');
Exercise
Add a parameter that passes a prompt string to be shown before waiting for input (e.g. "Press [Y]es or [N]o"). This prompt will show again if the input was invalid (i.e. wrong). Test your function using one of the above snippets of code in a program.
This
function will take a string as its first input parameter, and the number of times that
string is to be repeated as its second. You can see that if you are passing more
than one parameter, you should separate each parameter with a semi-colon (;).
The function will return another string that contains the original
string repeated that number of times:-
function RepeatString( str : String;
count:integer ) : String;
var
resultStr:String;
i:integer;
begin
resultStr:='';
for
i := 1 to count do
resultStr:=resultStr+str;
RepeatString:=resultStr;
end;
Here is another way of implementing the WriteUnderLine procedure making use of our new RepeatString function:-
procedure WriteUnderline( str : String
);
begin
WriteLn(str);
RepeatString('-',Length(str)); WriteLn;
end;
And here's a way of drawing a fancy underline:-
RepeatString('-=',39);
Write('-');
This would display as follows:-
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Very pretty!
Exercise
Create a procedure called RepeatStrMax that repeats a string so that it doesn't exceed a maximum length of characters.
For example, running the following:-
WriteLn(RepeatStrMax('-=',79),'-');
would ensure that "-=" was written out 39 times, giving a total length of 78 characters, just below the limit of 79 characters passed to the procedure. This ensures that the pattern doesn't go beyond the width of the screen (80 characters) minus one character for the last "-" character (to make the pattern symmetrical-looking).
Nb. you may like to use a while loop to ensure that the string does not go beyond the maximum length.
Also note - there is more than one valid way of achieving this task!