1. (20 Points)
Write a program that computes the length of a mortgage (in number of months). The user will input the amount of the mortgage (called the capital), the annual percentage rate and the amount of the monthly payment. The program will compute the number of months plus the amount of the last payment.
```   Capital        : 75000
Yearly rate    : 8.5
Monthly payment: 650

240 payments of \$ 650.00 plus a final payment of \$ 546.54
```
NOTES:

• At each iteration the capital is increased by the monthly interest rate. If the resulting capital is more than the monthly payment, you subtract the payment and proceed to the next month, otherwise the remaining capital is the amount of the last payment.
• The number of iterations is not know at the start.
• Since we are dealing with dollar amounts, the monetary figures in the output should be formatted to show only 2 decimal places.

```    PROGRAM Mortgage;

VAR capital, rate, payment : real;
months                  : integer;

BEGIN
{ Get the initial info }

write('Capital        : ');
write('Yearly rate    : ');
write('Monthly payment: ');

{ Rate was entered in yearly amount }
{ We need the monthly percentage amount (plus 1 for the carry-over) }

rate := 1 + (rate / 1200);

{ First month increase }

capital := capital * rate;

{ Initialize months }

months := 0;

{ As long as the capital is greater than the payment, subtract the }
{ payment, increament months and compute next months capital }

WHILE( capital > payment ) DO
BEGIN
capital := capital - payment;
months := months + 1;
capital := capital * rate;
END;

writeln;
write(months, ' payments of \$ ', payment:0:2;
writeln(' plus a final payment of \$ ', capital:0:2');

END.
```

2. (20 Points)
Write a program that reads a series of integers terminated by a 0. The program should then print:

• The number of integers
• The average (with 1 decimal digit of precision)
• The maximum number
• The minimum number
Example:
```   Enter a series of integers terminated by a 0.
80 90 75 66 82 92 0

You have entered 6 values.
The average is: 80.8
The maximum is: 92
The minimum is: 66
```

Extra credit (5 points): instead of requiring a 0 to terminate the input, use the EOL to check for the end of the input.

```   PROGRAM Stats;

VAR total, entries, value, min, max : integer;

BEGIN

writeln('Enter a series of integers terminated by a 0');

{ Initializations }

total := 0;
entries := 0;
min := value;
max := value;

WHILE( value <> 0 ) DO
BEGIN
entries := entries + 1;
total := total + value;
IF( value < min ) THEN
min := value
ELSE
IF( value > max ) THEN max = value;

END; { While }

writeln;
writeln('You have entered ', entries, ' values.');
writeln('The average is: ', (total/entries):0:1);
writeln('The maximum is: ', max);
writeln('The minimum is: ', min);
END.

{ Alternative version using EOLN }

PROGRAM Stats;

VAR total, entries, value, min, max : integer;

BEGIN

writeln('Enter a series of integers.');

{ Initializations }

total := 0;
entries := 0;

WHILE( NOT EOLN ) DO
BEGIN

entries := entries + 1;
total := total + value;
{ If this is first entry, initialize min and max, else set }
{ min and max }

IF( entries = 1 ) THEN
BEGIN
min := value;
max := value;
END
ELSE
IF( value < min ) THEN
min := value
ELSE
IF( value > max ) THEN max = value;

END; { While }

writeln;
writeln('You have entered ', entries, ' values.');
writeln('The average is: ', (total/entries):0:1);
writeln('The maximum is: ', max);
writeln('The minimum is: ', min);
END.
```

3. (20 Points)
Write a procedure that computes simple arithmetic operations. The procedure should accept two real operands and a character that represents the operator (+, -, *, /). The procedure should return the result as a real and a boolean error flag that is set to TRUE if the operation is invalid.

Hints:

• Which should be value parameters and which should be variable parameters ?
• The program has to decide between 4 valid operators plus possible invalid characters. Which is the best branching statement ?

```   PROCEDURE Arithmetic( lhs, rhs : real; oper : char;
VAR result : real; VAR error : boolean);

{ lhs, rhs : left-hand and right-hand side operands }
{ oper     : aritmetic operand (+,-,*,/) }
{ error    : set to TRUE if operand is invalid }

BEGIN

{ Assume no error at start }

error := FALSE;
result := 0;    { Better safe than sorry }

CASE oper OF
'+' : result := lhs + rhs;
'-' : result := lhs - rhs;
'*' : result := lhs * rhs;
'/' : IF (rhs <> 0) THEN     { Don't allow division by zero }
result := lhs / rhs
ELSE
error := TRUE;

ELSE { None of the above cases }
error := TRUE;

END; { CASE }

END;
```

4. (20 Points)
The following code contains at least 5 errors (syntax and/or logic). Identify line number and error.

```  1. PROGRAM Flawed;

2. PROCEDURE DoAdd(VAR errorCode : integer);
3. PROCEDURE DoSubtract(VAR errorCode : integer; amount : real);

4. PROCEDURE DoCommand(command : char, errorCode : integer);

5. VAR amount : real;

6. BEGIN

7.    write('Amount: ');

9.    CASE command OF
10.      'A', 'a' : DoAdd(amount, errorCode);
11.      'S', 's' : DoSubtract(amount, errorCode);
12.    ELSE
13.       errorCode := 1;
14.    END;

15. END; { DoCommand }

16. VAR inp  : char;
17.    error : integer;

18. BEGIN

19.    WHILE (error = 0) DO
20.    BEGIN
21.       write('Command: ');

23.       IF (NOT inp IN ['E', 'e']) DO
24.       BEGIN
25.          DoCommand(inp, error);
26.          IF (error <> 0) THEN
27.             writeln('Error ', error);
28.       END;

29.       IF (inp = 'E') AND (inp ='e') THEN
30.          error = -1;
31.    END;
32. END.
```

 1 Line: 4 Error: there should be a semicolon (";"), not a comma (","), between the type char and the next variable. 2 Line: 4 Error: errorCode should be a VAR parameter, otherwise the caller will never know if it was set. 3 Line: 10 Error: DoAdd expects 1 parameter 4 Line: 11 Error: DoSubtract expects and integer followed by a real 5 Line: 19 Error: error was never initialized. 6 Line: 23 Error: (NOT inp IN ['E', 'e']) is illegal, should be NOT (inp IN ['E', 'e']) 7 Line: 23 Error: DO is for WHILE loops, IF should be followed by THEN. 8 Line: 29 Error: inp could never be both 'E' and 'e'. 9 Line: 30 Error: The assignment operator is :=, the semicolon is missing.

5. (20 Points)
Evaluate the following:

 a) (TRUE OR NOT FALSE) AND (NOT TRUE OR TRUE) : TRUE b) NOT((379 MOD 9) IN [0,2,4,6-8]) : TRUE c) (ord('A') > 0) AND (ord('A') < 256) : TRUE d) TRUE AND NOT FALSE AND FALSE OR FALSE OR TRUE : TRUE e) (9 <= 2) OR (3 > 5) OR (3 = 3) AND (9 >= 2) : TRUE