Issue Reading from text file - java

I am trying to create a program in Java that calculates the average cost of winning the lottery and saves that average to reference when it runs again (my goal is to be able to create a more accurate outcome every time i run it). The average successfully saves to my txt file, but when I run the program it uses 0 as the previous average every time. Any help is greatly appreciated! Thanks!
(Number of times it runs can be changed by changing the 'runs' variable)
public class WinningTheLottery
{
public static final int SIZE = 5;
public static void main(String[] args)
{
int[] winningNums = new int[SIZE];
int[] guessNums = new int[SIZE];
int spent, runs = 1;
double oldAvg = 0;
double newAvg;
int totalSpent = 0;
NumberFormat currency = NumberFormat.getCurrencyInstance();
try
{
Scanner fileScanner = new Scanner(new File("average.txt"));
PrintWriter fileWriter = new PrintWriter(new File("average.txt"));
while (fileScanner.hasNextDouble())
{
oldAvg = fileScanner.nextDouble();
}
for (int i = 0; i < runs; i++)
{
spent = 0;
randomlyAssignedNumbers(winningNums);
// Arrays.toString(nameOfArray) => built in method to print an array
System.out.println("\n[" + (i+1) + "] Todays winning numbers:\n" + Arrays.toString(winningNums).replace("[", "").replace("]", ""));
do
{
randomlyAssignedNumbers(guessNums);
spent++;
} while (howManyCorrect(winningNums, guessNums) < 5);
System.out.println("After spending " + currency.format(spent) + ", you won the Fantasy 5 lottery $75,000 prize!");
totalSpent += spent;
}
newAvg = ((totalSpent/runs) +oldAvg)/2;
fileWriter.println(newAvg);
System.out.println("\nAverage Cost to win the Lottery: " + currency.format(newAvg)
+ "\n(Previous Average: " + currency.format(oldAvg) + ")");
fileScanner.close();
fileWriter.close();
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
public static void randomlyAssignedNumbers(int[] anyArray)
{
Random rng = new Random();
for (int i = 0; i < anyArray.length; i++)
{
anyArray[i] = rng.nextInt(36) + 1;
}
}
public static int howManyCorrect(int[] a1, int[] a2)
{
if (a1.length != a2.length)
return -1;
int count = 0;
for (int i = 0; i < a1.length; i++)
{
if (a1[i] == a2[i])
count++;
}
return count;
}
}

Your code is opening the file in overwrite mode, default of many programming languages, before scanner can read the content, thus deleting the content before fileScanner.hasNextDouble() read. Move your PrintWriter instantiation after Scanner read, and it will work.
Note: To open the file in append mode, which I don't think you need here. But in Java you use new FileWriter("average.txt", true) and then wrap a PrintWriter around it.

Try not constructing the PrintWriter until after you read the previous value. As noted in the Javadoc the file will be truncated by creating the PrintWriter.

Related

Creating triple-ended queue with efficient random access

I have been tasked to solve a question concerning the creation of a triple-ended queue with efficient random access, as outlined in this: https://open.kattis.com/problems/teque. I created a program based around using 2 very large arrays, one containing the front half of all stored integers so far and the other the back half, with both being of the same size or the front half containing at most 1 more element than the back half after every insertion operation. This should allow all insertion and retrieval operations to be of O(1) time complexity, but the code just keeps exceeding the given time limit. Can anyone tell me what is wrong with my code? Here it is:
import java.util.*;
import java.io.*;
public class Teque3 {
static int[] front = new int[1_000_000];
static int[] back = new int[1_000_000];
static int frontHead = 499_999;
static int backHead = 499_999;
static int frontSize = 0;
static int backSize = 0;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
for (int i = 0; i < n; i++) {
String[] line = br.readLine().split(" ");
if (line[0].equals("get")) {
int index = Integer.parseInt(line[1]);
if (index >= frontSize) System.out.println(back[backHead + index - frontSize]);
else System.out.println(front[frontHead + index]);
continue;
}
if (frontSize == backSize) {
if (line[0].equals("push_front")) {
frontHead--;
front[frontHead] = Integer.parseInt(line[1]);
frontSize++;
} else if (line[0].equals("push_back")) {
back[backHead + backSize] = Integer.parseInt(line[1]);
front[frontHead + frontSize] = back[backHead];
frontSize++;
backHead++;
} else if (line[0].equals("push_middle")) {
front[frontHead + frontSize] = Integer.parseInt(line[1]);
frontSize++;
}
} else {
if (line[0].equals("push_front")) {
frontHead--;
front[frontHead] = Integer.parseInt(line[1]);
backHead--;
back[backHead] = front[frontHead + frontSize];
backSize++;
} else if (line[0].equals("push_back")) {
back[backHead + backSize] = Integer.parseInt(line[1]);
backSize++;
} else if (line[0].equals("push_middle")) {
backHead--;
back[backHead] = Integer.parseInt(line[1]);
backSize++;
}
}
}
}
}
You could try to minimze IO-Operations: Collect your programm output. Instead of writing System.out.println better create a new StringBuilder to collect everything. In the end write all at once.
static StringBuilder result = new StringBuilder();
...
private static void result(int value) {
result.append(value).append("\n");
}
...
if (index >= frontSize) result(back[backHead + index - frontSize]);
else result(front[frontHead + index]);
...
System.out.println(result);
Decouple read from parse and process: Create one thread for reading the operations. But the operations in a Queue. Start another thread for the process.

how do I use insertion sort on a 2D array?

So, I made this code almost work, but I want to use insertion sort on the array and for the output to display results sorted by product ID only by insertion sort. Each product ID should have the same corresponding number of units. The units should not be sorted independently. The only order would be by product ID is what I'm basically implying.
import java.util.*;
import java.io.*;
class newversion {
public static int [][] table; // the output table
public static int numOfRows; //number of rows used up in the table
public static int lookfor(int productID){
int location = -1; //-1 an error
for(int i = 0; i < numOfRows; i++){
if (table[i][0] == productID){
location = i;
}
}
return location;
}
/*
here is my modified bubble sort code. I based it on this, but done differently:
http://stackoverflow.com/questions/23283655/bubble-sort-on-2d-array-java
public static void swap(int int1, int int2, int[] array) {
if(int1 == int2){
return;
}
else{
int temp = int2;
array[int2] = array[int1];
array[int2] = temp;
}
}
but it didn't work and I had to try something else
*/
public static boolean contains(int productID){
if (lookfor(productID) == -1){
return false;
}
return true;
}
public static void main(String[] args) {
File file = null;
Scanner scanner = null;
try{
file = new File("data.csv");
scanner = new Scanner( file );
}
catch(Exception e){
System.out.println("Error opening file!");
System.exit(1);
}
//citation of idea for sorting method in 2D array: http://stackoverflow.com/questions/23283655/bubble-sort-on-2d-array-java
//I'm using bubble sort on a 2D array
//this is his code
/*
private static void bubblesort(Integer[] array) {
for (int i = 0; i < array.length; i++) {
for(int j = 0; j < array.length - 1; j++) {
if(array[j].compareTo(array[j+1]) > 0) {
swap(j, j+1, array);
}
}
}
}
private static void swap(Integer int1, Integer int2, Integer[] array) {
if(int1 == int2)return;
Integer temp = new Integer(array[int2]);
array[index2] = array[int1];
array[int1] = temp;
}
*/
//here's my idea for bubble sort on a 2D array
/*
for (int i = 0; i < numOfRows; i++){
for(int j = 0; j < numOfRows - 1; j++) {
if(table[j][0].compareTo(array[j+1][0]) > 0) {
swap(j, j+1, table);
}
}
//this didn't work well either
//Now, I have to try another for-loop
*/
//Count the number of lines in the file
int size_of_file = 0;
while (scanner.hasNextLine()){
scanner.nextLine();
size_of_file++;
}
table = new int[size_of_file][2];
//reset scanner
try{
file = new File("data.csv");
scanner = new Scanner( file );
}
catch(Exception e){
System.out.println("Error opening file!");
System.exit(1);
}
//save the title
String titleLine = scanner.nextLine();
System.out.println(titleLine);
//for each line in the file, store and total it.
numOfRows=0;
while (scanner.hasNextLine()){
String ln = scanner.nextLine();
String[] row = ln.split(",");
System.out.println(row[0] + ", " + row[1]);
if (contains(Integer.parseInt(row[0]))){
//This is the location in the table where the product id exists already.
int location = lookfor(Integer.parseInt(row[0]));
//add the units to what we have in the table
table[location][1] += Integer.parseInt(row[1]);
}
else{
table[numOfRows][0]= Integer.parseInt(row[0]);
table[numOfRows][1]= Integer.parseInt(row[1]);
numOfRows++;
}
}
//output
try{
PrintWriter output = new PrintWriter("output.csv");
output.println(titleLine);
for(int i=0;i<numOfRows;i++){
output.println(table[i][0] + "," + table[i][1]);
}
output.close();
}
catch(Exception e){
System.out.println("Error writing file");
}
}
}
I want to understand how to use FileReader better. I read a little bit about it here:
https://www.caveofprogramming.com/java/java-file-reading-and-writing-files-in-java.html
https://bytes.com/topic/java/answers/585814-reading-data-into-array-file
Although I don't think I understand from that how to store it into an array. Could someone explain how I can store values from FileReader class into an array? I want it in a 2D array where the number of rows is just however many product IDs I have and there is always 2 columns.
Excel File to read from:
Product ID Units
10002 4
10004 6
10008 2
10010 3
10010 3
output I get right now:
Product ID Units
10002 20
10004 72
10008 12
10010 37
10007 28
20003 42
30019 56
30020 29
10006 36
20005 32
etc.
I apologize if this update should be posted as a different question. Let me know so I can go by community standards. The piece of output I posted, you'll notice isn't sorted by productID. That's the last thing I want to do. Other than that, it basically works. I am apologizing in case someone wants to vote me down for not posting the answer, since technically it would be the same answer to the initial question. If this update should be a different thread, again, let me know and I'll make the edit.

JVM Bytecode, how can I find the type of local variables?

I'm working on a fork of FernFlower from Jetbrains and I've been adding minor improvements to it.
One thing that really annoys me about FernFlower is that it bases the type of the local variable based on its value in bpush/spush etc. While Jode and Procyon somehow find a way to find the original value of a local variable.
Here is the original source code.
public static void main(String[] args) throws Exception {
int hello = 100;
char a2 = 100;
short y1o = 100;
int hei = 100;
System.out.println(a2+" "+y1o+", "+hei+", "+hello);
}
When decompiled with FernFlower, it outputs this:
public static void main(String[] args) throws Exception {
byte hello = 100;
char a2 = 100;
byte y1o = 100;
byte hei = 100;
System.out.println(a2 + " " + y1o + ", " + hei + ", " + hello);
}
But when decompiled with Jode/Procyon it outputs the original local variable types:
public static void main(String[] args)
throws Exception
{
int hello = 100;
char a2 = 'd';
short y1o = 100;
byte hei = 100;
System.out.println(a2 + " " + y1o + ", " + hei + ", " + hello);
}
I was wondering how is this possible because I thought no local variable type information is stored at compile time? How can I add the same functionality to FernFlower?
.class files optionally contain a 'LocalVariableTable' attribute for debugging purposes. If you invoke the command javap -l <Class>.class you can see the data if it is present.
So after looking around and debugging I found that for some reason FernFlower decides to completely ignore some of the data in the LocalVariableTable.
Here is ferns original code for decoding the LocalVariableTable:
public void initContent(ConstantPool pool) throws IOException {
DataInputFullStream data = stream();
int len = data.readUnsignedShort();
if (len > 0) {
mapVarNames = new HashMap<Integer, String>(len);
for (int i = 0; i < len; i++) {
data.discard(4);
int nameIndex = data.readUnsignedShort();
data.discard(2);
int varIndex = data.readUnsignedShort();
mapVarNames.put(varIndex, pool.getPrimitiveConstant(nameIndex).getString());
}
} else {
mapVarNames = Collections.emptyMap();
}
}
If you want type information you need to add the following:
#Override
public void initContent(ConstantPool pool) throws IOException {
DataInputFullStream data = stream();
int len = data.readUnsignedShort();
if (len > 0) {
mapVarNames = new HashMap<Integer, String>(len);
mapVarTypes = new HashMap<Integer, String>(len);
for (int i = 0; i < len; i++) {
int start = data.readUnsignedShort();
int end = start + data.readUnsignedShort();
int nameIndex = data.readUnsignedShort();
int typeIndex = data.readUnsignedShort();
int varIndex = data.readUnsignedShort();
mapVarNames.put(varIndex, pool.getPrimitiveConstant(nameIndex).getString());
mapVarTypes.put(varIndex, pool.getPrimitiveConstant(typeIndex).getString());
}
} else {
mapVarNames = Collections.emptyMap();
mapVarTypes = Collections.emptyMap();
}
}
It now outputs the same code as Jode with proper variable types :)
I wonder why FernFlower chose to ignore this information.

Stuck with Pascal's Triangle in Java

Ok, I need to have a class that re-creates the Pascal Triangle. We are using BlueJ and I can't get my arrays to access each other.
Here's the code:
public class PascalTriangle {
private int currentLineNumber;
private int[] previousLineArray;
private int[] nextLineArray;
public void firstLine()
{
currentLineNumber = 1;
System.out.println("1");
}
public void nextLine()
{
if (currentLineNumber == 1) {
int [] previousLineArray = new int [(currentLineNumber+1)];
previousLineArray[0] = 1;
previousLineArray[1] = 1;
System.out.println("1 1");
currentLineNumber = 2;
}
else if(currentLineNumber >= 2) {
for (int lineCount = currentLineNumber; lineCount <= currentLineNumber; lineCount++) {
int [] nextLineArray = new int [(lineCount+1)];
nextLineArray[0] = 1;
System.out.print(nextLineArray[0] + " ");
for (int nextLineCount = 1; nextLineCount < lineCount; nextLineCount++) {
// The next line is the line with the NullPointerException
nextLineArray[(nextLineCount)] = (previousLineArray[(nextLineCount-1)
+ previousLineArray[(nextLineCount)]]);
System.out.print(nextLineArray[(nextLineCount)] + " ");
}
nextLineArray[(lineCount)] = 1;
System.out.print(nextLineArray[(lineCount)] + "\n");
previousLineArray = nextLineArray;
}
currentLineNumber = currentLineNumber+1;
}
}
}
The class will compile but as I get to the third line, which should read 1 2 1, I get a java.lang.NullPointerException at PascalTriangle.nextLine(PascalTriangle.java:29) it highlists the nextLineArray[(nextLineCount)] = (previousLineArray[(nextLineCount-1) line. Why will the nextLineArray take the information from previousLineArray which is set when the nextLine() method is called for the first time?
Any help would be appreciated :) Thanks.
the problem is the following:
in the line where int [] previousLineArray = new int [(currentLineNumber+1)]; - you create a local array that shadows your member and only visible inside of if statement. Then when you come to this line: nextLineArray[(nextLineCount)] = (previousLineArray[(nextLineCount-1) it uses your member array that was not init.

Finding smallest and largest population and the average

I've been working on getting this program to work. I'm having a little trouble getting the program to read the files I have created, census2000 and census2010. These contain the 50 states and their population in 2000 and 2010. I believe that the rest of my program is correct. I was told to use methods to find the smallest population, largest population and the average. Here is two lines from the 2000 file:
Alabama 4447100
Alaska 626932
Here is my program:
public static void main(String[] args) throws IOException {
String state = "";
int population = 0;
int p = 0, s = 0, pop = 0, stat = 0, populate = 0, sum = 0;
File f = new File("census2000.txt");
Scanner infile = new Scanner(f);
infile.useDelimiter("[\t|,|\n|\r]+");
while (infile.hasNext()) {
checksmall(p, s);
checklargest(pop, stat);
checkAverage(populate, sum);
population = infile.nextInt();
state = infile.next("/t");
System.out.println(state + "has" + population + "people");
}
System.out.println(state + "has smallest population of" + population);
prw.close();
}
public static boolean checksmall(int p, int s) {
boolean returnValue;
if (p < s) {
returnValue = true;
} else {
returnValue = false;
}
return (returnValue);
}
public static boolean checklargest(int pop, int stat) {
boolean returnVal;
if (pop > stat) {
returnVal = true;
} else {
returnVal = false;
}
return (returnVal);
}
public static int checkAverage(int populate, int sum) {
int retVal;
retVal = populate + sum;
return (retVal);
}
}
What am I doing wrong?
I believe the problem is here:
state = infile.next("/t");
I think what you're trying to do is skip a tab in the file and read the state? You could do that by reading in the line and then splitting the line using \t as the delimiter.
String line;
while (infile.hasNextLine()){
line = infile.nextLine();
String data[] = line.split("\\s+");
state = data[0];
population = Integer.parseInt(data[1]);
}
edit: also as the other answer points out, you're attempting to perform functions on the file's data before it's read.
You need to be calling checksmall, checklargest and checkAverage after/while the file is loaded.

Categories