Chapter 7 Exercises: Procedures and Functions

These exercises progress from straightforward application of individual concepts to multi-concept challenges requiring design decisions. Complete all Core exercises before attempting Challenge exercises. The Mastery exercises at the end integrate material from earlier chapters.


Part A: Warm-Up (Procedures Without Parameters)

Exercise 7.1 — PrintBanner Write a procedure called PrintBanner that prints a decorative banner:

****************************
*   Welcome to My Program  *
****************************

Call it from the main program at the beginning and end of execution.

Exercise 7.2 — PrintSeparator Write a procedure called PrintSeparator that prints a line of 40 dashes. Use it to visually separate sections of output in a program that prints your name, your major, and your favorite programming language, with separators between each.

Exercise 7.3 — PrintMenu Write a procedure called PrintMenu that displays:

=== Calculator Menu ===
1. Add
2. Subtract
3. Multiply
4. Divide
5. Quit
=======================

Write a main program that calls PrintMenu, reads the user's choice, and prints "You chose option X" (where X is their choice). Use a REPEAT...UNTIL loop to keep showing the menu until the user chooses 5.


Part B: Core (Parameters and Functions)

Exercise 7.4 — PrintStars Write a procedure PrintStars(Count: Integer) that prints Count asterisks on a single line followed by a newline. Then use it to print a right triangle:

*
**
***
****
*****

Hint: Call PrintStars inside a FOR loop.

Exercise 7.5 — PrintBox Write a procedure PrintBox(Width, Height: Integer) that prints a hollow rectangle of asterisks. For example, PrintBox(6, 4) should print:

******
*    *
*    *
******

Use const parameters since the procedure does not modify them.

Exercise 7.6 — Swap Write a procedure Swap(var A, B: Integer) that exchanges the values of two Integer variables. Demonstrate it in a main program by printing the values before and after the swap. Explain in a comment why var parameters are necessary here.

Exercise 7.7 — Min and Max Functions Write two functions: - MinOf3(A, B, C: Integer): Integer — returns the smallest of three integers - MaxOf3(A, B, C: Integer): Integer — returns the largest of three integers

Test them with both positive and negative numbers. What happens when two or all three values are equal?

Exercise 7.8 — IsEven and IsOdd Write a function IsEven(N: Integer): Boolean that returns True if N is even. Write a companion function IsOdd(N: Integer): Boolean that calls IsEven (do not duplicate the modulo logic). Print the numbers 1 through 20, marking each as "even" or "odd" using your functions.

Exercise 7.9 — Power Function Write a function IntPower(Base, Exponent: Integer): Int64 that computes Base raised to the power Exponent using a loop (do not use the built-in ** operator or any math library function). Assume Exponent >= 0. Test with: - IntPower(2, 10) should return 1024 - IntPower(5, 0) should return 1 - IntPower(3, 6) should return 729

Why is the return type Int64 instead of Integer? Add a comment explaining.

Exercise 7.10 — ReadValidInteger Write a procedure ReadValidInteger(const Prompt: string; var Value: Integer; Min, Max: Integer) that: 1. Displays the prompt 2. Reads an integer from the user 3. If the input is outside the range [Min..Max], displays an error and tries again 4. Repeats until a valid integer is entered

The valid integer is stored in Value (a var parameter). Test it by reading an age between 0 and 150, then reading a month between 1 and 12.


Part C: Challenge (Multi-Concept)

Exercise 7.11 — Temperature Converter Suite Write the following functions: - CelsiusToFahrenheit(C: Real): Real - FahrenheitToCelsius(F: Real): Real - CelsiusToKelvin(C: Real): Real - KelvinToCelsius(K: Real): Real

Then write FahrenheitToKelvin and KelvinToFahrenheit by composing the functions above (i.e., FahrenheitToKelvin should call FahrenheitToCelsius and then CelsiusToKelvin). Write a menu-driven main program that lets the user choose a conversion, enter a value, and see the result. Use a const parameter for the input temperature in each function.

Exercise 7.12 — Statistics Suite Write a program that reads up to 100 real numbers from the user (terminated when they enter 0), stores them in an array, and then computes and displays: - The count of numbers entered (function CountEntries) - The sum (function Sum) - The average (function Average — calls Sum and CountEntries) - The minimum (function Minimum) - The maximum (function Maximum) - The range (function Range — calls Minimum and Maximum)

Use const parameters for the array in all functions. The reading procedure should use var parameters for the array and count.

Exercise 7.13 — Password Validator Write a function IsStrongPassword(const Password: string): Boolean that returns True if the password meets ALL of these criteria: - At least 8 characters long - Contains at least one uppercase letter - Contains at least one lowercase letter - Contains at least one digit

Decompose this into helper functions: HasMinLength, HasUppercase, HasLowercase, HasDigit. Write a main program that reads passwords from the user and reports whether each is strong or weak, listing which criteria failed.

Exercise 7.14 — Digit Analysis Write the following functions for an Integer parameter N: - DigitCount(N: Integer): Integer — returns the number of digits - DigitSum(N: Integer): Integer — returns the sum of all digits - ReverseDigits(N: Integer): Integer — returns the number with digits reversed (e.g., 1234 becomes 4321) - IsPalindrome(N: Integer): Boolean — returns True if N equals its reverse

Handle negative numbers by working with the absolute value. Test with: 12345, 12321, 1000, 7, 0.

Exercise 7.15 — Procedure Tracing Without running the following program, trace its execution by hand and predict the exact output. Then compile and run it to check your prediction.

program TraceMe;

procedure Alpha(X: Integer; var Y: Integer);
begin
  X := X + 10;
  Y := Y + 10;
  WriteLn('Alpha: X=', X, ' Y=', Y);
end;

procedure Beta(var A: Integer; B: Integer);
begin
  A := A * 2;
  B := B * 2;
  WriteLn('Beta: A=', A, ' B=', B);
  Alpha(A, B);
  WriteLn('Beta after Alpha: A=', A, ' B=', B);
end;

var
  P, Q: Integer;
begin
  P := 5;
  Q := 3;
  WriteLn('Before: P=', P, ' Q=', Q);
  Alpha(P, Q);
  WriteLn('After Alpha: P=', P, ' Q=', Q);
  Beta(P, Q);
  WriteLn('After Beta: P=', P, ' Q=', Q);
end.

Write your predicted output before running the program. If your prediction was wrong, identify exactly which parameter mode caused the surprise.


Part D: Extension (Open-Ended)

Exercise 7.16 — Mini Calculator with History Design and implement a calculator program that: - Supports +, -, *, / operations on two real numbers - Keeps a history of the last 10 calculations - Has a "show history" option - Uses procedures for all operations, input, and display - Uses functions for the actual calculations - Validates input (no division by zero, valid numbers)

Focus on clean decomposition. Your main program body should be no more than 15 lines.

Exercise 7.17 — Text Analyzer Write a program that reads a line of text and reports: - Number of characters - Number of words (separated by spaces) - Number of sentences (ending with '.', '!', or '?') - Number of vowels - Number of consonants - Number of digits - Average word length

Each statistic should be computed by its own function. The main program should call each function and display the results in a formatted report. Use const for the text parameter in every function.

Exercise 7.18 — Procedural Refactoring Take the following monolithic program and refactor it into well-named procedures and functions. Do not change what the program does — only how it is organized. The refactored main body should be no more than 10 lines.

program MonolithicGrades;
var
  Name: string;
  Score1, Score2, Score3, Score4, Score5: Integer;
  Total, Average: Real;
  Grade: Char;
  I: Integer;
begin
  Write('Student name: ');
  ReadLn(Name);
  Write('Score 1: '); ReadLn(Score1);
  Write('Score 2: '); ReadLn(Score2);
  Write('Score 3: '); ReadLn(Score3);
  Write('Score 4: '); ReadLn(Score4);
  Write('Score 5: '); ReadLn(Score5);
  Total := Score1 + Score2 + Score3 + Score4 + Score5;
  Average := Total / 5;
  if Average >= 90 then Grade := 'A'
  else if Average >= 80 then Grade := 'B'
  else if Average >= 70 then Grade := 'C'
  else if Average >= 60 then Grade := 'D'
  else Grade := 'F';
  WriteLn;
  WriteLn('=============================');
  WriteLn('  Student Report Card');
  WriteLn('=============================');
  WriteLn('Name:    ', Name);
  WriteLn('Score 1: ', Score1:4);
  WriteLn('Score 2: ', Score2:4);
  WriteLn('Score 3: ', Score3:4);
  WriteLn('Score 4: ', Score4:4);
  WriteLn('Score 5: ', Score5:4);
  WriteLn('-----------------------------');
  WriteLn('Total:   ', Total:6:1);
  WriteLn('Average: ', Average:6:1);
  WriteLn('Grade:   ', Grade);
  WriteLn('=============================');
end.

Hint: You should end up with at least 4 procedures/functions. Consider using an array instead of five separate variables.


Part E: Design Exercises

Exercise 7.19 — Signature Design For each of the following tasks, write only the procedure or function heading (not the body). Choose appropriate parameter modes (var, const, or value) and return types. Justify each choice in a comment.

a) Read a student's name from the keyboard b) Calculate the area of a triangle given base and height c) Sort three integers into ascending order d) Check whether a string contains only alphabetic characters e) Convert a temperature from any scale to any other scale f) Read and validate a menu choice (must be between 1 and N)

Exercise 7.20 — Decomposition Plan You are asked to write a program that: - Reads a list of up to 50 student names and their test scores - Computes each student's letter grade - Finds the class average - Finds the highest and lowest scores - Prints a formatted grade report - Prints a class summary with statistics

Without writing any code, create a decomposition plan. List each procedure and function you would write, its parameters (with modes), its return type (if a function), and a one-sentence description of what it does. Organize them in the order they would appear in the source file.


Part M: Mastery (Spaced Review Integration)

These exercises deliberately integrate concepts from Chapters 3, 5, and 6 with the new material from Chapter 7.

Exercise 7.21 — Type-Safe Input Library Write a collection of input procedures that combine Chapter 3 types, Chapter 5 validation, Chapter 6 loops, and Chapter 7 procedures: - ReadInteger(const Prompt: string; var Value: Integer) — reads an integer, reprompts on invalid input - ReadReal(const Prompt: string; var Value: Real) — reads a real, reprompts on invalid input - ReadIntegerInRange(const Prompt: string; var Value: Integer; Min, Max: Integer) — as above, but with range checking - ReadYesNo(const Prompt: string): Boolean — returns True for 'Y'/'y', False for 'N'/'n', reprompts otherwise

Test all four in a small demonstration program.

Exercise 7.22 — CASE Inside Functions (Ch 5 Review) Write a function MonthName(Month: Integer): string that uses a CASE statement to return the name of the month (1 = 'January', etc.). Write a companion function DaysInMonth(Month: Integer; IsLeapYear: Boolean): Integer that returns the number of days. Write a main program that reads a month number and year, and prints: "March 2024 has 31 days."

Exercise 7.23 — Loop-Based Functions (Ch 6 Review) Write the following functions, each using a different loop type: - Factorial(N: Integer): Int64 — use a FOR loop - GCD(A, B: Integer): Integer — use a WHILE loop (Euclidean algorithm) - IsPrime(N: Integer): Boolean — use a FOR loop with early exit

Write a main program that demonstrates all three. For GCD, show that GCD(48, 18) = 6. For IsPrime, print all primes between 2 and 100.

Exercise 7.24 — FOR Loop Variable Types (Ch 3 Review) Write a procedure PrintCharRange(StartChar, EndChar: Char) that uses a FOR loop with a Char loop variable to print all characters from StartChar to EndChar. Demonstrate with: - PrintCharRange('A', 'Z') — prints the alphabet - PrintCharRange('0', '9') — prints the digits - PrintCharRange('a', 'f') — prints the first six lowercase letters

This exercise reviews Chapter 3's rule that FOR loop variables can be any ordinal type, not just Integer.

Exercise 7.25 — Comprehensive: Mini Gradebook Combine everything from Chapters 3–7 to build a mini gradebook program: - Store up to 30 students' names and scores (use parallel arrays) - Menu-driven interface (CASE statement from Chapter 5, REPEAT loop from Chapter 6) - Procedures: AddStudent, DisplayAllStudents, DisplayStatistics - Functions: CalculateAverage, FindHighest, FindLowest, DetermineGrade - Input validation on all numeric entries (range checking with loops) - Formatted output aligned in columns

This exercise is intentionally substantial. Plan your decomposition before writing code. Your main program body should be no more than 20 lines.


Submission Guidelines

For each exercise, submit: 1. The complete Pascal source file (.pas), compilable with fpc 2. A sample run showing representative input and output 3. For design exercises (7.19, 7.20): a written document with your analysis

Label files as exercise-07-XX.pas where XX is the exercise number.