CSCI 112: Programming and Algorithms II
Fall 2005
Program 3: Telephone Bill
Code due: 5pm Tuesday October 4
(the first midterm is Friday October 7, it will include linked list programming)
Grading Weight: 4 (programs will have a weight between 1 - 5)

Overview:
Implement a linked-list to store a collection of phone calls as they would appear on a telephone bill.  Each item in the call list includes:
  1. month of call (integer)
  2. day of the month of the call (integer)
  3. number called (string)
  4. length of the call in minutes (integer)
Your program must provide the following functionality:
  1. insert a new call
  2. remove a call by specifying the date and the number called
  3. lookup the length of a call by specifying the date and number called.  If found, print the call to  standard output using the same format as the print command.  If not found, do nothing.
  4. total of all calls in a given month
  5. print all calls


Program Requirements:

Implementation:

Implement your program using the following two classes:
class Call
Stores the information about the call (date, number, minutes) and the next pointer used to link calls together.

Unlike the Movie class in the previous assignment, class Call will NOT have an initialize() function and MUST have a constructor that takes arguments to initialize all of its member variables.

This program will be easier to implement if class Bill can access the private member variables (date, number, minutes).  You can provide access to private member variables by using the friend mechanism.  The friend mechanism allows another class access to all private variables.

class Call
{
        friend class Bill;
        public:
            ...
private:
// private members are now public for class Bill member functions
};

class Bill
Implements the linked-list (a linked-list of class Call)

Will need a constructor to initialized the linked list to empty

Must have a public member function for each of the functionality listed above (insert, remove, lookup, total minutes, print).

Use dynamic allocation to create and delete instances of class Call:

When inserting into the list, you should create a new instance of class Call using the new operator.
When removing a call from the list, you should call delete on the removed call.

Input:
Your program must read commands (insert, remove, lookup, total, print) and data (month, day, number, minutes) from standard input (cin).  The input will be a collection of commands (each on its own line) followed by the data used by the command.  The commands can be in any order, in other words, all the inserts don't have to be first.  

The insert command takes four arguments (month, day, number, minutes), and looks like:
insert 1/4 530-555-1234 42
The remove command takes three arguments (month, day, number):
remove 2/23 530-898-6442
  
The lookup command takes a three arguments (month, day, number) and if there is a matching record, prints the call to the screen just like the print command.
lookup 4/12 800-588-1990
The total command takes a month as the argument and prints the sum of all the minutes of all the calls for that month (see below for format):
total 1
The print command does not take any arguments and prints all calls (see below for format):
print
Note that the commands don't all take the same number of arguments.  In main() you will have to decide how many arguments to read based on the command just read:

Insertion order:

The linked list of calls must be ordered by date.  If there are multiple calls for a single day, then the calls for that day should be in the same order that they were inserted into the list.
Files:

Each class should have a .h file and a .cpp file (note that the filenames are all lower case):
call.h
call.cpp
bill.h
bill.cpp
In addition to the above files, you will need to turn in a file containing your main() function:
main.cpp

Destructor:

You must provide a destructor for class Bill.  It must call delete for each Call object in its linked-list.

Program Output:

When a call is printed (which happens with the print and the lookup commands), print it in this format:

month/day <colon> <space> number <space> minutes <newline>

The call in the insert example above would be printed
1/4: 530-555-1234 42
The total command should print the total in the following format:
total for month 1 is 218 minutes

Errors and Error Messages:
main() must print out all the error messages.  The Bill and Call classes cannot print error messages.

All error messages must be written to standard error (cerr << "Call on ...." << endl).

Only one call per day is allowed to each number (this makes lookup and remove easier).  If the user inserts  a call with the same date and number as a call already in the list, ignore the requests and print the following error (replace the <month> with the actual month, the <day> with actual day, and the <number> with the actual number):

Call on <month>/<day> to <number> is already in list, could not be inserted.

If a call associated with a remove command is not in the list (i.e. no call in the list has this date and number), ignore the request and print the following error:

Call on <month>/<day> to <number> not in list, could not be removed.

If the description associated with a lookup command is not in the list, ignore the request and print the following error:
Call on <month>/<day> to <number> not in list, could not be looked up.
If a command is given other than the legal commands (insert, remove, lookup, total, print), print the following error, and terminated the program by calling exit(1) (since each command has a different number of arguments, it is hard to recover from a bad command):
Unrecognized command: <command>
Can't recover. Giving up.


Hints:

Much of this program is very similar to the last program (p2): the program structure is nearly identical, and the Call class is similar to the Movie class. 

Program incrementally.  For example, make sure that the main() reads the input correctly before moving on.  Then make sure class Call is correct.  Then implement class Bill.

Class Bill is the hardest part.  Implement it incrementally:  The insert and remove functions are the most difficult functions.  You might want to write an insert function that always inserts at the head of the list and get your entire program (except the remove) working before you tackle the ordered-by-date insert.  I suggest that you leave the remove function until last.

Assert statements can be very helpful when first learning how to use pointers.  The steps are:
  1. #include <assert.h>
  2. put assert(expression); statements in your code.  
If an assert expression ever evaluates to false, an error message with the line number of the assert will be printed.

I will post some sample tests to the class website.  These tests are just some samples.  I will write additional tests and use them to grade your program.  I suggest you spend some time thinking about how to test your program and write your own tests.

You should use the UNIX diff command to compare the output of your program to the output of my program.  It works like this:

% diff file_1 file_2

If the files are identical (and they have to be identical for you to pass the test), diff does not print anything to the screen.

If the files are different, diff will print the differences (it prints the different segments from each file).



General Requirements:

I will deduct 10 percent if your program does not compile using my Makefile on the department's Sun workstations.  Thus you must make sure to use the filenames listed below (do not capitalize your filenames), and if you are working on windows, you should compile your program on a Sun before turning it in.

I will grade your program using another program, so if your program does not work exactly as specified below you will lose points.

The first lines of all your files (.h and .cpp) must contain:

/****
last name, first name
ecst_username@ecst.csuchico.edu
112 Program 3: Telephone bill
****/


How to turn in code:
If you download my Makefile, and have your program on a Department machine, you can submit your program by typing:
$ make submit
Look carefully at the output to make sure all the following files were copied:
call.h
call.cpp
bill.h
bill.cpp
main.cpp
You may submit as many times as you want before the deadline.  Once the deadline passes, you will not be able to submit.

You can also just copy or ftp the above files into the directory
:
/user/projects/csci112/p3/USERNAME
where USERNAME is your ecst username.

See how to turn in assignments  for detailed instructions on how to turn in the assignment.

Note:  You will not be able to access this directory once the deadline has passed.


Late assignments:
If you do not finish by the deadline (see top for the deadline), you may turn your assignment in up to 24 hours late.  You will lose 15% for turning your assignment in 1-24 hours late.

If you turn your assignment in late, use the following command:
$ make submit_late
Or you can copy or ftp your assignment into the following directory
/user/projects/csci112/p3_late/USERNAME
Assignments will not be accepted if more than 24 hours late.