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:


    PROGRAM Mortgage;

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

    BEGIN
       { Get the initial info }

       write('Capital        : ');
       readln(capital);
       write('Yearly rate    : ');
       readln(rate);
       write('Monthly payment: ');
       readln(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:

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 }

      read(value);

      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;

         read(value); { Next ! }
      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

         read(value);

         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:


   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: ');
  8.    readln(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: ');
 22.       readln(inp);

 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