Write a program module that takes an input line of text and computes and prints the average number of consonants per syllable and the average number of syllables per word. Count every occurrence of one or more consecutive vowels as one syllable. (Note that this was posed as a problem in the exercise set of chapter 5, but could not be done there using sets.)
This can be viewed as an elaboration of the vowel counter problem in section 9.1. Provided that an appropriate rule for counting syllables is used, text of any size and from any source can be automatically examined.
Given
a line of text
To Compute
the number of consonants
the number of syllables
the number of words
Output Desired
the number of consonants per syllable
the number of syllables per word
Print an informative header.
Initialize counting variables to track consonants, syllables, and words.
Ask for a line of text to analyze.
Input the text line.
Examine each character:
check for end of string
if so, add one to word count and we're done
check for blank
if so, and previous one not a blank, add one to word count
check for consonant
if so, add one to consonant count
check for vowel
if so, and previous one not a vowel, add one to syllable count
otherwise, go on to next character
Compute consonants per syllable and output it.
Compute syllables per word and output that, too.
To hold input characters - next, last : CHAR
As counters - cons, syll, word : CARDINAL
For output - consPerSyll, syllPerWord
Sets - Letters, Vowels, Consonants
Imports Needed: WriteString, WriteLn, SkipLine, WriteReal
NOTE: As in most extended examples by this point in the book, the user documentation has been omitted in order to save space. This cannot be done in student programs or in commercial ones.
MODULE TextLineStats;
(* Written by R.J. Sutcliffe *)
(* using ISO Modula-2 *)
(* last revision 1994 03 02 *)
FROM SRealIO IMPORT
WriteReal;
FROM SWholeIO IMPORT
WriteCard;
FROM STextIO IMPORT
ReadString, WriteString, WriteLn, SkipLine;
TYPE
CharSet = SET OF CHAR;
String = ARRAY [0 .. 255] OF CHAR;
CONST
blank = " ";
VAR
next, last : CHAR;
replyStr, theString : String;
count, numChars, numOfCons, numOfSyll, numOfWords : CARDINAL;
consPerSyll, syllPerWord : REAL;
yesChars, Letters, Vowels, Consonants : CharSet;
again : BOOLEAN;
BEGIN
(* First print out header information. *)
WriteString ("This program analyzes a line of text for");
WriteString (" statistical information.");
WriteLn;
(* Next initialize the sets and other variables *)
yesChars := CharSet {"Y", "y"};
Letters := CharSet {'A' .. 'Z', 'a' .. 'z'};
Vowels := CharSet
{'A', 'E', 'I', 'O', 'U', 'Y', 'a', 'e', 'i', 'o', 'u', 'y'};
Consonants := Letters - Vowels;
REPEAT
(* Now tell user to type the input. *)
REPEAT
WriteString ("Please provide line of text for analysis. ");
WriteLn;
ReadString (theString);
SkipLine; (* gobble end of line state *)
numChars := LENGTH (theString);
IF numChars = 0
THEN
WriteString ("Type a proper string. Try again.");
WriteLn;
END;
UNTIL numChars > 0;
(* initialize totals here, so can re-use *)
numOfCons := 0;
last := blank; (* ensure OK vowel count. *)
numOfSyll := 0;
numOfWords := 0;
count := 0;
REPEAT (* loop back to here if not at end of text *)
next := theString [count];
IF (next = blank) AND (last # blank)
(* check for word end *)
THEN
INC (numOfWords)
ELSIF (next IN Consonants) THEN(* check for consonants *)
INC (numOfCons)
ELSIF (next IN Vowels) AND NOT (last IN Vowels) THEN
(* check for vowel *) (* no syll if 2 vowels *)
INC (numOfSyll)
END; (* otherwise must be special char *)
last := next; (* reset last for next time around *)
INC (count);
UNTIL count > numChars; (* actual check for end is here *)
(* Now do processing for output *)
INC (numOfWords); (* count last word; not followed by blank *)
IF numOfSyll > 0
THEN
consPerSyll := FLOAT (numOfCons)/FLOAT (numOfSyll);
END;
syllPerWord := FLOAT (numOfSyll)/FLOAT (numOfWords);
WriteLn;
WriteString ("Number of consonants: ");
WriteCard (numOfCons, 6);
WriteLn;
WriteString ("Number of syllables: ");
WriteCard (numOfSyll, 6);
WriteLn;
WriteString ("Number of words: ");
WriteCard (numOfWords, 6);
WriteLn;
WriteString ("Number of consonants per syllable: ");
IF numOfSyll > 0
THEN
WriteReal (consPerSyll, 6);
ELSE
WriteString ("undefined.");
END;
WriteLn;
WriteString ("Average number of syllables per word: ");
WriteReal (syllPerWord, 6);
WriteLn;
(* get ready to loop around again or quit *)
WriteString ("Do you wish to do another? (Y/N) ==> ");
ReadString (replyStr);
SkipLine;
again := replyStr [0] IN yesChars; (* reply starts with 'y' *)
UNTIL NOT again;
END TextLineStats.
This program analyzes a line of text for statistical information. Please provide line of text for analysis. Now is the time for all good parties to come to the aid of women. Number of consonants: 28 Number of syllables: 19 Number of words: 15 Number of consonants per syllable: 1.4737 Average number of syllables per word: 1.2667 Do you wish to do another? (Y/N) ==> n