Due date: TBD

Courtesy: This project was designed by Fawzi Emad at U.Maryland, College Park

1 Purpose

In this project you will write a program using structures and structures which contain other structures as members, arrays of structures, and functions with structure parameters, using both pass-by-value and pass-by-reference.

For this project we are imagining that you run a car repair shop. Your program will keep track of an inventory of parts, which will be used for repair jobs.

Your program begins by reading in an inventory of the parts you have in stock. Next it will read in your Repair Manual, which lists the repair jobs that you know how to perform, and specifies the parts that are required to complete each kind of job. Finally, it will read in a list of jobs that you are supposed to perform this day, and it will attempt to perform them. These jobs will only be performed if you have enough of the required parts in inventory. Of course the number of parts in your inventory must be reduced as each repair job is performed.

2 Project description

2.1 Program input

The input file will be divided into three portions: Initial parts inventory, Repair Manual, and Jobs to perform. A description of each of these sections of the input file appears below.

2.1.1 Initial parts inventory

The first portion of the input file contains a listing of parts that you have on hand. Each line contains an integer that represents the number of this particular part that you have, followed by the name of the part. At the bottom you will see ``11111'', which designates the end of the list. Below is the list which appears as the first section of the primary_input file:
2 engine
4 pcv valve
7 thermostat
8 valve cover gasket
2 engine
4 tire
4 throttle body inlet
6 starter
8 fuel pump
14 spark plug
7 intake manifold
6 pcv valve
2 clutch
3 exhaust manifold
4 valve cover gasket
4 radiator
15 fan belt
15 wheel bearing
4 tire
5 fuel filter
11 wheel weight
7 cv joint
23 cv boot
6 transmission mount
4 transmission filter
4 radiator
3 clutch
47 bolt
134 nut
51 washer
37 ignition wire
20 spark plug
14 brake caliper
60 washer
7 rotor
17 brake pad
3 master cylinder
4 compressor
3 evaporator core
2 expansion valve
17 oil filter
6 drain pan plug
23 oil, quart
17 grease, ounce
28 radiator fluid, gallon
33 brake fluid, quart
19 transmission fluid, quart
11111

Please notice that many items appear more than once on the list. Also notice that this list is not sorted in any way.


Assumptions:

2.1.2 Repair Manual

The middle section in the input file contains a list of repair jobs that you know how to perform. Each job has a name, followed by a list of the parts that must be used in order to complete that job. At the end of each job listed, you will see a line containing ``11111'' to designate the end of the list of parts for that particular job. After the last job, you will see two lines that look like ``11111'' to designate that we have reached the end of the entire repair manual. Below is the list of jobs (the repair manual) that is listed in the middle section of the primary_input file:
Oil Change
1 oil filter
1 drain pan plug
5 oil, quart
11111
Replace Transmission
1 transmission
1 transmission mount
12 bolt
6 transmission fluid, quart
11111
Replace Tires
4 tire
4 wheel weight
11111
Replace Fan Belt
1 fan belt
11111
Replace Engine
1 engine
12 bolt
5 oil, quart
1 pcv valve
1 throttle body inlet
4 bolt
4 washer
4 nut
4 grease, ounce
2 valve cover gasket
12 bolt
16 washer
8 nut
11111
Fix Brakes
4 rotor
4 brake caliper
8 brake pad
1 master cylinder
6 brake fluid, quart
16 bolt
16 nut
4 washer
11111
Tune Up
1 oil filter
1 drain pan plug
2 valve cover gasket
5 oil, quart
1 pcv valve
1 fuel filter
4 ignition wire
4 spark plug
6 transmission fluid, quart
3 radiator fluid, gallon
11111
11111

Notice that some of the parts listed may not be mentioned in the initial inventory list. Also there may be parts on the initial inventory list that are not mentioned in any of the jobs in the repair manual. The jobs listed are not sorted in any way, and the list of parts for each job is also not sorted. Note that the same part may appear more than once in the list for a particular job.


Assumptions:

2.1.3 Jobs to Perform

The third and final section in the input file contains a list of job names. These are the jobs that you have been asked to do this day. Below is the list of jobs that you will see at the end of the primary_input file:
Oil Change
Tune Up
Replace Transmission
Oil Change
Fix Brakes
Replace Engine
Oil Change
Replace Tires
Overhaul Engine
Replace Transmission
Notice that there may be jobs listed that were not listed in the repair manual. There may also be jobs listed in the repair manual that are not mentioned in this section. By the way, the same job may be listed in this section repeatedly. Also, please notice that there is no limit to the number of jobs that may be listed in this section, so you must process them one at a time rather than trying to read them all into an array and then process them. This section does not terminate with ``11111''.


Assumptions:

2.2 Data structures

You must follow the instructions in this section very carefully or you will lose a lot of credit for this project. You will define the following three structure types for use with this project. (You may also define others if you find them useful.) These structure types should be defined globally.

  1. Part structures have 2 members:
  2. PartsList structures have 2 members:
  3. Job structures have 2 members:

Important: Your inventory must be stored using a PartsList structure. Your Repair Manual must be stored using an array of Job structures.

2.3 A useful function

As you will read below, this project demands that you use functions effectively. As a big hint, we will mention one important function that you should write, and we will give an outline of how to implement it.

You should write a function that accepts two parameters: A PartsList, and a Part that we will call newPart. (You must decide whether to pass these parameters by value, or to pass them with a pointer.)

The role of the function is to add the part newPart to the list. We will do this in such a way that the elements in the list are always ordered alphabetically by name, and no name will appear more than once on the list.

As an example, imagine that newPart has the name ``brake caliper'', and the quantity 15. Here is how the function should try to add this part to the list:

  1. If the list is empty, then you should initialize the first element in the list to be a copy of newPart - i.e. set the name of the first element to ``brake caliper'' and set the quantity to 15. (The function should then terminate.)
  2. If a part already appears on the list with the same name as newPart (in this case ``brake caliper''), then you must add the quantity specified by newPart (15) to the quantity of the part of the same type that is already on the list. In other words, if you already have a part on the list with the name ``brake caliper'' and with quantity 4, then you should just increase the quantity of this part to 19. (The function should then terminate.)
  3. If the list already contains one or more parts, but none of them have the same name as newPart, then you must insert a copy of newPart into the list so that the names of the parts in the list are always ordered alphabetically. Since you will fill your PartsList structures with data by repeatedly calling this function, you may assume that the parts that are already on the list are sorted alphabetically. Therefore, to find the proper location for newPart, you should start at the beginning of the list and cycle through the parts until you find one that is alphabetically greater than newPart. This will be the spot where newPart must be inserted. All of the items on the list from this point to the end of the list must be moved over to make room for newPart. To move these elements over, first move the last one, then the next to the last one, and so on. After you have made room, copy newPart into the proper location. (In the event that newPart is the ``largest'' alphabetically, you do not have to move any of the existing members of the list - just add a copy of newPart to the end of the list.)

You may need to write some ``helper'' functions that will be called by this function. Don't forget that we still have that rule about having a maximum of 30 statements per function!

2.4 Processing and output

  1. Begin by reading in the initial inventory, and storing the data. Use the function described in the section above to add each part to the inventory list. The parts should be stored alphabetically by name, and no name should appear more than once on the list.
  2. Display the initial inventory list in the order it is stored. See the primary_output file, below, for the precise formatting.
  3. Read in the Repair Manual and store the data. The jobs should be added to the array of Jobs in the order that they appear in the input file. (The job names do not have to be alphabetical.) As you are reading the parts list for each job, use the function described in the section above to add each part to the list of parts required for the job. For any particular job, the parts in the list should be stored in alphabetical order (by name), and no name should appear more than once on the list.
  4. Display the Repair Manual in the order the jobs are stored. See the primary_output file, below, for the precise formatting.
  5. Print the line that says ``Time to fix some cars!'' (See the primary_output file, below, for the precise formatting.)
  6. Read in the list of jobs to perform, one at a time. After reading each job, perform the following actions:
    1. Check to see if you have a job by that name in your Repair Manual. If you don't, print the exact message: ``I do not know how to do this job.'' Then move on to the next job in the list.
    2. Cycle through the parts needed to complete the job. If you find a part that is not listed in your inventory, print the exact message ``I do not carry this item: %s'', where %s is the name of the part. If you find a part that is listed in your inventory, but the quantity in inventory is not sufficient, then print the exact message: ``I do not have enough of this item: %s'', where %s is the name of the part. You will print one message for each type of part that is lacking. Note that in the case where you originally had an item in stock, but the quantity of the item has been reduced to 0, you should print the message that says you do not have enough of the item, rather than the message that says you do not carry that item. If you do not have enough of one or more of the parts that are required for the job, then the job will not be attempted, so you should not decrease the quantities of any of the parts in your inventory.
    3. If you have enough of every part required for the job, print the exact message: ``Job Done!''. You must then subtract from the inventory the quantities of each part that were required to complete the job. For example, if the job lists ``8 bolt'' as a part, and you have 17 bolts in your inventory, then you must reduce the inventory to 9 bolts.

  7. After you have attempted to perform all of the jobs on the list, you must print the message ``Final Inventory'' and then display your final inventory. See the section regarding primary_output for the exact formatting requirements. In the event that the quantity of an item is reduced to exactly zero, you should no longer display that item when listing the inventory.

2.5 Primary Output

Below are the contents of the file primary_output. This will give you an idea about how your output must be formatted. As usual, it is important for you to check your output against ours using the diff command.

Starting Inventory:
===================
   47 bolt
   14 brake caliper
   33 brake fluid, quart
   17 brake pad
   5 clutch
   4 compressor
   23 cv boot
   7 cv joint
   6 drain pan plug
   4 engine
   3 evaporator core
   3 exhaust manifold
   2 expansion valve
   15 fan belt
   5 fuel filter
   8 fuel pump
   17 grease, ounce
   37 ignition wire
   7 intake manifold
   3 master cylinder
   134 nut
   17 oil filter
   23 oil, quart
   10 pcv valve
   8 radiator
   28 radiator fluid, gallon
   7 rotor
   34 spark plug
   6 starter
   7 thermostat
   4 throttle body inlet
   8 tire
   4 transmission filter
   19 transmission fluid, quart
   6 transmission mount
   12 valve cover gasket
   111 washer
   15 wheel bearing
   11 wheel weight

Repair Manual
=============

Oil Change
   1 drain pan plug
   1 oil filter
   5 oil, quart

Replace Transmission
   12 bolt
   1 transmission
   6 transmission fluid, quart
   1 transmission mount

Replace Tires
   4 tire
   4 wheel weight

Replace Fan Belt
   1 fan belt

Replace Engine
   28 bolt
   1 engine
   4 grease, ounce
   12 nut
   5 oil, quart
   1 pcv valve
   1 throttle body inlet
   2 valve cover gasket
   20 washer

Fix Brakes
   16 bolt
   4 brake caliper
   6 brake fluid, quart
   8 brake pad
   1 master cylinder
   16 nut
   4 rotor
   4 washer

Tune Up
   1 drain pan plug
   1 fuel filter
   4 ignition wire
   1 oil filter
   5 oil, quart
   1 pcv valve
   3 radiator fluid, gallon
   4 spark plug
   6 transmission fluid, quart
   2 valve cover gasket

Time to fix some cars!
======================

Attempting job: Oil Change
Job Done!

Attempting job: Tune Up
Job Done!

Attempting job: Replace Transmission
I do not carry this item: transmission

Attempting job: Oil Change
Job Done!

Attempting job: Fix Brakes
Job Done!

Attempting job: Replace Engine
Job Done!

Attempting job: Oil Change
I do not have enough of this item: oil, quart

Attempting job: Replace Tires
Job Done!

Attempting job: Overhaul Engine
I do not know how to do this job.

Attempting job: Replace Transmission
I do not have enough of this item: bolt
I do not carry this item: transmission

Final Inventory:
================
   3 bolt
   10 brake caliper
   27 brake fluid, quart
   9 brake pad
   5 clutch
   4 compressor
   23 cv boot
   7 cv joint
   3 drain pan plug
   3 engine
   3 evaporator core
   3 exhaust manifold
   2 expansion valve
   15 fan belt
   4 fuel filter
   8 fuel pump
   13 grease, ounce
   33 ignition wire
   7 intake manifold
   2 master cylinder
   106 nut
   14 oil filter
   3 oil, quart
   8 pcv valve
   8 radiator
   25 radiator fluid, gallon
   3 rotor
   30 spark plug
   6 starter
   7 thermostat
   3 throttle body inlet
   4 tire
   4 transmission filter
   13 transmission fluid, quart
   6 transmission mount
   8 valve cover gasket
   87 washer
   15 wheel bearing
   7 wheel weight

4 Developing your program

You may want to skip this section at first, read the rest of the project, and come back to study it carefully when you are about to begin writing your program.

The more you write individual functions to perform various manipulations on structures, the easier your code becomes to test. It is really recommended you use functions for each separate, discrete operation to be performed on any structure.

Here are some suggestions for possible functions. You do not have to use these, and you may use as many other functions as you want:


Do not use a global structure variable or array, like your book does in its example in Chapter 16! You will lose substantial credit if you use global variables in your project.

4.2 Program debugging

  1. Add lots of debug printf statements if your code isn't working, to find out where! You need to know this before you can find out why the problem is occurring.

  2. Draw lots of pictures of your structure types to trace exactly where things are in memory.

  3. If after you have tried these techniques, and tested each of your functions, you still can't figure out why your program doesn't work, bring a printout to our office hours, and we can help you learn how to track the problem down.

IT IS THE RESPONSIBILITY, UNDER THE UNIVERSITY HONOR POLICY, OF ANY STUDENT WHO LEARNS OF AN INCIDENT OF ACADEMIC DISHONESTY TO REPORT IT TO THEIR INSTRUCTOR.