CPE 101 Project 5

Objectives

UPC Receipt Calculator

You are to write a program that simulates a self-checkout style cash register with a bar code scanning device.  Imagine a grocery cart of items at a check-out stand.  Each item passed through the scanner returns a UPC code. Your program must take the list of UPC codes and produce the sales receipt.

Instructor Solution

The instructor has provided an executable program you can run to see the expected behavior of the finished program.
You can run the executable on Unix1 by typing the command:

~graderjd/Public/upc_calc.exe 

General constraints


Requirements


Input
The input data is a list of UPC's (including check digit).  Each line of input contains a 12-character string representing a UPC.  Input is terminated by EOF.
All the input data will be read before any output is produced.
There will be at most 500 data items.

Output
A list of products, including quantity and subtotal.
The total price of the entire purchase.
The total number of items purchased.
A list of invalid UPC's.
(The program does not display any prompts to the user.)

Functions
Read the list of UPC's.
For each UPC, verify the check digit, using the algorithm from the textbook (Chapter 7 Programming Problem 5) (image)(img).  If the verification fails, that means the scanner made an error reading the label, and that item is to be skipped and an error reported.

The instructor is providing a small "database" of UPC codes that you must use.  This "database" contains the UPC codes for all the products available for sale.  It isn't necessary for you to see the entire list, but an excerpt is provided below.  To lookup an item in the database, invoke the find_product() function defined in this library file:   upc_lib.h
The object file for this library is available on unix1:     ~graderjd/Public/upc_lib.o

Count the number of times each product appears.
Add the product price to a total (after converting it to an integer).
Display the products in the order they appeared in the input.
If there are any invalid UPC's, display them (also in the order they appeared in the input).  For each invalid item indicate the reason it was rejected:


Excerpt from database:
{"088270221332","Rainer Cherry Soda","1.09"},
{"000420200004","Twix 3.02OZ","1.29"},
{"880607148868","SAMSUNG GALAXY s2","678.23"},
{"075944869020","Kenneth Cole Reaction FAST CASH XL SHOES","242.22"},
{"081380201850","NORDSTROM RACK ivory skirt small","89.16"},
{"013556500009","bojolais village","24.55"},
{"089784300292","lighting","8.44"},
{"070462459937","l.e.i. lime green tank S","12.99"},
{"002021804308","Pantene hair solution 302 ml","9.75"},
{"088722379598","Nike shorts","23.32"},
{"003920897309","Brinks door lock","19.44"},

Sample Input
000420200004
000420200001
000420200004
088270221332
000420200004
088722379598
123123123125
000420200004
880607148868

Sample Output
	Purchases
Twix 3.02OZ                                         (  4)          5.16 
Rainer Cherry Soda                                  (  1)          1.09 
Nike shorts                                         (  1)         23.32 
SAMSUNG GALAXY s2                                   (  1)        678.23 
                                              TOTAL (  7)        707.80

	Invalid Items
000420200001 check digit doesn't match
123123123125 product doesn't exist in the database



Another Sample Output
	Purchases
Twix 3.02OZ                                         (499)        643.71 
Rainer Cherry Soda                                  (  1)          1.09 
                                              TOTAL (500)        644.80

Testing

It is recommended that you unit test your functions with checkit.

Grading

50%
application produces correct output for all instructor test cases.
15%
Program design is effectively decomposed into several small well-defined, special-purpose functions
15% Algorithm design uses structured logic for decisions and loops.
15% Coding standards are followed.
5% Clean compile and link (no warnings using the required compiler flags).

Remember, your program will be tested on Unix1.  Code that does not compile will receive a grade of zero.

Submitting Your Work

You need to submit your source code electronically using the   handin   utility: No late submittals will be accepted! 

  1. You may submit as many source code files as you like, but only one of them may contain a main function.
  2. The file containing the main function must be named upc_calc.c.
  3. Your files will be compiled with this command:   gcc -c -Wall -ansi -pedantic *.c
  4. Move the necessary file(s) to your Unix1 account using your favorite secure file transfer program.
  5. Log on to Unix1 using your favorite Secure Shell client program.
  6. Change directory (cd) to the directory containing your source file to hand in.  
  7. Be sure to compile and test your code on Unix1 using the required compiler flags ( -Wall -ansi -pedantic) one last time just before turning the files in.
  8. Submit your code using handin:
    handin graderjd Project5  upc_calc.c  (optional other files)



FAQ

Q: Do we have to write implement the .h file?
A: No, the instructor has already implemented it. On Unix1, you can link it directly with your object file (.o) with a command similar to this:
    gcc ~graderjd/Public/upc_lib.o upc_calc.o 

Q: Do we need to use strings in this assignment?
A: Yes, the UPC code, price and product name are strings.

Q: I'm confused about the check digit.  Are we checking the UPC number for the required number of digits or it is looking for a match in the database?
A: It's a two step process. First you verify the check digit. That is, perform the computation using the specified algorithm to see if the UPC is valid.  If it is valid, you can try to look it up in the database.  If it isn't in the database, the clerk in our IT department forgot to add the product to the database and the customer gets it for free.

Q: Are we allowed to use any library we choose?
A: You may use  stdio.h, strings.h, and optionally, stdbool.h.

Q: How do we reference the items in the database?
A: You can't.  There's no way for you to directly access the items in the database. You have to call find_product with a specific UPC and it will return that product if it exists.

Q: How does your program exit as it seems to be scanning for inputs, but just keeps scanning rather than stopping.
A: It uses an end-of-file loop. If you are experiencing that it "keeps scanning" during console use, it's because you haven't entered the end-of-file character. (pg625)

Q: If we are not given a complete list of valid upc's, how are we to check how many of each item there is, as I was planning on using an if statement for each item, with a separate variable being incremented for each one.
A: Nope, that approach won't work. I'm not going to post the answer because I want you to try to figure it out yourself. If you can't come up with a solution, see me for a hint.

Q: What purpose does the check digit serve and how would we test for just that, because even if a single digit is off, shouldn't the find_product function return an empty product?
A: The check digit serves to make sure the bar code scanned correctly. For example, if the label was damaged, the code won't scan properly. The check digit verifies that the sequence of digits is valid. We want to make sure we have a valid UPC before we look it up in the database.

Q: Why is the price stored as a string rather than a double? Wouldn't a double value be easier to use to store numbers?
A: As I've said many times in lecture, NEVER USE FLOATING POINT VARIABLES TO REPRESENT MONEY!!!. Yes, a double would be easier, but it would give THE WRONG ANSWER. A double is just an estimate, not an exact quantity.

Q: How can you do the check digit algorithm, which involves algebra, on the UCP, which is a string of characters?
A: You have to convert the characters into integers. A single character digit is converted into an integer like this:
     int num;
     char letter;
     num = (int)letter - (int)'0';
Process all the letters in a string by doing the above conversion in a loop.

Q: In lecture you said we don't need to use strcmp() on this project?
A: If I said that, I was mistaken. strcmp() will be helpful to see if a UPC matches one you've read in the past.

Q: How do I fix this link error?
gcc upc_calc.o upc_lib.o
upc_calc.o: In function `find_price':
upc_calc.c:(.text+0x257): undefined reference to `pow'
A: Try this:
 gcc -lm upc_calc.o upc_lib.o