Due: Fifth Week
Objective of this Program: (1) To learn about repetition in programs, i.e.,to keep on doing something until a condition is satisfied, (2) to start learning about modularization, i.e., breaking the program into smaller pieces, and to return values from a method, (3) to see how to get data into a program from a file, and (4) to use more complex decision making techniques.
This program is inspired by the cable company billing example on pages 217-223.
This program consists of calculating the bills for the We Spray Anything Company. They use planes to spray crops for a variety of problems. The rates they charge the farmer depend on what is being sprayed and how many acres one wants sprayed.
Furthermore there are discounts if the amount to be sprayed is sufficiently large or if the bill exceeds a certain amount.
We will be reading the data in from a file. Each line in the file will be a triple of numbers: (1) the ID number of the client, (2) a code for what is being sprayed, and (3) the number of acres being sprayed.
The main module will read in the data from a file. The name of the file is spraying.txt. You can get the input file of spraying.txt to test your program. One does the reading from a file the same way one does reading from the console window. To create the Scanner file to read in the pairs, one has the following two lines of code:
File input = new File("spraying.txt");
Scanner scan = new Scanner(input);
Then one uses the scan as one has used it before. E.g., one has
clientNumber = scan.nextInt();
to read in the next clientNumber.
Note: The input file should be in the same directory as your project. That is to say, when you have created the folder in which your project is to be created, you put the input file of spraying.txt inside this folder. Then you will need only the name of the file to be opened. If you put the file in a different place, you must either (1) give a complete path before the name of the file to find it, e.g., "C:\\datafiles\\spraying.txt" or (2) set up your path in your computer to find it.
Note: You must add the following to the line for the declaration of main:
public static void main(String [] args) throws IOException
This is in case the file can not be found for example. This is discussed on page 152-153 of the text, where the author throws the FileNotFoundException. The IOException if more general and includes all exceptions.
Write a program which will read in three pieces of data containing the following information:
clients id number, type of spraying requested (integer code 1-4), and number of acres to be sprayed (integer) E.G., 1003 3 950We will declare:
int clientNumber, //Client ID number type, //Type of billing //Type 1: Spraying for weeds, $1 an acre //Type 2: Spraying for grasshoppers, $3 an acre //Type 3: Spraying for army worms, $4 an acre //Type 4: Spraying for all of these, $6 an acre acres; //Number of acres to be sprayed double amountDue; //The amount due for the clientOne will continue to read in data until the client number of 0 is read in.
After reading in each triple, we will calculate the bill. Since the calculation of the bill is something which logically stands by itself, we will create a separate module calculateBill which will calculate the bill and return the amount. The line of code that does this is:
amountDue = calculateBill(type,acres);
We will print out on one line the client ID, type, number of acres, and the amount due. An example of what the output will look like is:
Client Number Type Acres Amount Due 1000 1 1200 $1140.00 1001 2 800 $2310.00
Note If there is bad input data, for example, the type does not have the values of 1-4 inclusive, calculateBill will return a negative value. In this case you should print out a "bad input data" for the amount:
1003 5 600 bad input data
After we have read in all of the relevant data, we will output the total amount billed for all of the clients in a separate line.
You will have a while loop to control the reading of data from the file. You will continue to read in data until the clientNumber value of 0 is read in.
After exiting the while loop, you will ouput a single line telling how much was due for all of the clients for this input file.
Note: Be sure to close your file before exciting the program. You do this with one line of code:
scan.close();
where scan is the name of the Scanner class with which we are reading in data.
The author gives you an example of how to get a $ in your output with cents on page 222 of the text. However, there is a Java API called NumberFormat which is better. The reason that it is better is that it formats the data depending on the local currency. That is to say, if one ran the same program in different countries, it would automatically put in the correct currency symbol without having to change the code. The Java API of DecimalFormat discussed on page 969-972 of the text is a special case of this API. You must import java.text.NumberFormat to use the NumberFormat.
You use the NumberFormat by the following. The line below is the declaration of the object fmt of the class NumberFormat:
NumberFormat fmt = NumberFormat.getCurrencyInstance();
The one gets the output with the dollar sign and cents with the following code:
fmt.format(amountDue)
If amountDue had the value of 3423.56789, the output generated by the fmt above would look like
$3,423.57.
However, if you ran the same program in France, it would look like
(euro symbol)3.423,57
In France, they reverse the use of "." and "," that we use. This is very useful in today's use of the Internet.
The protocol for this method is
public static double calculateBill(int type, int acres)
One should first check if the acres are negative. If so, then you should return a -1 (an error condition). The rates they charge the farmer depend on what he is spraying for and how many acres he wants sprayed according to the following schedule:
Type 1: Spraying for weeds, $1 per acre Type 2: Spraying for grasshoppers, $3 per acre Type 3: Spraying for army worms, $4 per acre Type 4: Spraying for all of these, $6 per acre
If the area to be sprayed is greater than 1000 acres, the farmer receives a 5% discount of his total bill. In addition, any farmer whose bill is over $1500, after the 5% discount for over 1000 acres, receives a further 10% discount on the amount over $1500. This 10% discount is taken even if the farmer does not have 1000 acres.
For each client, calculate the total cost to the farmer and return the total cost. Because we are taking percentages for discounts, the final bill be be in cents, so you should use a double to get the final cost. I.e., we have a calculation as .9*grossCharge, which means 90% of the gross charge (rate * acres).
To handle the different type to calculate the grossCharge , you can either use a nested if...else if..else if... (see pages 198-208) or the switch (see pages 208-215). The switch is cleaner, but use whichever you feel comfortable with.
Note: You should handle the case of bad input for the data of type. That is to say, if the input value of type is not a value of 1-4 inclusive, you should return a negative number to indicate bad data.
To check your program to see if it is working, the following inputs (hopefully correctly) calculate the amount due:
Input Amount Due 1000 1 1200 $1140.00 1001 2 800 $2310.00 1002 3 300 $1200.00 1003 4 1100 $5793.00 1004 3 783 $2968.80 1005 1 1550 $1472.50The calculations above are as follows, e.g., for account 1001, the gross charge is $2400 (3 * 800). One doesn't get the 5% discount for more than 1000 acres, but gets a 10% discount of the amount over $1500. So 2400 - 1500 is 900, so one gets a $90 discount.
For account 1003, the gross charge is $6600 (6 * 1100). Since one has more than 1000 acres, one receives a 5% discount, lowering his bill to $6270. Then the amount of the bill over $1500 is $4770, so one gets a $477 discount from the $6270, yielding $5793 as the final bill.
For account 1005, the gross charge is $1550 (1 * 1550). Since one has more than 1000 acres, one receives a 5% discount, lower the bill to $1472.50. The bill is now less than $1500, so there is no further discount.
Suppose that there is more than one bill per client. That is to say, the data would look like:
1000 4 5000 1000 2 500 1000 1 750 1010 1 8075 1010 2 550 1012 3 800 . .This means that there were 3 spraying jobs for client 1000 during the billing period, 2 jobs for client 1010, etc.
You are to read in the data as above, but the output is to be different. In the extra-credit, you are to output a line for each of the billing for client 1000, but then to give a total bill for client 1000. Then output the a line for each billing for client 1010, and then give a total bill for client 1010. Then give a line for each billing of client 1012, etc. Finally, one should output the total billing for all of the accounts.
You implement this with two loops, an outer loop and an inner loop. We call such a program a nested loop. A new customer's is detected by a change in account number. That is, when one gets a new transaction and it has a different account number than the account number of the account that one is now processing, one exits the processing loop (the inner loop) and then one outputs the total amount of this client. One then goes to the outer loop to check if this is the terminating account (it's account value is zero). If not, then one enters the outer loop and initializes the necessary data and start processing the data for the new account.
The end of data will be recognized by a sentinel account number 0.
The data for the extra-credit is sprayingextra.txt.
As with all of the extra-credits, there should be two projects to hand-in. The regular assignment and the extra-credit assignment.
You should post your project as a 'zip' file on the COL website. Also indicate how many hours you worked on the program in the Readme.txt file.
Homepage of CTI School
back to 211
homepage