Project Description
In this fifth and final phase of the project you will be experimenting with
C++ templates and exceptions in your application.
The Rental System
The Rental System manages a list of customers who want to rent items,
a list of available items, and a list of desired items for each customer (the
customer's "queue"). The system also reacts to the following commands:
OPEN
- Open and read a stock file that represents the items that are currently
in-stock.
- If the file does not exist - display an error
- If the file is empty - display an error
- You may assume all data is correct in stockfile.
CUSTOMER
- Add a customer to the system
- If customer already exists, display an error.
RENT
- Rents items to a customer.
- Until the customer's quota is full, finds the first item on the customer's
queue that is also in-stock, removes it from the stock, and adds it to the
customer's rented list.
- Once the quota is full, a receipt is printed.
- If the quota cannot be filled and a item was rented, a receipt is printed.
- If no item was rented, then no receipt is printed.
RETURN
- Return the item for the customer.
- Removing it from the customer's rented
list and returning it to the stock.
- If the item was not rented by the customer, display an error.
QUEUE
- Add an item to a customer's queue (list of items they want to rent).
- If customer does not exist, display an error.
- If item is in the system (it is either in-stock or rented by another
customer) - allow it to be queued.
- If item does not exist in the system, display an error
- The same item can be queued multiple times.
PRINT_ITEMS
- Prints a list of in-stock items (ItemNumber, Size, Title)
PRINT_CUSTOMERS
- Prints all customers and their current rentals -
all personal information (name, username, CC#, address, city, state, zip)
followed by all currently rented items (ItemNumber, Size, Title)
PRINT_USER
- Prints the queue for a particular user
- If username does not exist, display an error.
- If the user has no items in their queue, then leave the queue area blank.
PRINT_SORTED_CUSTOMERS
- Optional
- Prints a sorted list of customers and their current rentals -
all personal information (name, username, CC#, address, city, state, zip)
followed by all currently rented items (ItemNumber, Size, Title)
- Sorting is done based on username (ASCII sorting)
PRINT_LOG
- Optional
- Prints the transaction log for each user
- Prints the logs in same order as PRINT_CUSTOMERS
- If a user has no transactions, then leave the area blank or print an
appropriate message.
Data
Rental System
The Rental System manages the collection of Customers and in-stock items. You
may also have the Rental System manage other components according to your
design. However, for this project, your Rental System class MUST have at the
minimum:
- a collection of Customers
- a collection of items
Customers
Basic Functionality
Customers who rent items are essentially the same as in previous projects.
There are multiple customers allowed in the system. Extensions to the
representation of a Customer are described in the next section.
Customers each have the following information, you may represent these in
a variety of ways and are not limited to this exact representation:
- First name - sequence of any characters without spaces
- Last name - sequence of any characters without spaces
- Username - sequence of alphabetic, numerical, or the underscore ('_')
characters - each username is unique
- Credit Card number - sequence of digits
[0 - 9999999999999999], displayed as 16 digits
- Street Address - sequence of any characters with spaces
- City - sequence of any characters with spaces
- State - sequence of 2 characters (upper or lower) that match the 50 US
states
- Zip - sequence of digits [1000 - 99999], displayed as 5 digits
- Queue - a list of items the user would like to rent
- Rented List - a list of items the user is currently renting
Polymorphic Functionality
There are three different kinds of customers in the Rental System. Your
project must use Inheritance and Polymorphism to implement a Customer class
Hierarchy. Each kind of Customer has a unique cost associated with renting
their items as well as a unique limit to the number of items that they can
rent. Customers may not change types - once added to the system, they will
remain the same type of Customer.
Notice that all items in the rental system have the same
charges - so renting a DVD for a Basic customer costs the same as renting a
Book for a Basic customer. This is to simplify your code changes. If this
were the final production system, this simplification may or may not be
reasonable.
Your Customer class hierarchy should look essentially like this:
- Basic Customer - most basic deal
- Pays $.99 per disc/volume
- Limited to 3 items at a time
- Extended Customer - better deal
- Pays a flat fee of $1.99 each time they rent 1 or more items
- In addition, pays $.25 per disc/volume
- Limited to 5 items at a time
- Premium Customer - best deal
- Pays a flat fee of $3.99 each time they rent 1 or more items
- Limited to 10 items at a time
Items
Your Rental System must be template based in order to support objects of
various types. Your system need only support ONE of these types at a time.
You must modify your system to rent Books in addition to renting DVDs. Any type
that your system can support must support the following operations:
- Print the Item to an output stream
- Get the unique numerical identifier
- Get the Title
- Get the "size" of the item (for DVDs this is the number of discs, for
Books this is the number of volumes), this should be a generic method that will
work for both types (hint, hint)
Books
Books are very similar to DVDs, they have a title and a number, but instead of
a number of discs, they have a number of volumes. Multiple copies of the same
Book are allowed. It can be assumed that the first Book added to the system
has the correct Number of Volumes and Title information.
Books each have the following information:
- Book Number - unique identifier, sequence of digits [1 - 999999]
- Size (Number of Volumes) - sequence of digits that represent the number of
volumes in this book [1 - 100]
- Title - sequence of any characters with white space
You should take the maximum advantage of the similarities between Books and
DVDs in order to support your templated Rental System.
DVDs
DVDs are essentially the same as described in Project 1. Multiple copies of
the same DVD are allowed. It can be assumed that the first DVD added to
the system has the correct Number of Discs and Title information.
DVDs each have the following information:
- DVD Number - unique identifier, sequence of digits [1 - 999999]
- Size (Number of Discs) - sequence of digits that represents the number of
discs [1 - 100]
- Title - sequence of any characters with white space
Program Requirements
Templates
Your Rental System must be able to be created (using templates) to allow
creation of a "Rental System for DVDs" or a "Rental System for Books". Do not
attempt to support BOTH DVDs and Books within the same instance of a Rental
System (i.e. using some strange inheritance). Do NOT manually create two
different Rental Systems. You MUST use templates in your solution. There
should be no references to "DVD" or "Book" WITHIN the Rental System.
Obviously, your main() or auxiliary functions will at some point need to be
able to parse the command line, and then will need to know what kind of
Rental System you are creating. However, after that point in processing, there
should be no reason for your code to know the difference (hint, hint: how will
you create a new DVD/Book to add to the system using templates?).
Your application must support a second command line parameter indicating which
type of system the user would like to create, one with "DVDS" or "BOOKS". You
can assume that the capitalized version are the ONLY acceptable version of the
parameter. This command line parameter will follow the command-file name. If
some other command is supplied, the program should print an error and
terminate (unless you implement the extra credit as described).
Examples:
Proj5 command.txt DVDS
Proj5 command.txt BOOKS
Exceptions
Your application must also support throwing exceptions instead of simply
producing the error messages that are supported by your current system. You
MUST throw exception objects (not just ints, chars, bools, or strings) that
will be instantiations of your own exception classes.
All error conditions detected by your classes MUST result in the throwing of
an exception. All appropriate code must be containted in a "try block". All
exceptions must be caught where appropriate. All error messages that are
currently required to be printed (i.e. improperly formatted commands) must
continue to be printed.
All of your exception classes can (but don't have to) be in the same file (ex:
Exceptions.h and Exceptions.cpp). You are encouraged (but not required) to use
an inheritance hierarchy in defining your exception classes. You may design
your exception classes as elaborately or simply as your code requires.
Utility Class
You have been provided with a "Utility" class that has one static method that
you may use to correctly parse the command file. If you choose not
to use the Utility class, then you will have to rely upon the correctness of
your own implementation.
You can find Utility.o, Utility.cpp and Utility.h in the following location:
/afs/umbc.edu/users/d/a/dana3/pub/CMSC202/p5/
The one public method of the Utility class is:
static bool GetCommand(istream& sin, vector& command);
The GetCommand method makes the following guarantees:
- Returns true if the command was correctly formatted and the data was of
the correct type (digits versus strings)
- Returns false otherwise
- Parses the data, pushing each individual item onto a vector
- First item in the vector is the command name
- Each parameter to a command is a single entry in the vector
- Validates that all numbers are composed of digits
- Validates that the state in the address is one of the 50 states
- Validates the username by verifying that all characters are alphabetical,
numerical or the underscore ('_')
- Stock file is not read, nor tested for existence
- The state of the vector is undefined if GetCommand fails
- The command as read from the file will be printed to the standard output
stream
- Validates the Customer Type is one of the three acceptable
types.
There are constants for each command included in the Utility.h so you do not
have to declare those in your own code.
If you would like to have the Utility class throw exceptions - you must add
this functionality yourself (since everyone will have different exception
classes, it was unreasonable to add this as a standard feature).
Extra Credit
In order to be considered for the extra credit, you must submit a README file
to the graders describing what you did.
Supporting Arbitrary Costs - 10 pts
In general, a system like this should be able to support a variety of costs
for each of the objects. If a library wanted to adapt the system to support
book rental, then we should provide a facility for doing that. Also, objects
will differ substantially in their rental cost. For example, if we rent
Bicycles instead of DVDs, the cost should be significantly higher. Expand
your template to support arbitrary costs.
Your system should expand the Book class to support the following cost
structure:
- Basic Customer - most basic deal
- Pays $2.99 per disc/volume
- Limited to 2 items at a time
- Extended Customer - better deal
- Pays a flat fee of $5.99 each time they rent 1 or more items
- In addition, pays $.75 per disc/volume
- Limited to 8 items at a time
- Premium Customer - best deal
- Pays a flat fee of $7.99 each time they rent 1 or more items
- Limited to 15 items at a time
You should not include any code (other than the main() or auxiliary functions)
that know what type of object our Rental System stores. You must include all
of these values in the templated instantiation of a Rental System object (hint,
hint). You should NOT have two Books classes. Nor should your Books clas
have any logic that decides which instantiation it has. Use templates.
Your system will be tested using the following command line:
Proj5 command.dat BOOKS_EC
Your system must continue to function normally with the BOOKS parameter in the
normal test cases.
Supporting Arbitrary Types - 10 pts
In general, a system like this should be able to support a variety of objects.
Expand your template so that it supports additional types.
Any type that can be used in this system must have 3 components:
- Unique identifier - this can be any type of object and should be
parameterized in your template (i.e. could be a string, int, vector, ... any
type that supports all of the standard operators >>, <<, ==, <, etc.)
- Description - this must be a string
- Size - this must be an unsigned integer
Your program will be tested by supplying a third command-line parameter of a
type that represents the type of object that will represent the Unique
identifier. For simplicity - your code need only accept "STRING" and "INT".
In example:
Proj5 command.dat BOOKS INT
Indicates that we want a Rental System of Books that have an integer as their
Unique identifier. You can assume that the correct type will be supplied in
the command file. If this parameter is not supplied, then you can assume
whatever type your current system supports - this will support "backwards
compatibility" with the normal test suite. This should work for both Books
and DVDs with strings and ints. You can safely assume that all integer
identifiers will be positive. Do not worry about range-testing these
identifiers, you can assume they are all valid. You need only assume that the
operator==, operator<< and operator>> exist for the templated type.
Command File Requirements
The name of the command file will be read from the command line. You should
thoroughly test your program by developing your own command file. You do not
need to submit your command file. We will test your program using our own
command file(s).
Your program is required to repeat the command as read from the file. The
Utility class will take care of this for you, if you use it.
Commands
Please note that there have been minor changes to the command parameters.
Valid command keywords are all uppercase.
Valid commands for the system are as follows:
- OPEN <stock filename>
- CUSTOMER <first name> <last name> <username>
<card number> <customer type>
<address>
<city> <state> <zip code>
- RENT <username>
- RETURN <item number> <username>
- QUEUE <item number> <username>
- PRINT_ITEMS
- PRINT_CUSTOMERS
- PRINT_USER <username>
- PRINT_SORTED_CUSTOMERS [optional - old extra credit, will not be used]
- PRINT_LOG [optional - old extra credit, will not be used]
Command File Error Checking
- <customer type> must be one of the following strings:
"BASIC", "EXTENDED", or "PREMIUM". Each must be capitalized. The Utility
class will validate this for you.
- If a command is incorrect in any way (format or content), it shall be
discarded and processing of the command file shall continue. Must include
an error message.
- If a command cannot be executed (like queueing a DVD/Book for a non-existant
customer), a message shall be printed and processing of the command file
shall continue.
- Data must be validated. Utility takes care of this, mostly. Integer
ranges are not validated by Utility.
- Names, addresses, and other "word" based items, unless
specifically limited - they may contain any printable character.
- Printable characters are defined as any character that can be typed on the
keyboard. You need not validate these characters at all.
Sample Command File
Commands that have been tested and described in previous projects have been
left off of this example to eliminate clutter. However, your program must
still support the complete functionality of the system as described above.
OPEN stock.txt
CUSTOMER Fred Flintstone fflint0 1234123456785678 BASIC
123 Bedrock LN Apt. 7
Rock Vegas NV 12345
QUEUE 12345 fflint0
QUEUE 423644 fflint0
QUEUE 826918 fflint0
RENT fflint0
RETURN 12345 fflint0
RETURN 423644 fflint0
RETURN 826918 fflint0
PRINT_ITEMS
Stock File
You can assume that any stock file that we test with your program is
properly formatted and that all data is valid. You need not perform ANY
error checking on the stock file. The stock file represents all the items that
are currently "in-stock" (since the inventory is taken every evening).
For now, you will assume that another file processes the inventory every
evening and provides your system with an up-to-date copy of the stock every
morning.
Sample Stock File
12345 6 Harry Potter Collection
423644 1 Absolute C++
826918 3 Lord of the Rings Collection
759203 1 Timeline
927833 1 Ender's Game
32145 1 Chaos
928173 6 Hitchhiker's Guide to the Galaxy Anthology
General Requirements
- In keeping with course standards, main( ) will be implemented in a file
named Proj5.cpp.
- Prototypes for any helper functions called from main will be located in
Proj5Aux.h and the functions themselves implemented in Proj5Aux.cpp.
- Each class will be defined in a separate header (e.g. Customer.h) file
and implemented in a similarly named .cpp file (e.g. Customer.cpp).
- You must provide a makefile for this project which compiles and
links all files when the grader types
make Proj5.
- Your executable must be named Proj5.
Note that not all of the programming details have been spelled out for you.
For example, the rental system must keep track of which DVD is rented by whom,
but there's no indication about how that should be done.
This is intentional....you are required to give the project design
serious thought before writing code. Remember to think ahead to what might
be assigned in future projects and design your classes so that they are
easily modifiable.
Program Output
Your program's output must adhere to the following requirements:
- Customer credit card numbers must be displayed in the form
1234-5678-9012-3456.
- All monetary values must be displayed with 2 decimal places.
- When displaying a list of DVDs or customers, data must be aligned in
columns.
- Lists of DVDs/Books/customers shall be displayed in the order
DVDs/Books/customers were added to the rental system.
- As the stock file is processed, messages informing the user of each item
that is being added shall be displayed
For purposes of formatting output only, you make the following
assumption:
- The renter's first and last name total no more than 20 characters.
- The renter's username totals no more than 20 characters.
You must provide the makefile for this project. Use the makefile provided to
you for project 1 and modify it appropriately. If you don't change the
names of the files (much) from project 1, the changes will be minimal.
The make utility can also be used for compiling a single program without
linking.
For example, to compile Box.cpp, type make Box.o.
In addition to compiling and linking your files, make can be used
for maintaining your directory. Typing make clean will remove any
extraneous files in your directory, such as .o files and core files.
Typing make cleanest will remove all .o files, core, Proj5,
and backup files created by the editor. More information about these
commands can be found at the bottom of the makefile.
The grade for this project will be broken down as follows. A more detailed
breakdown will be provided in the grade form you receive
with your project grade.