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