12/22/00 down to 12/04/00

Due 12/22 Friday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
0. Period 2: check yesterday's programming assignment to determine if you (and Tayeb) carried
    out the specified assignment
1. Get revised versions of  fish.cpp and nbrhood.cpp if you can't compile and link successfully.
2. If you're getting linking errors involving apstring objects, go to AP classes page and download valid
    versions of apstring.h and apstring.cpp
3. ADT programming question: This is one of the best AP computer science programming
    questions you will find.
Make your solution COLLECTIBLE.
     a. Print 1993 A Exam Question 3
     b. Use browser to copy 93a3.cpp to your editor and implement your solutions to 1993 A Exam Question 3.

// FILE: 93a3.cpp
// PURPOSE: 1993 AP A Exam Question #3
//---------------------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ and gxx 
// 1. FILES: No special files needed. Using C++ string instead of apstring
// 2. COMMAND LINE: g++ (or gxx) -Wall 93a3.cpp
//---------------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Print Exam A Question 3 and implement solutions to its questions
//    in the functions started below
//---------------------------------------------------------------------
#include <iostream.h>
#include <iomanip.h>
#include <string>   //*** NOT <string.h> !!!!
#include <stdlib.h>
class stringType {
  friend void removeHead(stringType &);
  friend void appendChar(stringType &, char);
  friend ostream &operator << (ostream &, stringType &);
  friend void driverA(void);
  friend void driverB(void);
  friend void driverC(void);
public:
  stringType(string st2 = ""): st(st2) {}
  char head(void) { assert(st.length() > 0); return st[0]; }
  bool isEmptyString(void) { return (st.length() == 0); }
private:
  string st;
}; //stringType
void removeHead(stringType &S);
void appendChar(stringType &S, char x);
void appendChar(stringType &S, char x);
ostream &operator << (ostream &ostr, stringType &S);
bool isVowel(char ch);

void moveFirstToLast(stringType &S) {
  //***********************************
  //             part a               *
  //***********************************
}//*** moveFirstToLast
void removeLeadingVowels(stringType &S) {
  //***********************************
  //             part b               *
  //***********************************
}//*** removeLeadingVowels
void removeAllVowels(stringType &S) {
  //***********************************
  //             part c               *
  //***********************************
}//*** removeAllVowels
void driverA(void);
void driverB(void);
void driverC(void);
void main(void) {
  cout << "\n\n\n\n\n\t" << string(60, '*') << endl << endl;
  cout << "\t\t\t1993 Exam A: Question 3\n\n";
  driverA();
  driverB();
  driverC();
  cout << endl << "Press <ENTER> to quit: ";
  cin.get();
}
void driverA(void) {
  cout << "S before call to moveFirstToLast(S)"
       << "\t\tS after the call\n";
  stringType s("Eat");  cout << "\t\t" << s;
  moveFirstToLast(s);  cout << "\t\t\t\t\t" << s << endl;
  s.st = "range";  cout << "\t\t" << s;
  moveFirstToLast(s);  cout << "\t\t\t\t\t" << s << endl;
  s.st = "a";  cout << "\t\t" << s;
  moveFirstToLast(s);  cout << "\t\t\t\t\t" << s << endl;
  s.st = "abcd";  cout << "\t\t" << s;
  moveFirstToLast(s);  cout << "\t\t\t\t\t" << s << endl;
}//*** driverA
void driverB(void) {
  cout << "\nS before call to removeLeadingVowels(S)"
       << "\t\tS after the call\n";
  stringType s("Eat");  cout << "\t\t" << s;
  removeLeadingVowels(s);  cout << "\t\t\t\t\t" << s << endl;
  s.st = "range";  cout << "\t\t" << s;
  removeLeadingVowels(s);  cout << "\t\t\t\t\t" << s << endl;
  s.st = "a";  cout << "\t\t" << s;
  removeLeadingVowels(s);  cout << "\t\t\t\t\t" << s << endl;
  s.st = "abcd";  cout << "\t\t" << s;
  removeLeadingVowels(s);  cout << "\t\t\t\t\t" << s << endl;
}//*** driverB
void driverC(void) {
  cout << "\nS before call to removeAllVowels(S)"
       << "\t\tS after the call\n";
  stringType s("Eat");  cout << "\t\t" << s;
  removeAllVowels(s);  cout << "\t\t\t\t\t" << s << endl;
  s.st = "range";  cout << "\t\t" << s;
  removeAllVowels(s);  cout << "\t\t\t\t\t" << s << endl;
  s.st = "a";  cout << "\t\t" << s;
  removeAllVowels(s);  cout << "\t\t\t\t\t" << s << endl;
  s.st = "abcd";  cout << "\t\t" << s;
  removeAllVowels(s);  cout << "\t\t\t\t\t" << s << endl;
}//*** driverC
void removeHead(stringType &S) {
  if ( S.isEmptyString() ) return;
  string newSt = "";
  for (int k = 1; k < S.st.length(); k++)
    newSt += S.st[k];
  S.st = newSt;
}//*** removeHead
void appendChar(stringType &S, char x) {
  S.st += x;
}//*** appendChar
ostream &operator << (ostream &ostr, stringType &S) {
  return ostr << S.st;
}//*** operator <<
bool isVowel(char ch) {
  switch( ch | 32) {
  case 'a': case 'e':
  case 'i': case 'o':
  case 'u': return true;
  default: return false;
  }//** switch
}//*** isVowel

Due 12/21 Thursday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. Use browser to copy the solution to PH.cpp given below to your editor and replace current version
    of getLargest(). The given solution uses parallel vectors to solve the problem.
     a. Define a class that has public data members of the long and the Position type.
     b. Use that class to define an apvector which can replace the 2 apvectors in the given solution.
     c. Revise the solution using a single vector of the newly-defined class (which consists solely of
         of 2 public data members) in place of the vector of long and the vector of Position.
     d. NOTE: You don't need to know anything about the Position and Neighborhood classes
         to carry out this assignment.

Neighborhood getLargest(const apmatrix<long> &m) {
  // precond: m has at least 4 elements, all elements > 0
  //postcond: returns neighborhood object which contains
  //          positions of 4 largest elements in m
  Neighborhood temp;
  const int COLS = m.numcols(), ROWS = m.numrows(), vSIZE = ROWS*COLS;
  apvector<long> v(vSIZE);
  apvector<Position> v2(vSIZE);
  // 1. Write m's values and corresponding indices to parallel vectors
  for (int r = 0; r < ROWS; r++)
    for (int c = 0; c < COLS; c++) {
      v[r*COLS + c] = m[r][c];
      v2[r*COLS + c] = Position(r, c);
    }
  // 2. Selection sort: while v is sorted, v2 is changed in parallel
  for (int current = 0; current < vSIZE - 1; current++) {
    int minPos = current;
    for (int pos = current+1; pos < vSIZE; pos++) {
      if ( v[pos] < v[minPos] )
	minPos = pos;
    }//**for pos
    long hold = v[minPos]; Position hold2 = v2[minPos];
    v[minPos] = v[current]; v2[minPos] = v2[current];
    v[current] = hold; v2[current] = hold2;
  }//**for current
  // 3. The positions of the 4 largest elements in m
  //    are loaded in Neighborhood object temp
  for (int k = vSIZE-1; k >= vSIZE - 4; k--) 
    temp.Add(v2[k]);
  return temp;
}

 

Due 12/20 Wednesday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
0. Neil, please email me your magic solution so I can post it.
1. Use browser to copy PH.cpp below and  MakePH below to your editor or download them from
    /usr/local/mpx3/jaye.
2.  Important: in MakePH be sure that a TAB rather than spaces is responsible for the indentation before
     the   g++ command and before the ./PH.out command. Also:
    a. Make sure all the case study files and all the semester AP classs files (apstring, apvector, apmatrix)
        are in the directory in which you compile.
    b. Enter: make -f MakePH
        If you compile & link with gxx, follow instruction on line 4 of MakePH below
    c. If all goes well, execute program with this command: ./PH.out
  
d. See if you can modify getLargest() to enable it to meet its postcondition.

# FILE: MakePH
# PURPOSE: PH.out
# TO USE: To execute PH.out, enter: ./PH.out
# FOR gxx: Change g++ to gxx
PH.out: PH.cpp apstring.cpp environ.o fish.o position.o nbrhood.o \
utils.o display.o simulate.o randgen.o
        g++ -o PH.out PH.cpp apstring.cpp environ.o fish.o position.o \
nbrhood.o utils.o display.o simulate.o randgen.o
      ./PH.out
   
// FILE: PH.cpp
// PURPOSE: Use Position and Neighborhood classes
// OTHER FILES: All case study and semester I AP class files and
//              MakePH
//---------------------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ 
// 1. COMMAND LINE: 
//    make -f MakePH
// 2. TO EXECUTE: ./PH.out
//---------------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Modify getLargest() to enable it to return Neighborhood object
//    containing positions of the 4 largest elements in apmatrix m
//---------------------------------------------------------------------
#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
#include "apmatrix.h"
#include "apstring.h"
#include "environ.h"
#include "display.h"
#include "simulate.h"
Neighborhood getLargest(const apmatrix<long> &m) {
  // precond: m has at least 4 elements
  //postcond: returns neighborhood object which contains
  //          positions of 4 largest elements in m
  Neighborhood temp;
  const int COLS = m.numcols();
  for (int c = 0; c < COLS; c++)
    temp.Add( Position(0, c) );
  return temp;
}
void load(apmatrix<long> &);
void print(const apmatrix<long> &);
int main() {
  apstring title("Executing Position/Neighborhood class program");
  cout << "\n\n\n\n\n\t\t" << title << endl << endl;
  apmatrix<long> M;
  load(M);
  print(M);
  Neighborhood max = getLargest(M);
  cout << "Positions of the 4 largest elements:\n";
  cout << max << endl << endl;
  cout << "Values are:\n";
  for (int k = 0; k < max.Size(); k++) {
    Position P = max.Select(k);
    cout << P << " = " << M[P.Row()][P.Col()] << endl;
  }
  cout << endl;
  return 0;
}
void load(apmatrix<long> &m) {
  long A[][5] = { {17, 83, 31, 27, 44}, {55, 19, 65, 37, 34},
		      {99, 29, 39, 49, 59}, {11, 22, 33, 44, 55} };
  int ROWS1 = sizeof(A)/sizeof(A[0]);
  int COLS1 =sizeof(A[0])/sizeof(long);
  m.resize(ROWS1, COLS1);
  for (int r = 0; r < ROWS1; r++)
    for (int c = 0; c < COLS1; c++)
      m[r][c] = A[r][c];
}
void print(const apmatrix<long> &M) { 
  const int ROWS = M.numrows(), COLS = M.numcols();
  for (int r = 0; r < ROWS; r++) {
    cout << "\t\t";
    for (int c = 0; c < COLS; c++) {
      cout << setw(6) << M[r][c];
    }//**for c
    cout << endl;
  }//**for r
  cout << endl;
}


Due 12/19 Tuesday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. The instructions for compiling and linking posProblem.cpp program (due 12/15 Friday) were
    incorrect: Use position2.h and position2.cpp. The currrent version of   the program (under 12/15 Friday)
    will not cause the compiling/linking errors that the original version did. See if you can get posProblem.cpp
    program to compile and link if you weren't able to before.
2. Use browser to copy magic.cpp below to your editor or download it from /usr/local/mpx3/jaye.
    Then complete the program as specified in the PROGRAMMING INSTRUCTIONS.

// FILE: magic.cpp
// PURPOSE: implement Coxeter's Magic Squares Algorithm
// OTHER FILES: apvector.h, apvector.cpp, apstring.h apstring.cpp
//              apmatrix.h, apmatrix.cpp
//---------------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ and gxx
// 1. FILES: apvector.h, apvector.cpp, apstring.h apstring.cpp, apmatrix.h
//    apmatrix.cpp must be in folder or directory in which you compile
// 2. COMMAND LINE:
//    g++ (or gxx) magic.cpp apstring.cpp
//---------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Complete magic() as specified below
//---------------------------------------------------------------
#include <iomanip.h>
#include "apstring.h"
#include "apmatrix.h"
void magic(apmatrix<int> &m, int n) {
  //precond: n is # of elements in a side
  //post: m is resized to n by n and it's a Magic Square!!
  //-----------------------------------
  // Use Coxeter's algorithm
  //------------------------------------
  m = apmatrix<int>(n, n, 0);   // This works with gxx!!!
}
void print(const apmatrix<int> &);
int main() {
  apmatrix<int> M;
  for (;;) {
    const apstring title("Using Coxeter's Magic Squares Algorithm");
    cout << "\n\n\n\n\n\n\n\n";
    cout << setw(39 + title.length()/2) << title.c_str() << endl << endl;
    int n;
    for (;;) {
      cout << "Enter size of square (odd # from 1 to 13, -1 to quit): ";
      cin >> n;  cin.ignore(80, '\n');
      if ( n < 0 ) break;
      else if ( n % 2 == 1 && n >= 1 && n <= 13 )
        break;
    }
    if ( n < 0 ) return 0;
    magic(M, n);
    print(M);
    cout << "\n\nPress <ENTER> to continue...";
    cin.ignore(10, '\n');
    cout << endl;
  }//== for
  return 0;
}
void print(const apmatrix<int> &m) {
  const int ROWS = m.numrows(), COLS = m.numcols();
  const int WIDTH = 5;
  apmatrix<int> M;
  M = m;
  M.resize(ROWS+1, COLS+1);
  for (int r = 0; r < ROWS; r++) {  // 1. sum rows
    long rowSum(0);
    for (int c = 0; c < COLS; c++)
      rowSum += M[r][c];
    M[r][COLS] = rowSum;
    M[r][COLS] = rowSum;
  }//==for r
  for (int c = 0; c < COLS; c++) { // 2. sum cols
    long colSum(0);
    for (int r = 0; r < ROWS; r++)
      colSum += M[r][c];
    M[ROWS][c] = colSum;
  }//==for c
  long diagSumHi(0), diagSumLo(0); // 3. sum diagonals
  for (int r = 0; r < ROWS; r++) { // Could be done with
    diagSumLo += M[r][r];          // row or col sums!!
    diagSumHi += M[r][ROWS-1-r];
  }
  M[ROWS][COLS] = diagSumLo;
  cout << endl;                   // 4. print it
  cout << setw(WIDTH * (ROWS+1)) << diagSumHi << endl;
  for (int r = 0; r < ROWS+1; r++) {
    for (int c = 0; c < COLS+1; c++)
      cout << setw(WIDTH) << M[r][c];
    cout << endl;
  }
  cout << endl;
}

Due 12/18 Monday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. Revise p  approximation program to work with a Position object instead of  x and y variables. (To
     use the Position class copy position2.h and position2.cpp from this web site: Marine Biology case study
2. Read Litvin section 6.4.3 (Neighborhood class) and Hubbard pp. 273-275 (composition).

Due 12/15 Friday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. In Rational1.cpp: Implement free binary operators - and ==. Write driver to validate them.
2. In Litvin's Chapter 6: Case Study. Read section 6.4.2 (the Position class).
3. Use browser to copy posProblem.cpp below to your editor or download it from /usr/local/mpx3/jaye.
    Then complete the program as specified in the PROGRAMMING INSTRUCTIONS.

// FILE: posProblem.cpp
// PURPOSE: Work with ADT Position
// OTHER FILES: position2.h and position2.cpp
//---------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ and gxx
// 1. FILES: position2.h, position2.cpp, apstring.h, apstring.cpp
//           must be in folder or directory in which you compile
// 2. COMMAND LINE:
//    g++ (or gxx) posProblem.cpp position2.cpp apstring.cpp
//-------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Complete distance() as specified and run program to validate.
// 2. Complete maxPair() as specified and run program to validate.
//-------------------------------------------------------------------
#include <iomanip.h>
#include <math.h>
#include "apvector.h"
#include "position2.h"
double distance(const Position &A, const Position &B) {
  //postcondition: returns distance between coordinates represented
  //  by A and B
  return -1.5;
}
apvector<Position> maxPair(const apvector<Position> &v) {
  // precondition: v contains at least 2 elements. 
  //postcondition: returns an apvector of the two Positions in v whose
  //  coordinates are at the greatest distance from each other. Use distance()
  apvector<Position> max(2);
  return max;
}
void load(apvector<Position> &);
void print(const apvector<Position> &);
void distTest(void);
int main() {
  apstring title("Finding pair of coordinates forming largest distance in V");
  cout << "\n\n\n\n\n\t" << title << endl << endl;
  apvector<Position> v, pair;
  distTest();
  load(v);
  print(v);
  pair = maxPair(v);
  cout << "The pair is: " << pair[0] << " and " << pair[1] << endl;
  cout << "Their distance is: " << distance(pair[0], pair[1]) << endl;
  cout << "Output should be: (80,3) and (-9,4) with distance = 89.0056\n";
  cout << endl;
  return 0;
}
void load(apvector<Position> &vec) {
  Position A[] = { Position(3,2), Position(5,1), Position(80,3), 
		   Position(0,15), Position(7,8), Position(75,8), Position(19,13), 
		   Position(-9,4), Position(12, 6), Position(12,15)  };
  const int SIZE = sizeof(A)/sizeof(Position);
  vec.resize(SIZE);
  for (int k = 0; k < SIZE; k++)
    vec[k] = A[k];
}
void print(const apvector<Position> &vec) {
  const int SIZE = vec.length();
  cout << endl;
  for (int k = 0; k < SIZE; k++)
    cout << setw(3) << k << ".   " << vec[k] << endl;
}
void distTest(void) {
  Position A(2, 4), B(14, 9), C(2, 10);
  cout << "Testing distance():\n";
  cout << A << " to " << B << " = " << distance(A, B) << endl;
  cout << A << " to " << C << " = " << distance(A, C) << endl;
}



Due 12/14 Thursday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. Use RandGen class and Monte Carlo Method to write short program that approximates p. Print out
    n(in cicular region), n(in square region), and current approximation for every million or 10 million
    simulated (x, y) ordered pairs.
2. In Rational1.cpp:
a. Implement member function reduce() which: (1) reduces p and q to lowest terms and (2) normalizes
    p and q: 7/(-5) is changed to -7/5,  0/(-6) is changed to 0/1 and 7/0 is changed to 0/1. Hint: Euclid's
    algorithm can be quite helpful!
b. Use reduce() to improve the explicit-value constructor (shouldn't be necessary for default or copy
    constructors!!).
c. Implement ostream << operator that supports chaining and free + operator and write driver to validate them.
    BEFORE you attempt to implement << and +, comment out prototypes for all assignment operators in
    the Rational class definition or you will get LINKING ERRORS.
    EXAMPLE: Rational X(10, -35), Y(18,  28),   Z;
                         Z = X + Y;
                        cout << "X = " << X << "  Y = " << Y << "  X + Y = " << Z << endl;
    OUTPUT: X = -2/7    Y = 9/14      X + Y = 5/14

Due 12/13 Wednesday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. Download and print Litvin's Chapter 6: Case Study. Read sections 6.1 and 6.2 (the RandGen class).
2.  Cancel approximation of p until Thursday (we'll review problem Weds). Instead, use browser
     to copy  randTest.cpp below to your editor and follow PROGRAMMING INSTRUCTIONS .
3. Use browser to copy Rational1.cpp below to your editor or download it from /usr/local/mpx3/jaye.
    Then complete the program as specified in the PROGRAMMING INSTRUCTIONS.

// FILE: randTest.cpp
// PURPOSE: Use RandGen class member functions
// OTHER FILES: randgen.h, and randgen.cpp
//---------------------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ and gxx 
// 1. FILES: randgen.h and randgen.cpp must be in folder or directory 
//    in which you compile
// 2. COMMAND LINE: 
//    g++ (or gxx) randtest.cpp randgen.cpp
//--------------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Run program several times and observe results.
// 2. Replace explicit-value constructor, RandGen X(17), with
//    default constructor, RandGen X. Run program and observe results.
//-------------------------------------------------------------------
#include <iomanip.h>
#include "randgen.h"

void testRandInt(void);
void realTest(void);
void main(void) {
  RandGen X(17);
  // RandGen X;
  testRandInt();
  realTest();
  cout << endl << endl;
}//*** main
void testRandInt(void) {
  RandGen rg;
  cout << "\n\n\n\n\n\n\nTesting rg.RandInt(2):  ";
  for (int k = 0; k < 15; k++) cout << setw(3) << rg.RandInt(2);
  cout << "\nTesting rg.RandInt(3):  ";
  for (int k = 0; k < 15; k++) cout << setw(3) << rg.RandInt(3);
  cout << "\nTesting rg.RandInt(10): ";
  for (int k = 0; k < 15; k++)cout << setw(3) << rg.RandInt(10);
  cout << "\n\nTesting rg.RandInt(-1,1): ";
  for (int k = 0; k < 15; k++)cout << setw(3) << rg.RandInt(-1,1);
  cout << "\nTesting rg.RandInt(-2,2): ";
  for (int k = 0; k < 15; k++)cout << setw(3) << rg.RandInt(-2,2);
  cout << "\nTesting rg.RandInt(1,6):  ";
  for (int k = 0; k < 15; k++)cout << setw(3) << rg.RandInt(1,6);
}
void realTest(void) {
  RandGen rg;
  cout << setprecision(5) << setiosflags(ios::showpoint | ios::fixed);
  cout << "\n\nTesting rg.RandReal():\n";
  for (int k = 1; k <= 24; k++) 
    cout << setw(9) << rg.RandReal() << ( k % 8 ? "" : "\n" );
  cout << "\nTesting rg.RandReal(-9, 9):\n";
  for (int k = 1; k <= 24; k++) 
    cout << setw(9) << rg.RandReal(-9, 9) << ( k % 8 ? "" : "\n" );
}
// FILE: Rational1.cpp
// PURPOSE: Implement a rational number class
// OTHER FILES: apstring.h apstring.cpp
//---------------------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ and gxx 
// 1. FILES: apvector.h, apvector.cpp apstring.h, apstring.cpp must 
//    be in folder or directory in which you compile
// 2. COMMAND LINE: 
//    g++ (or gxx) Rational1.cpp apstring.cpp
//---------------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Implement member functions getP() and getQ() FIRST. You can't 
//    compile without them.
// 2. Implement and test ONE AT A TIME: a. Rational() b. Rational(int, int)
//    c. Rational(const Rational &)  Think about reduce() (due Thursday)
//---------------------------------------------------------------------
#include <iomanip.h>
#include "apstring.h"
class Rational {
public:
  Rational(void);   //** sets p to 0, q to 1
  Rational(int p2, int q2);  //** sets p to p2, q to q2
  Rational(const Rational &r); //** sets p to r.p, q to r.q
  int getP(void) const; //** returns p
  int getQ(void) const; //** returns q  
  void printData(void) const; //** prints p and q in "p/q" format
  Rational &operator=(const Rational &r); //** assigns to owner
  Rational &operator+=(const Rational &r); //** assigns p/q + r.p/r.q to owner 
  Rational &operator+=(int r);  //** //** assigns p/q + r to owner 
  Rational &operator-=(const Rational &r); //** assigns p/q - r.p/r.q to owner  
  Rational &operator-=(int r); //** assigns p/q - r to owner  
private:
  void reduce(); //** reduces p/q to lowest terms. q is NEVER negative  
  int p;
  int q;
};
//////////////////////////////////////////////////////////////////////
//  define member functions below:

//-----------------------------------------------------------
ostream &operator << (ostream &, const Rational &);
ostream &operator >> (istream &, const Rational &);
//////////////////////////////////////////////////////////////////////
//  define stream operator functions below:

//-----------------------------------------------------------
Rational operator + (const Rational &, const Rational &);
Rational operator - (const Rational &, const Rational &);
Rational operator * (const Rational &, const Rational &);
Rational operator / (const Rational &, const Rational &);
//////////////////////////////////////////////////////////////////////
//  define free arithmetic operator functions below:


//-----------------------------------------------------------
bool operator == (const Rational &, const Rational &);
bool operator != (const Rational &, const Rational &);
bool operator > (const Rational &, const Rational &);
bool operator < (const Rational &, const Rational &);
//////////////////////////////////////////////////////////////////////
//  define free arithmetic operator functions below:
void driver1(void); // tests all three constructors, printData(), and reduce()
int main(void) {
  driver1();
  cout << endl << endl;
  return 0;
}//*** main
void driver1(void) {
  apstring title("Testing getP(), getQ(), the constructors, before reduce()");
  cout << "\n\n\n\n\n";
  cout << setw(39 + title.length()/2) << title. c_str() << endl << endl;
  Rational X;
  cout << "After Rational X; X should = 0/1\nX currently = "
       << X.getP() << "/" << X.getQ() << endl << endl;
  Rational Y(-35, 21);
  cout << "After Rational Y(-35, 21); Y should = -5/3\nY currently = "
       << Y.getP() << "/" << Y.getQ() << endl << endl;
  Rational Z(35, -21);
  cout << "After Rational Z(35, -21); Y should = -5/3\nY currently = "
       << Y.getP() << "/" << Y.getQ() << endl << endl;
  cout << "If Y != -5/3 and Z != -5/3, work on private member function reduce()\n"
       << "Hint: Use Euclid's Algorithm and use reduce() in the constructors.\n\n";
  Rational W(Y);
  cout << "After Rational W(Y); W should = -5/3\nW currently = "
       << W.getP() << "/" << W.getQ() << endl << endl;
}

 

Due 12/12 Tuesday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. Use browser to copy apmatrixAP1.cpp below to your editor or download it from /usr/local/mpx3/jaye.
    Then complete the program as specified in the PROGRAMMING INSTRUCTIONS.

// FILE: apmatrixAP1.cpp
// PURPOSE: AP Exam practice problem: apmatrix class
// OTHER FILES: apvector.h, apvector.cpp, apstring.h apstring.cpp
//              apmatrix.h, apmatrix.cpp
//---------------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ and gxx 
// 1. FILES: apvector.h, apvector.cpp, apstring.h apstring.cpp, apmatrix.h
//    apmatrix.cpp must be in folder or directory in which you compile
// 2. COMMAND LINE: 
//    g++ (or gxx) apmatrixAP1.cpp apstring.cpp 
//---------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Study the affect of sumBorder() and deleteBorder() with
//    the three examples of apmatrix object A shown below 
// 2. Complete sumBorder() and deleteBorder() as specified below,
//    and run program to validate your solutions.
/*****************************************************************
               PRACTICE AP EXAM A QUESTION: using apmatrix class
   sumBorder(A) = 15 when A is:
   1   0   2   1
   0   1   2   2
   2   3   0   4
   A after deleteBorder:
   1   2
-----------------------------------------------------
   sumBorder(A) = 33 when A is:
   2   3   0   4
   5   0   1   2
   3   6   0   4
   1   2   3   4
   A after deleteBorder:
   0   1
   6   0
-----------------------------------------------------
   sumBorder(A) = 10 when A is:
   1   2
   3   4
   A after deleteBorder:
   Table is empty.
*****************************************************************/
#include <iomanip.h>
#include "apmatrix.h"
#include "apstring.h"
int sumBorder(const apmatrix<int> &M) {
  //precondition:  M.numrows() > 1, M.numcols() > 1
  //postcondition: returns the sum of the values in the border of the matrix
  //----------------------------------------------------------------------
  const int ROWS = M.numrows(), COLS = M.numcols();
  cout << "\n *** sumBorder() not installed *** ";
  return -77;
}//*** sumBorder
void deleteBorder(apmatrix<int> &M) {
  //precondition:  M.numrows() > 1, M.numcols() > 1
  //postcondition: removes the border of M by moving rows up and columns left
  //               and by resizing M to have 2 fewer rows and 2 fewer columns
  //               EXAMPLE: M.resize(M.numrows()-2, M.numcols()-2);
  //------------------------------------------------------------------------
  const int ROWS = M.numrows(), COLS = M.numcols();
  cout << "\n *** deleteBorder() not installed *** ";
}//*** deleteBorder
void print(const apmatrix<int> &M, apstring msg);
void load(apmatrix<int> &, apmatrix<int> &, apmatrix<int> &);
void load(apmatrix<int> &, const int *A);
void test(apmatrix<int> &);
void main(void) {
  apmatrix<int> A, B, C;
  apstring title("PRACTICE AP EXAM A QUESTION: using apmatrix class");
  cout << "\n\n\n\n\n\n" << setw(39 + title.length()/2) << title.c_str() << endl << endl;
  load(A, B, C);
  test(A);
  cout << "Press <ENTER>: "; cin.ignore(10, '\n');
  test(B);
  cout << "Press <ENTER>: "; cin.ignore(10, '\n');
  test(C);
  return 0;
}
void test(apmatrix<int> &M) {
  cout << "\n\n   sumBorder(M) = " << sumBorder(M) << " when A is:"; 
  print(M, "");
  deleteBorder(M); 
  print(M, "\n   A after deleteBorder:");
  cout << "\n   sumBorder(M) = " << sumBorder(M) << endl;
  cout << "----------------------------------------\n\n";
}
void print(const apmatrix<int> &M, apstring msg) {
  const int wdth = 4;
  int Rows = M.numrows(), Cols = M.numcols();
  cout << msg << endl;
  if ( Rows < 1 || Cols < 1 ) {
    cout << "   Table is empty." << endl;
    return;
  }
  for (int r = 0; r < Rows; r++) {
    for (int c = 0; c < Cols; c++)
      cout << setw(wdth) << M[r][c];
    cout << endl;
  }//for r
}//*** print
void load(apmatrix<int> &m1, apmatrix<int> &m2, apmatrix<int> &m3) {
  const int A1[3][4] = { {1, 0, 2, 1}, {0, 1, 2, 2}, {2, 3, 0, 4}};
  const int A2[4][4] = { {2, 3, 0, 4}, {5, 0, 1, 2}, {3, 6, 0, 4},
			 {1, 2, 3, 4}};
  const int A3[2][2] = { {1, 2}, {3, 4}};
  m1.resize(sizeof(A1)/sizeof(A1[0]), sizeof(A1[0])/sizeof(int));
  load(m1, &A1[0][0]); 
  m2.resize(sizeof(A2)/sizeof(A2[0]), sizeof(A2[0])/sizeof(int));
  load(m2, &A2[0][0]); 
  m3.resize(sizeof(A3)/sizeof(A3[0]), sizeof(A3[0])/sizeof(int));
  load(m3, &A3[0][0]); 
}//*** load
void load(apmatrix<int> &M, const int *A) {
  const int COLS = M.numcols();
  for (int r = 0; r < M.numrows(); r++)
    for (int c = 0; c < COLS; c++)
      M[r][c] = *(A + r*COLS + c); 
}//*** load

Due 12/11 Monday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. Read Litvin pp. 35-36 (apvector constructors and assignment) and pp. 40-42 (apmatrix class)
2. Take 10-minute practice test (after the assigned reading above). In Litvin's Exam A (p.129) do
     problems 26-30.   Set a timer for 10 minutes and STOP at that time. Record your result on p. 293.
3. Use browser to copy apmatrix1.cpp below to your editor or download it from /usr/local/mpx3/jaye.
    Then complete the program as specified in the PROGRAMMING INSTRUCTIONS.

// FILE: apmatrix1.cpp
// PURPOSE: Work with apmatrix container class
// OTHER FILES: apvector.h, apvector.cpp, apstring.h apstring.cpp
//              apmatrix.h, apmatrix.cpp
//---------------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ and gxx 
// 1. FILES: apvector.h, apvector.cpp, apstring.h apstring.cpp, apmatrix.h
//    apmatrix.cpp must be in folder or directory in which you compile
// 2. COMMAND LINE: 
//    g++ (or gxx) apmatrix1.cpp apstring.cpp 
//---------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Complete sumMat(), maxRow(), and maxCol() as specified below
//    and run program to validate your solutions
// 2. Complete swapCols() and swapRows(), run program to validate.
//----------------------------------------------------------------
#include <iomanip.h>
#include "apstring.h"
#include "apmatrix.h"
long sumMat(const apmatrix<long> &mat) {
  // postcond: if mat has elements, their sum is returned
  //           otherwise, 0 is returned
  return -77;
}
void maxRow(const apmatrix<long> &m, long &rowSum, int &rowNum) {
  // precond: m isn't an empty apmatrix
  // postcond: the row whose sum is largest has its total assigned
  //           to rowSum and its index position stored to rowNum
  rowSum = -77; rowNum = -77;
}
void maxCol(const apmatrix<long> &m, long &colSum, int &colNum) {
  // precond: m isn't an empty apmatrix
  // postcond: the column whose sum is largest has its total assigned
  //           to colSum and its index position stored to colNum
  colSum = -77; colNum = -77;
}
void swapCols(apmatrix<long> &m, int c1, int c2) {
  // precond: m isn't an empty matrix, c1 and c2 < m.numcols()
  // postcond: the columns with index positions c1 and c2 are swapped
}
void swapRows(apmatrix<long> &m, int r1, int r2) {
  // precond: m isn't an empty matrix, r1 and r2 < m.numrows()
  // postcond: the rows with index positions c1 and c2 are swapped
}
void loadMat(apmatrix<long> &);
void printMat(const apmatrix<long> &, const apstring &);
void driver1(const apmatrix<long> &);
void driver2(apmatrix<long> &);
int main() {
  const apstring title("Testing apmatrix operations");
  cout << "\n\n\n\n\n\n" << setw(39 + title.length()/2) 
       << title.c_str() << endl << endl;
  apmatrix<long> m;
  loadMat(m);
  driver1(m); //*** test sumMat(), maxRow(), and maxCol()
  driver2(m); //*** test swapCols() and swapRows()
  cout << endl;
  return 0;
}
void driver1(const apmatrix<long> &M) {
  printMat(M, "Before sumMat(M):");
  cout << "Sum of the elements is: " << sumMat(M) << endl;
  int maxRowNum; long maxRowSum;
  maxRow(M, maxRowSum, maxRowNum);
  
  cout << "max row's index: " << maxRowNum << "   " 
       << "max row sum: " << maxRowSum << endl;
  int maxColNum; long maxColSum;
  maxCol(M, maxColSum, maxColNum);
  cout << "max col's index: " << maxColNum << "   "
       << "max col sum: " << maxColSum << endl;
  cout << endl;
}
void driver2(apmatrix<long> &M) {
  swapCols(M, 1, 3);
  printMat(M, "After swapCols(1, 3) and before swapRows(M, 0, 1):");
  swapRows(M, 0, 2);
  printMat(M, "\nAfter swapRows(M, 0, 2):");
}
void loadMat(apmatrix<long> &m) {
  const int COLS = 4;
  long M[][COLS] = { { 9, 12, 13, 15},
                     {14,  7, 11, 19},
		     {18, 13, 16, 17} };
  const int ROWS = sizeof(M)/sizeof(M[0]);
  m.resize(ROWS, COLS);
  for (int r = 0; r < ROWS; r++)
    for (int c = 0; c < COLS; c++)
      m[r][c] = M[r][c];
}
void printMat(const apmatrix<long> &m, const apstring &msg) {
  const int ROWS = m.numrows(), COLS = m.numcols();
  cout << msg << endl;
  for (int r = 0; r < ROWS; r++) {
    for (int c = 0; c < COLS; c++)
      cout << setw(4) << m[r][c];
    cout << endl;
  }
}

Due 12/08 Friday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. Take 10-minute practice test: In Litvin's Exam A (p.129) do problems 16 thru 20. Set a timer for
    10 minutes and STOP at that time.
2. Use browser to copy classes5.cpp below to your editor or download it from /usr/local/mpx3/jaye.
    Then complete the program as specified in the PROGRAMMING INSTRUCTIONS.

// FILE: classes5.cpp
// PURPOSE: Use overloaded assignment operators
// OTHER FILES: apvector.h, apvector.cpp, apstring.h apstring.cpp
//---------------------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ and gxx 
// 1. FILES: apvector.h, apvector.cpp apstring.h, apstring.cpp must 
//    be in folder or directory in which you compile
// 2. COMMAND LINE: 
//    g++ (or gxx) classes5.cpp apstring.cpp
//---------------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Complete operator=() as specified below. Validate your solution
//    by running program and choosing option 6.
// 2. Modify bSearch() below by using overloaded < and > operators.
//    Your final version should NOT call member function getName().
// 3. Declare and implement an -= for Complex and an -= for double. 
//    Then (1) uncomment #define MINUS_EQL(beneath the #includes) and 
//    (2) go to withdrawDriver() and change V[index].withdraw(amount) 
//    to V[index] -= amount to validate.
//---------------------------------------------------------------------
#include <iostream.h>
#include <iomanip.h>
#include "apvector.h"
#include "apstring.h"
//#define MINUS_EQL 
class Customer {
public:
  Customer(void);
  Customer(const apstring &, double);
  Customer (const Customer &);
  void printData(void) const;
  apstring getName(void) const;
  double getBalance(void)const;
  bool getWasAssigned(void) const;
  Customer &operator=(const Customer &);
  void deposit(double amt);
  void withdraw(double amt);
private:
  apstring name;
  double balance;
  bool wasAssigned;
};
ostream &operator << (ostream &, const Customer &);
ostream &operator >> (istream &, const Customer &);
bool operator > (const apstring &, const Customer &);
bool operator < (const apstring &, const Customer &);
void assignmentDriver(void);
void withdrawDriver(apvector<Customer> &);
void addCustomer(apvector<Customer> &);
void deleteCustomer(apvector<Customer> &);
void loadVec(apvector<Customer> &);
void printVec(const apvector<Customer> &, const apstring &);
void menu(char &);
void bSearchDriver(const apvector<Customer> &);
void depositDriver(apvector<Customer> &);
Customer &Customer::operator=(const Customer &right) {
  //postcondition: LHS (the owner) gets right's name and balance
  //  but wasAssigned gets true regardless
}
int bSearch(const apvector<Customer> &v, const apstring &key) {
  // precondition: v's elements are in ascending order
  //postcondition: when Customer's name = key, its index is returned
  // otherwise -1 is returned 
  int lo(0), hi(v.length()-1);
  while ( lo <= hi ) {
    int mid = (lo + hi)/2;
    if ( key < v[mid].getName() )
      hi = mid - 1;
    else if ( key > v[mid].getName() )
      lo = mid + 1;
    else
      return mid;
  }
  return -1;
}
int main(void) {
  apvector<Customer> cVec;
  char ch;
  loadVec(cVec);
  do {
    printVec(cVec, "");
    menu(ch);
    switch( ch ) {
    case '1': bSearchDriver(cVec); break;
    case '2': depositDriver(cVec); break;
    case '3': withdrawDriver(cVec); break;
    case '4': addCustomer(cVec); break;
    case '5': deleteCustomer(cVec); break;
    case '6': assignmentDriver(); break;
    case '0': return 0;
    default: break;
    } // switch
    cout << "Press <ENTER> to continue..."; cin.ignore(80, '\n');
  } while (ch != '0');
  cout << endl << endl;
  return 0;
}//*** main
//////////////////////////////////////////////////////////////////////
//  free (non-member) functions that have been defined
//////////////////////////////////////////////////////////////////////
void deleteCustomer(apvector<Customer> &V) {
  // precondition: bSearch() works!!
  //postcondition: if found, specified Customer object is removed by
  // shifting all successors (if any) forward and V is resized accordingly
  // EXAMPLE deleting L: A D G K L M Q X  ---->  A D G K M Q X                   
  //                     0 1 2 3 4 5 6 7         0 1 2 3 4 5 6 
  apstring name;
  cout << "Enter name of customer to delete: ";
  getline(cin, name);
  int index = bSearch(V, name);
  if ( index < 0 ) {
    cout << "ERROR: " << name << " not found.\n";
  }
  else {
    const int SIZE = V.length();
    for (int p = index; p < SIZE-1; p++) {
      V[p] = V[p+1];
    }
    V.resize(SIZE-1);
  }
}
void addCustomer(apvector<Customer> &V) {
  // HINT: don't use bSearch()--use a linear search here!!
  //postcondition: specified Customer object is added by shifting
  //  all successors (if any) back and V is resized accordingly
  // EXAMPLE adding L: A D G K M Q X ---->  A D G K L M Q X                   
  //                   0 1 2 3 4 5 6        0 1 2 3 4 5 6 7 
  const int SIZE(V.length());
  apstring name;
  cout << "Enter name of customer to add: ";
  getline(cin, name);
  int insertPos;
  for (insertPos = 0; insertPos < SIZE; ++insertPos) {
    if ( name < V[insertPos].getName() ) break;
  }
  V.resize(SIZE+1);
  for (int index = SIZE; index > insertPos; --index) {
    V[index] = V[index-1];
  }
  V[insertPos] = Customer(name, 0.0);
}
void withdrawDriver(apvector<Customer> &V) {
  // precondition: bSearch() function works!!! 
  //postcondition: this is the counterpart to depositDriver(). Therefore
  // use depositDriver() as a model to complete this function
  apstring name;
  cout << "Enter customer name: ";
  getline(cin, name);
  int index = bSearch(V, name);
  if ( index < 0 ) {
    cout << name << " not found.\n";
  }
  else {
    cout << "Enter amount to withdraw: ";
    double amount;
    cin >> amount; cin.ignore(10, '\n');
    V[index].withdraw(amount);
    cout << "New balance is: " << V[index].getBalance() << endl;
  }
}
void assignmentDriver(void) {
  apstring title("Testing overloaded assignment operators");
  cout << "\n\n\t\t" << title << endl << endl;
  Customer X("Pat", 123.45), Y, Z;
  cout << "BEFORE STATEMENT z = y = x;\n";
  cout << "Customer object X = " << X << endl << "Customer object Y = " 
       << Y << endl << "Customer object Z = " << Z << endl;
  Z = Y = X;
  cout << "AFTER  STATEMENT z = y = x;\n";
  cout << "Customer object X = " << X << endl << "Customer object Y = " 
       << Y << endl << "Customer object Z = " << Z << endl << endl;
  Z = Customer("Les", 123.45); Y = Customer();
  cout << "BEFORE STATEMENT z = y -= x;\n";
  cout << "Customer object X = " << X << endl << "Customer object Y = " 
       << Y << endl << "Customer object Z = " << Z << endl;
#ifdef MINUS_EQL 
  Z = Y -= X;
#endif
  cout << "AFTER STATEMENT z = y -= x;\n";
  cout << "Customer object X = " << X << endl << "Customer object Y = " 
       << Y << endl << "Customer object Z = " << Z << endl;
}
void loadVec(apvector<Customer> &A) {
  Customer list[] = 
  {Customer("Boden", 2920.20), Customer("Ferrara", 666.77), Customer("Gell", 7000),
   Customer("Green",757.99), Customer("Jaye", 1267.13), /*Customer("Latham", 110.6),*/
   Customer("Liang", 1199.88), Customer("Platek", 15.15), Customer("Simion", 1919.19), 
   Customer("Winokur", 23.23), Customer("Zaman", 260.26) };
  const int SIZE = sizeof(list)/sizeof(Customer);
  A.resize(SIZE);
  for (int k = 0; k < SIZE; k++) {
    A[k] = list[k];
  }
}
void printVec(const apvector<Customer> &A, const apstring &msg) {
  cout << "\n\n\n\n\n" << msg;
  const int ColSIZE = 12;
  const int SIZE = A.length();
  for (int k = 0; k < SIZE; k++)
    cout << setw(20) << k << "  " << A[k].getName() 
	 << setw(ColSIZE - A[k].getName().length()) << ""
	 << setiosflags(ios::fixed | ios::right) << setprecision(2) 
	 << setw(7) << A[k].getBalance() << "  wasAssigned = "
	 << ( A[k].getWasAssigned() ? "true" : "false" ) << endl;
  cout << endl;
}
void menu(char &choice) {
  const int left = 25;
  int top = 6;
  const apstring TAB("\t\t\t");
  cout << TAB << "  Bank Customer List Operations\n";
  cout << TAB << "----------------------------------\n";
  cout << TAB << "Binary search on customer name   1\n";
  cout << TAB << "Make a deposit                   2\n";
  cout << TAB << "Make a withdrawal                3\n";
  cout << TAB << "Add a new customer               4\n";
  cout << TAB << "Delete a customer                5\n";
  cout << TAB << "Test overloaded assignment       6\n";
  cout << TAB << "Quit program                     0\n";
  cout << TAB << "----------------------------------\n";
  cout << TAB << "       SELECTION==> ";
  for (;;) {
    cin.get(choice); cin.ignore(10, '\n');
    if ( choice < '0' || choice > '7' )  
      cout << TAB << "*** Invalid choice. Try again: ";
    else
      break;
  }
} //*** menu
void bSearchDriver(const apvector<Customer> &V) {
  apstring name;
  cout << "Enter customer name to be searched: ";
  getline(cin, name);
  int index = bSearch(V, name);
  if ( index < 0 )
    cout << name << " not found.\n";
  else {
    cout << name << " found at index position " << index 
     << ",  Balance = " << V[index].getBalance() << endl;
  }
}
void depositDriver(apvector<Customer> &V) {
  apstring name;
  cout << "Enter customer name: ";
  getline(cin, name);
  int index = bSearch(V, name);
  if ( index < 0 ) {
    cout << name << " not found.\n";
  }
  else {
    cout << "Enter amount to deposit: ";
    double deposit;
    cin >> deposit; cin.ignore(10, '\n');
    V[index].deposit(deposit);
    cout << "New balance is: " << V[index].getBalance() << endl;
  }
}
//////////////////////////////////////////////////////////////////////
//  member functions that have been defined
//////////////////////////////////////////////////////////////////////
Customer::Customer(void):
  name("John Doe"), balance(0.0), wasAssigned(false) {
}
Customer::Customer(const apstring &name2, double balance2): 
  name(name2), balance(balance2), wasAssigned(false) {
}
Customer::Customer(const Customer &customer):
  name(customer.name), balance(customer.balance), wasAssigned(false) { 
}
apstring Customer::getName(void) const {
  return name;
}
double Customer::getBalance(void)const {
  return balance;
}
bool Customer::getWasAssigned(void) const {
return wasAssigned;
}
void Customer::deposit(double amt) {
  balance += amt;
}
void Customer::withdraw(double amt) {
  if ( balance - amt < 0 ) 
    balance -= 20.00; //** penalty for attempted over-draft
  else
    balance -= amt;
}
void Customer::printData(void) const  {
  cout << "name = " << name << ",  balance = " 
       << balance << ", wasAssigned = " 
       << ( wasAssigned? "true" : "false" );
}
//-------------------------------------------------------
//  STREAM OPERATOR FUNCTIONS
//-------------------------------------------------------
ostream &operator<<(ostream &os, const Customer &right) {
  right.printData();  
  return os;
}
istream &operator>>(istream &is, Customer &right) {
  apstring name;
  double balance;
  cout << "Enter customer name: "; is >> name;
  cout << "Enter customer balance: "; is >> balance;
  right = Customer(name, balance);
  return is;
}
bool operator > (const apstring &left, const Customer &right) {
  return ( left > right.getName() );
}
bool operator < (const apstring &left, const Customer &right) {
  return ( left < right.getName() );
}
//**** end of program

Due 12/06 Wednesay

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
1. Take 10-minute practice test: In Litvin's Exam A (p.129) do problems 11 thru 15. Set a timer for
    10 minutes and STOP at that time. Then grade your work (p. 257) and identify any concepts or
    skills that seem to be weaknesses. For example, in the 10-problem assignment due Monday, #9-10,
    functiom Smile(), involved a concept called recursion. We haven't studied the concept yet. Use p. 293
    to keep a brief journal or notes on the concepts that challenge you.

2. Read sections 11.2 (overloading the assignment operator), 11.3 (the this pointer. This little section is
     pretty wild--go with the flow and we'll discuss it in class), and 11.5 (arithmetic assignment operators)
3. Overload the stream insertion operator, <<, for the Customer class and enable it to support chaining.
     Design reasonable output and validate your solution by writing a test driver for it.

Due 12/04 Monday

Homework and tests must be kept in chronological order in a folder or a loose leaf binder
0. Test Tueday 12/05: C++ classes, apvector operations: sorting, searching, inserting, etc...
1. Take 20-minute practice test: In Litvin's Exam A (p.129) do problems 1 thru 10. Set a timer for
    20 minutes and STOP at that time. Then grade your work (p. 257) and identify any concepts or
    skills that seem to be weaknesses.
2. Read sections 11.6 (overloading relational operators) and 11.7 (overloading the stream operators)
3. On the basis of the concepts that you just read in section 11.7:
    a. Overload the stream insertion operator, <<, for the Customer class to support this fragment:
        Customer X("Pat", 17.35);
        cout << "X's record: " << X << endl;
        OUTPUT: X's record: name: Pat, balance: 17.35
    b. Design overloaded stream extraction operator, >>,  that supports this fragment:
        cin >> X;
        cout << X << endl;
        OUTPUT: Enter customer name: Eve
                         Enter customer balance: 456.78
                         name: Eve, balance: 456.78

    c In classes3.cpp, define function streamDriver() that tests your overloaded iosteam operator definitions.