In this assignment you are going to help Kitty City, a new startup cat supply company, to create an online ordering system. The customer interacts with your program to order cat food, cat litter, and cat toys. Once the order has been placed, the customer specifies the desired monthly payment, and the program reports the total amount that will be owed (original cost plus interest) and the number of monthly payments needed to pay the balance.
overview
Kitty City wants to establish an online presence, but they're not quite ready to create a web site. Instead, they want you to create a simple text-based prototype of an order entry system so they can experiment with this new world of computers. (They're not exactly ahead of the curve, but that's not your problem.)
The program should interact with the customer to accumulate an order, then calculate the total amount owed (cost of goods plus interest) based on the monthly payment the customer chooses. These two parts of the task are largely independent.
The easiest way to understand how the program should work is to experiment with the sample executable version. Your program does not need to produce exactly the same messages or use exactly the same output format, but it must use the same input commands (character codes) and accept input in the same way that the sample program does. (This allows us to automate some of the testing on submitted homework.)
There are two versions of the sample program. The basic one operates the same as the program you are supposed to write. The other version of the sample program prints payment details. Your program does not need to do this, but the extra information is useful in understanding how payments are calculated.
Input to the first part of the program is a sequence of single-character commands that affect the customer's order. The program should process the following commands.
Command | Meaning |
a or A | add item(s) to order |
d or D | delete item(s) from order |
c or C | proceed to checkout (next part of program) |
q or Q | quit immediately without ordering |
If the code is A or D (either upper- or lower-case), the program should read another single-letter code that specifies the product and an integer specifying how many of the specified product to add to or delete from the order. The program should handle the following products and product codes.
Code | Product | Price per item |
f or F | Cat Food | $3.50 |
l or L | Cat Litter | $2.20 |
t or T | Cat Toy | $4.00 |
The program should check for unknown command and product codes. If the customer enters an unknown command or code, the program should print an appropriate message and skip to the next command. If the quantity ordered of any item is negative or if the user deletes more items than have been ordered, the program doesn't need to report that immediately. However, when the user tries to proceed to checkout (c or C command), the program should print an appropriate error message if any quantity is negative and not proceed to checkout until the user has fixed the problem by adjusting the order, i.e. by adding items of which there are negative quantities.
After each command has been entered, the current contents of the customer's order should be printed showing how many of each item have been ordered, the costs of the items ordered, and the total cost of the order.
Once a customer has completed an order, they can enter C (or c) to proceed to checkout. This next part of the program calculates payment information in essentially the same way any real credit card purchase is processed.
Monthly payment. The program should first calculate and print the minimum allowed monthly payment. The minimum payment is 2.0% of the total amount of the order, however, it should be at least $3.00. There is one exception to the $3.00 rule: If the total amount of the order is less than $3.00, then the minimum payment should be the total amount of the order.
After calculating the minimum payment, the program should ask the customer to enter the desired monthly payment. If the amount entered is less than the minimum, the program should ask for a new amount and continue until the customer enters an amount that is at least as big as the minimum payment.
Total paid and number of payments. Once the customer enters the desired monthly payment, the program should calculate the total amount the customer will have to pay (amount of the order plus monthly interest) and the number of payments needed to pay for the order. This must be calculated by writing an appropriate loop to compute the interest and principle paid, and balance remaining, one monthly payment at a time. This calculation should be repeated until the entire balance is paid. Inside the loop, the total amount paid should be computed by adding up the payments. After the loop terminates, the total paid and number of payments (including any partial final payment) should be printed.
The rules for calculating interest and crediting the monthly payment are the same as for a typical bank credit card:
There is no interest charge on the first payment. The entire amount is credited towards the balance owed.
On the second and all later payments, a monthly interest charge of 1.5% of the remaining balance is collected by the bank. The leftover money (monthly payment minus interest) is used to reduce the balance owed.
All payment calculations should be correctly rounded to the nearest penny ($0.01).
Example. Suppose the customer
orders $110.00 in merchandise and chooses to pay $10.00 per month. The
first payment reduces the balance owed to $100.00 and there is no interest
charge. On the second payment, there is an interest charge of $1.50 (1.5%
of the remaining $100 balance). So $1.50 is collected by the bank, and $8.50 is
credited towards the balance, leaving a balance of $91.50 after the second
payment. On the third payment, the interest charge will be 1.5% of the
$91.50 balance, and whatever is left of the $10.00 payment will reduce the $91.50 owed, and so forth.
implementation notes
If you run the sample program, you'll see that it reads and writes monetary
amounts in the usual dollars-and-cents notation (input 17.42, output either
17.42 or $17.42). Most of the time when one is dealing with numbers that
have decimal points, the natural representation is type double
(floating-point). However, remember that floating-point arithmetic
operations are not exact and can produce results that are very slightly
different from the true answer.
For most uses of floating-point numbers this is not a problem. But it is a problem if the numbers being stored should be exact, which is precisely the situation we have here: all calculations are supposed to be exact to the penny.
To avoid round off errors, we strongly suggest you store monetary
amounts as integer values containing the amount in pennies, not dollars.
So $17.42 should be represented as the int
value 1742
.
Although we want to store money as integers, it is
much easier to read and write dollars-and-cents values as
double
s, and let scanf
and
printf
handle the decimal points. Things will work fine
if you read money as a double
, then immediately multiply
the amount by 100, then cast the product to an integer.
For output, divide by 100.0 and print the result with
two decimal digits. If pennies
, for example, contains
4217, the following code will produce the output
$42.17
.
printf("$%.2f", pennies/100.0);
The starter program for this assignment also includes a function
that you may find useful in your calculations. The result of round(d)
,
where d
is a double
, is the nearest integer to d
,
properly rounded.
For this assignment you need to read various
single-character commands and codes. When scanf
is used
to read numbers (int
or double
), it skips
past any leading white space (blanks, tabs, newlines, and so forth)
that it encounters before it gets to the number. However, when you
use scanf
to read a character (%c
format),
it reads the very next character it finds, even if it is blank.
To make reading single characters easier, the starter
program contains a function read_nonblank()
. When it is
executed, it reads through the input one character at a time, skipping
white space. When it encounters a non-blank character, it stops
reading and returns that non-blank character to the caller. Call this
function to read the various command and code characters.
This program is a bit larger than the ones written for earlier assignments. While no one part of the program is overly complicated, the overall project is complicated enough that you need to take some time to get organized before you start coding.
Use functions to break the project down into manageable parts. Your program should be made up of several relatively small functions, not one or two huge blobs of code. Most functions should fit on a single screen, or, at most, a single printed page. If you find that you have a huge function, take a look to see if it is doing several different things, and, if so, break it up into several different functions, each of which does one thing well.
The assignment is designed so that the program has two relatively independent parts that can be worked on one at a time. One of these is the order entry part, where the customer interacts with the program. The other is the section that calculates the monthly payment, total paid, and number of payments. The only connection between these two parts is a single number: the total cost of the order. So you should be able to work on these parts one at a time. Be on the alert for ways to break these parts down into smaller functions that can be written and tested individually.
As you design the program, you should think about how you're going to test it. Try to identify parts of the program that can be tested by themselves before other parts are added. You may find it helpful to temporarily change the main program to call some of your functions with appropriate test data to verify that those functions are working. The key idea is to create a small, working program first, then add to it gradually, checking things as you go, until you have implemented everything.
Remember to use good style: use #define
constants instead of magic
numbers; use indenting and blank lines to make the text easy to follow; pick good variable, parameter, and function names;
include appropriate
comments; and so forth.
An interactive debugger is a code development tool that, loosely speaking, lets you slow down time (make it stop, even) and see inside the program as it's executing. More precisely, it allows you to run your program a few statements at a time, observe the values of variables, and even make temporary changes in the middle of execution. A good interactive debugger is an invaluable tool for finding problems and verifying that a program works.
The basic technique is to execute your program a bit at a time, stopping to verify that everything is working as expected - variables have the correct values, statements are executing in the order you expect, and so forth. MSVC, as is true of many systems, has a good interactive debugger that allows you to set "breakpoints" - locations in the code where you want to pause during execution. When execution is paused, you can examine the values of variables, run your program one statement at a time, set or remove additional breakpoints, and resume execution. You can find more hints about the MSVC debugger on a separate web page linked here, and you may well want to attend a debugger demonstration/tutorial in the IPL.
For this assignment we would like you to try using the debugger. To encourage this, you must turn in a printout showing the debugger in action. Your program for this assignment should include a loop to calculate interest and totals for the monthly payments. Once you've written this part of the program, use the debugger to watch the loop execute. Place a breakpoint at the beginning of the loop. Run your program until it gets to the loop. Then step through or run the program until the loop body has executed twice and is ready to start the third iteration. Make a printout of the screen at that point (more information below) showing the debugger windows with the source code, the values of local variables, and so forth. Include this printout with your written receipt when you hand in your assignment. Be sure your name and section number are included on the printout (visible on the screen at the time you make the snapshot) or written in by hand.
The details for printing a snapshot of the screen are slightly different, depending on which version of Windows you are using. With Windows NT, which is installed in the IPL, you can capture and print a snapshot of the screen as follows:
If you are not using Windows, you should submit a screen snapshot using the debugger included with your development environment or run the MSVC debugger on your code in the IPL and submit a Windows snapshot.
(Macintosh users: Press Apple/Command-Shift-3 to save a screen snapshot to your default hard drive. You should hear the "shclick" of a camera shutter when you do this, if you have your sound volume up.)
As always, be sure to read the homework submission guidelines, linked on the course home page in the Announcements section. You will have to submit your work (1) via the web using the page linked below and (2) on paper. The paper copy should include both your turn-in receipt and the printout showing the screen snapshot of the debugger.
self-extracting archive, including starter C file
hw3.exe - sample executable
hw3opt.exe - modified sample executable with extra debugging output
If any clarifications or changes need to be made for this homework, they will be posted to the cse142-announce email list and linked here.
Save paper. Read documents on the web and, if you must print, print two-sided. Recycle me when you're done.