PrintWriter creates file but doesn't print to file - java

This is a college course assignment that consists of classes TotalSales and TotalSalesTest.In the main program I have created a two dimensional array to output a columnar layout with cross-totals in 4 rows and 5 columns. This program outputs sales totals by row for each sales person(1 - 4) and output by column for products(1 - 5). I have created extra elements in the array to store total for rows and columns. So far both classes compiles. The problem is that although the PrintWriter creates a notepad file, it doesn't print to it. I could use some help on this problem. Here is the code`
//write program in a two diminsional array to output a columnar layout with cross-totals in 4 rows and 5 columns
//program outputs sales totals by row for each sales person(1 - 4) and output by column for products(1 - 5)
//create extra elements to store total for rows and columns
import java.util.Scanner;
import java.io.*;
public class TotalSales
{
private int salesPerson; //declare class variable
private int productNumber;//declare class variable
private double totalSales;//declare class variable
private double allSales;
//declare input and output variables
Scanner inFile; //declare inFile variable
PrintWriter outFile;//declare outFile variable
double[][]sales = new double[6][7];//declare array sales
public void initializer()
{
try
{
inFile = new Scanner( new File( "assign06.txt" ) );
outFile = new PrintWriter( "MonthlyTotalSales.txt" );
outFile.flush();
}
catch (FileNotFoundException e)
{
System.out.println("The input file could not be found!");
System.exit(1);
}
while(inFile.hasNext()) //while there is data to process…
{
salesPerson = inFile.nextInt();//reads salesPerson
productNumber = inFile.nextInt();//reads productNumber
totalSales = inFile.nextDouble();//reads totalSales
sales[salesPerson][productNumber]+=totalSales;
sales[salesPerson][6]+=totalSales;
sales[5][productNumber]+=totalSales;
allSales += totalSales;
} //end while loop
printDetails(sales);//call method printDetails
finishUp();//call method finishUp
}//end initializer
public void printDetails(double[][] array)
{
outFile.println("\t1\t2\t3\t4\t5");
for (int salesPerson =1; salesPerson <5; salesPerson++)
{
outFile.print(salesPerson+ " ");
for(int productNumber=1; productNumber <=array.length; productNumber++)
outFile.print(array[salesPerson][productNumber]+" ");
//end inside loop
outFile.println();
}//end outside loop
outFile.print("Total: \t ");
for(int salesTotal=1; salesTotal<array.length; salesTotal++)
{
outFile.print(array[5][salesTotal] +" ");
}
outFile.print(allSales);
outFile.println();
outFile.print(" ");
outFile.println();
}//end printDetails
public void finishUp()
{
inFile.close();
outFile.close();
System.out.println("The program has finished.");
}//end finishUp
}//end class TotalSales
Here is the test program:
public class TotalSalesTest
{
public static void main(String[] args)
{
TotalSales ts = new TotalSales();
ts.initializer();
}//end method main
}
Here is the text file for the input:
1 1 37.50
1 2 77.00
1 3 68.75
1 4 61.25
1 5 175.00
2 1 45.00
2 2 66.00
2 3 27.50
2 4 49.00
2 5 250.00
3 1 67.50
3 2 33.00
3 4 73.50
3 5 200.00
4 1 15.00
4 2 99.00
4 3 123.75
4 4 85.75
4 5 125.00
1 1 60.00
1 2 88.00
1 3 41.25
1 4 49.00
1 5 225.00
2 1 67.50
2 2 33.00
2 3 27.50
2 4 122.50
2 5 25.00
3 1 60.00
3 2 44.00
3 3 96.25
3 4 36.75
3 5 50.00
4 1 75.00
4 2 11.00
4 3 41.25
4 4 98.00
4 5 125.00
1 1 45.00
1 2 33.00
1 3 27.50
1 4 61.25
1 5 200.00
2 1 52.50
2 2 22.00
2 3 13.75
2 4 36.75
2 5 50.00
3 1 37.50
3 2 88.00
3 3 96.25
3 4 36.75
4 1 37.50
4 2 77.00
4 3 82.50
4 4 73.50
4 5 25.00
1 1 30.00
1 2 88.00
1 3 41.25
1 4 12.25
1 5 175.00
2 1 45.00
2 2 22.00
2 3 68.75
2 4 98.00
3 2 88.00
3 3 41.25
3 4 24.50
4 1 30.00
4 2 88.00
4 3 82.50
4 4 122.50
4 5 175.00

You call printDetails before initializing the writer... Move the printDetails call after outFile = new PrintWriter( "MonthlyTotalSales.txt" );and it should be fine. However, you should have included your constructor since as it is right now, I would think your code throws a NullPointerException because the writer is never initialized. You also need to close the file before writing in it, or at least you need to flush.
The whole structure of your code is bad, you should never have a method such as mainProgram on a class, you should never use a file as an attribute just to use it in every method, and you should never separate in different methods creation and closing of i/o classes.

It seems you didn't call outFile.close();
Call your finishUp() method once you complete writing in the file.

I think your program crashes with a nullpointer on
inFile.hasNext()
because you never actually opened or even instantiated the input file along with the output file in the try/catch block. Whoops!
change
try
{
outFile = new PrintWriter( "MonthlyTotalSales.txt" );
}
to
try
{
inFile = new Scanner(new File("Input.txt"));
outFile = new PrintWriter( "MonthlyTotalSales.txt" );
}

Related

Synchronized Thread in Java

I have 3 class like this:
Source.java
public class Source extends Thread{
private int x= 0;
public void increment(int id){
x++;
System.out.println(id+" "+x);
}
}
Task.java
public class Task extends Thread{
private Source source;
private int id;
public Task(Source source, int id){
this.source=source;
this.id=id;
}
public void run(){
for (int i=0;i<100;i++){
try{Thread.sleep(1000);}catch(InterruptedException e){}
source.inc(id);
}
}
}
Main.java
public class Main{
public static void main(String[] args) throws IOException{
Source source = new Source();
Task t1=new Task(source,1);
Task t2=new Task(source,2);
t1.start();
t2.start();
}
}
I want when the x of the class Source will be equal to 4 only one task continues to increment x until x is equal to 8, we return to normal.
The result will look like this:
1 1
2 2
1 3
2 4
1 5
1 6
1 7
1 8
1 9
1 10
2 11
1 12
2 13
...
How do I modify the code to achieve the desired result?
Basically you have two threads that modify the same variable x. There is no garantee about the order of execution.
You should synchronize.
With your current implementation you may face a problem (The race condition problem): Race condition example
Something like this is an scenario that most likely is going to happen to you:
....
1 3
2 4
2 5
1 6
1 7
2 7
1 8
2 9
1 10
2 10
...
As you can see the thread 2 (source 2) tries to increment the variable x when the variable has been already incremented but the value it has to increment is the old one.
x = 0
Thread 1 reads the variable x (0)
Thread 2 reads the variable x (0)
Thread 1 increments variable x + 1 (0 + 1) = 1
Thread 2 increments variable x + 1 (0 + 1) = 1
In order to solve this you need to synchronize your variable, an AtomicInteger would be enough. + I don't think you need the extends Thread on your Source class, you can get rid of it

HBASE filter by multiple values

I am having problems using filters to search data in hbase.
First I am reading some data from one table and storing in a vector or arrayList:
for (Result r : rs) {
for (KeyValue kv : r.raw()) {
if (new String(kv.getFamily()).equals("mpnum")) {
temp = new String(kv.getValue());
x.addElement(temp);
}
}
}
Then, I want to search a different table based on the values of this vector. I used filters to do this: (I tried BinaryPrefixComparator and BinaryComparator as well)
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE);
for (int c = 0; c < x.size(); c++) {
System.out.println(x.get(c).toString());
filterList.addFilter(new SingleColumnValueFilter(Bytes.toBytes("mpnum"), null, CompareOp.EQUAL, new SubstringComparator( x.get(c).toString() )));
}
I should get 3 results back, however I only get one result back, the first entry in the database.
What doesn't make sense is that when I hardcode the value that I am looking for into my code, I will get all 3 results back.
I thought there might be some issue with converting the bytes to String and then back to bytes, but that would not explain how it was able to bring back the first result. For some reason, it is stopping at the first match and doesn't continue to find the other 2 rows that contain matching data. If I hardcode it i get the results:
x.addElement("abc123");
filterList.addFilter(new SingleColumnValueFilter(Bytes.toBytes("mpnum"), null, CompareOp.EQUAL, new SubstringComparator( x.get(0).toString() )));
Does anyone know what the problem is or what I need to do to resolve my issue? Your help is much appreciated.
Thank You
edit: Here is the contents of the tables:
TABLE1:
ROW COLUMN+CELL
0 column=gpnum:, timestamp=1481300288449, value=def123
0 column=mpnum:, timestamp=1481300273355, value=abc123
0 column=price:, timestamp=1481300255337, value=85.0
1 column=gpnum:, timestamp=1481301599999, value=def2244
1 column=mpnum:, timestamp=1481301582336, value=011511607
1 column=price:, timestamp=1481301673886, value=0.76
TABLE2
ROW COLUMN+CELL
0 column=brand:, timestamp=1481300227283, value=x
0 column=mpnum:, timestamp=1481300212289, value=abc123
0 column=price:, timestamp=1481300110950, value=50.0
1 column=mpnum:, timestamp=1481301806687, value=011511607
1 column=price:, timestamp=1481301777345, value=1.81
13 column=webtype:, timestamp=1483507543878, value=US
3 column=avail:, timestamp=1481306538360, value=avail
3 column=brand:, timestamp=1481306538360, value=brand
3 column=descr:, timestamp=1481306538360, value=description
3 column=dist:, timestamp=1481306538360, value=distributor
3 column=mpnum:, timestamp=1481306538360, value=pnum
3 column=price:, timestamp=1481306538360, value=price
3 column=url:, timestamp=1481306538360, value=url
3 column=webtype:, timestamp=1481306538360, value=webtype
4 column=avail:, timestamp=1481306538374, value=4
4 column=brand:, timestamp=1481306538374, value=x
4 column=descr:, timestamp=1481306538374, value=description
4 column=dist:, timestamp=1481306538374, value=x
4 column=mpnum:, timestamp=1482117383212, value=011511607
4 column=price:, timestamp=1481306538374, value=34.51
4 column=url:, timestamp=1481306538374, value=x
4 column=webtype:, timestamp=1481306538374, value=US
5 column=avail:, timestamp=1481306538378, value=
5 column=brand:, timestamp=1481306538378, value=name
5 column=descr:, timestamp=1481306538378, value=x
5 column=dist:, timestamp=1481306538378, value=x
5 column=mpnum:, timestamp=1482117392043, value=011511607
5 column=price:, timestamp=1481306538378, value=321.412
5 column=url:, timestamp=1481306538378, value=x.com
THIRD TABLE (to store result matches)
0 column=brand:, timestamp=1481301813849, value=name
0 column=cprice:, timestamp=1481301813849, value=1.81
0 column=gpnum:, timestamp=1481301813849, value=def2244
0 column=gprice:, timestamp=1481301813849, value=0.76
0 column=mpnum:, timestamp=1481301813849, value=011511607
**should be three matches those that are in bold above but only brings back one match
If anyone is willing to help for a fee, send me an email at tt224416#gmail.com

Creating a Call Simulator

The number of calls received per minute at a Help Desk has been estimated to be between 5 and 10.
Write a simulation program that simulates calls arriving at the Help Desk for a period of 12 hours and output the frequency of calls during this period.
Sample output:
(Note: The frequencies for your program will be different from the ones shown below. Each time you run your program, you should get different frequencies)
Calls/Minute Frequency
5 155
6 172
7 148
8 123
9 62
10 60
This is what I've came up with, but cannot figure out how to split/leave a gap between calls/minute and frequency. Basically splitting it into two rows.
import java.util.Random;
public class randomCalls {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Random rn = new Random();
int n;
for(int i=1;i<=6;i++)
{
n = rn.nextInt(6) +5;
System.out.println("Calls/Minute" +"\n" + n);
System.out.print(' ');
System.out.println(" Frequency" + "\n"+ i);
}
}
}
I'm pretty sure you are trying to print out Calls/Minute and Frequency in columns. Here is a helpful link.
In order to use that method your need to...
Combine the lines System.out.println("Calls/Minute" +"\n" + n); and System.out.println(" Frequency" + "\n"+ i);, and format the resulting single line so that it is split into two columns.
//Example
System.out.printf("%-12.30s %-30.30s%n","Column 1","Column 2");
Place it BEFORE your for loop (or else it will print every time)
Within your for loop, format your output exactly the same as you did the line in step one.
//Example
System.out.printf("%-12.30s %-30.30s%n",n,i);
Sample output in your program would look like this:
Calls/Minute Frequency
6 1
7 2
8 3
8 4
9 5
6 6
Here is how I got it to print like described:
Random rn = new Random();
int n;
for(int i=1;i<=6;i++) {
n = rn.nextInt(6) +5;
System.out.println( n + " " + i );
Hope this helps!

External file with multiple numbers per line Java

I need help reading an external file that has more than one number per line. Here is the external data file:
1 1
2 3
3 5
4 7
5 2
6 4
1 6
2 8
3 1
4 3
5 5
6 7
1 8
2 1
3 2
4 3
5 4
6 5
I read it in by using
public class Prog435a
{
public static void main(String[] args) throws IOException
{
Scanner kbReader = new Scanner(new File("C:\\Users\\Super Mario\\Documents\\java programs\\Prog435\\Prog435a.in"));
while(kbReader.hasNext())
{
int data = kbReader.nextInt();
System.out.println(data);
}
}
}
However, it prints out the file with each number line by line. So instead of appearing in columns, it appears in a single column. How can I get this to print out in two columns as shown above? Thanks for the help.
Loop by line. Call nextInt() two times per line.
while(kbReader.hasNextLine()) {
System.out.println(kbReader.nextInt() + " " + kbReader.nextInt());
}

I am trying to create an array using data from a file

This is what I have so far....
/**
* #param args
*/
public static void main(String[] args) {
final String DATA_FILE = "payroll_problem.txt";
Scanner scan = null;
try
{
scan = new Scanner(new File(DATA_FILE));
}
catch (FileNotFoundException e)
{
System.err.printf("Could not open file \"%s\".\n", DATA_FILE);
}
int [] arr = new int[scan.nextInt()];
for(int i = 0; i < arr.length; i++)
{
arr[i] = scan.nextInt();
System.out.print(arr[i]);
}
scan.close();
}
I keep getting error code
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at fvse.main(fvse.java:22)
The five ints stand for how many hours the person has worked from Monday-Friday. Here is the data file.
Mohnan Maria 8 8 8 9 8 10.01
Blue Shelly 8 10 8 8 6 10.00
Black 8 8 8 8 8 23.0
Fortuna Jorge 5 5 5 5 5 10.10
Jones Mitchel 10 5.5 10 10 10 15.05
Olafson Sven 10 10 10 10 10 10.00
Cruz Astrid 1 1 1 1 1 20.50.3
Adler Irene 10 12 8 8 8 22.50
The problem happen because you call scan.nextInt() but your input file actually contains string/characters.
Either add the integer indicating the number of lines on the top of your input file, or change your code read by line (eg: using BufferredReader.readLine())
If you choose the former, make sure you also read the first and last name using two invocation of scan.next()
You are reading your file for integers, but more than likely that file is filled with strings or characters.
Edit: Try scanning for lines or characters, or just using a FileInputStream, and then parsing the data once it's been loaded in.
Edit: Now that i've seen your data file, I would read in the file using standard file input practices (check out http://www.javapractices.com/topic/TopicAction.do?Id=42 if you need a tutorial on that). Then split the string based on spaces, and go through each string in your new string array and handle the data. The first 2 strings being names, and then integers until you get another name, or the end of the string.

Categories

Resources