Parsing text file - java

I am trying to convert this .txt file into SQL queries that I can read into an SQLite Database, problem is that I can't get the information I need printed out when I need it.
The problem from this code is that it will print out when it reaches the prob property, and then print the same line again when it reaches the min/max property, just this time with the correct values found in the file.
There is only 1 item with this ID but it prints twice:
0908100 ItemID: 2060000 Prob: 0.108 Min: 1 Max: 1
0908100 ItemID: 2060000 Prob: 0.108 Min: 10 Max: 20
The whole file is properly structured so should always follow the same pattern so when it reaches "prob" I have been trying to find a way to check if the next value is min/max and if it isn't print, otherwise print after reading min/max, I haven't been able.
The output I want from the program would be like this when it finds a min/max property:
INSERT INTO `test`.`drops` (mobID, itemID, prob, min, max);
VALUES (0908100, 2060000, 0.108, 10, 20);
If there is no min/max after prob then the same line should be like this instead:
INSERT INTO `test`.`drops` (mobID, itemID, prob, min, max)
VALUES (0908100, 2060000, 0.108, 1, 1);
Money will always be itemID 0 with min/max being default to the value of money.
so:
INSERT INTO `test`.`drops` (mobID, itemID, prob, min, max)
VALUES (0908100, 0, 0.65, 87, 87);
.
public static void main(String[] args) throws FileNotFoundException {
int radNmr = 0;
String mobID = "";
String money = "";
String item = "";
String prob = "";
String min = "1";
String max = "1";
Scanner sc = new Scanner(new File("Monster_Drops1.txt"));
while (sc.hasNext()) {
String namn = sc.next();
String namn1 = sc.next();
if ("m".equals(namn.substring(0, 1)) && !"money".equals(namn) && !"max".equals(namn) && !"min".equals(namn) ) {
mobID = namn.substring(1);
}
switch(namn) {
case "money":
money = namn1;
break;
case "item":
item = namn1;
break;
case "prob":
if (!money.equals("")) {
money = "";
break;
} else if (money.equals("")){
prob = namn1;
System.out.println(mobID + " ItemID: " + item + " Prob " + prob + " Min: " + min + " Max: " + max);
break;
}
case "max":
if (min.equals("1")) {
max = namn1;
break;
} else if (!min.equals("1")) {
max = namn1;
System.out.println(mobID + " ItemID: " + item + " Prob " + prob + " Min: " + min + " Max: " + max);
max = "1";
min = "1";
break;
}
case "min":
if (max.equals("1")) {
min = namn1;
break;
} else if (!max.equals("1")) {
min = namn1;
System.out.println(mobID + " ItemID: " + item + " Prob " + prob + " Min: " + min + " Max: " + max);
break;
}
}
}
}
The Monster_Drops1.txt comes in this sort of format, the start/end tags after the monster ID has no relevance and I just added it because of the Scanner throwing errors at me when that line only had one value.
m0908100 Start
money 87
prob 0.65
item 2340802
prob 0.4
item 2640002
prob 0.1
item 2040002
prob 0.00003
item 2041001
prob 0.00003
item 2060000
prob 0.54
min 10
max 20
item 9010000
prob 0.98
m0740101 end
money 80
prob 0.55
item 6050000
prob 0.9
item 2041006
prob 0.00003
item 3014000
prob 0.41

I want to thank everone who took the time to help me out, it was very very helpful!
I did find an answer to this problem, and it was rather simple really, I read the file into an ArrayList using a Scanner, and then just modified that Switch to give me the correct output.

Related

How to update the variable secondPrice to the third else arguement?

while (true){
int secondPrice = 0;
String bid = scanner.nextLine();;
if (bid.isEmpty()){
System.out.println("The item " + auction.get(i).getName() + " was sold for " + secondPrice);
break;
}
if (Integer.valueOf(bid) <= auction.get(i).getPrice()){
System.out.println("Cannot bid lower than or equal to the amount given.");
System.out.println("Any bidders?");
}
else {
secondPrice += Integer.valueOf(bid) + 1;
auction.get(i).setPrice(Integer.valueOf(bid));
System.out.println("Price is now at " + Integer.valueOf(bid) + ". Any other bidders?");
}
}
When I run this, and I put some numbers on the scanner to raise the price, and when printing out secondPrice it's always 0, the same from the top.
it is because secondPrice is being re-initialized every time, try declaring it before the while loop. A simple way to program the second bidding system you proposed, you would have a variable storing each bid, then set the highest bid equal to the second highest bid + .01 before the payment is calculated

Trying to understand why I can't round to 2 decimal places in one code but can in another thats virtually the same

I am writing a few java classes for a uni assignment and am having some trouble understanding what is going behind the scenes when I am trying to round to 2 decimal places. I have searched around but can't seem to find an answer that solves this particular version of the problem. So my code asks users to input prices into a cash register program and then prints the total price as well as the number of items. The total price has to be stored as an integer value (i.e 3.21 would be 321) but then outputted as a decimal value at the end. Here's my code:
public class CashRegister_Re_Implementation {
private double totalPrice;
private int itemCount;
CashRegister_Re_Implementation() {
totalPrice = 0;
itemCount = 0;
}
public double getTotal() {
String roundOff = String.format("%.2f", ((totalPrice * 100) / 10000));
double newDecimal;
newDecimal = Double.parseDouble(roundOff);
return newDecimal;
}
public int getItemCount() {
return itemCount;
}
public void addItem(double price) {
totalPrice += price * 100;
itemCount++;
}
}
class CashRegisterTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
CashRegister_Re_Implementation reg1 = new CashRegister_Re_Implementation();
int count1 = 0;
System.out.println("Register 1 (2 items)");
while (count1 < 2) {
System.out.print("Item price: £");
double price = scan.nextDouble();
reg1.addItem(price);
count1++;
}
CashRegister_Re_Implementation reg2 = new CashRegister_Re_Implementation();
int count2 = 0;
System.out.println("\nRegister 2 (2 items)");
while (count2 < 2) {
System.out.print("Item price: £");
double price = scan.nextDouble();
reg2.addItem(price);
count2++;
}
CashRegister_Re_Implementation reg3 = new CashRegister_Re_Implementation();
int count3 = 0;
System.out.println("\nRegister 2 (2 items)");
while (count3 < 2) {
System.out.print("Item price: £");
double price = scan.nextDouble();
reg3.addItem(price);
count3++;
}
System.out.println("\nFirst register. Total price: £" + reg1.getTotal() + "p for " + reg1.getItemCount() + " items");
System.out.println("Second register. Total price: £" + reg2.getTotal() + "p for " + reg2.getItemCount() + " items");
System.out.println("Third register. Total price: £" + reg3.getTotal() + "p for " + reg3.getItemCount() + " items");
}
}
It works fine except that if I enter all 1.00 I get this output:
Register 1 (2 items)
Item price: £1.00
Item price: £1.00
Register 2 (2 items)
Item price: £1.00
Item price: £1.00
Register 2 (2 items)
Item price: £1.00
Item price: £1.00
First register Total price: £2.0p for 2 items
Second register Total price: £2.0p for 2 items
Third register Total price: £2.0p for 2 items
Why am I getting £2.0 instead of £2.00?
I wrote this separately and it works absolutely fine:
public static void main(String[] args) {
double x = 100;
double y = 100;
double z = x + y;
String roundOff = String.format("%.2f", z);
System.out.println(roundOff);
}
Output:
200.00
Process finished with exit code 0
Why can't I get £2.00 in the exercise? Many thanks for any time taken to read all this :p
This is because your method getTotal has a return type of double but while concatenating the value in System.out.println you don't use formatting.
public double getTotal() {
String roundOff = String.format("%.2f", ((totalPrice * 100) / 10000));
double newDecimal;
newDecimal = Double.parseDouble(roundOff);
return newDecimal;
}
You should either return the formatted string from above method or change the print statements as follows:
System.out.println("\nFirst register. Total price: £" + String.format("%.2f", ((reg1.getTotal() * 100) / 10000)) + "p for " + reg1.getItemCount() + " items");
System.out.println("Second register. Total price: £" + String.format("%.2f", ((reg2.getTotal() * 100) / 10000)) + "p for " + reg2.getItemCount() + " items");
System.out.println("Third register. Total price: £" + String.format("%.2f", ((reg3.getTotal() * 100) / 10000)) + "p for " + reg3.getItemCount() + " items");
Note that a formatter has now been applied to the return value that you get from the method getTotal().
For a better reusability you should outline the first line in the method getTotal() in a new method like getTotalFormatted(). So you can use it in your rounding-algorithm and for printing too.

The program doesn't end when the timer ends until you give an input

I had some free time and I decided to make a program that could give me math questions using Java Eclipse. Whenever the timer ends during it though, the while loop doesn't end until you give one last input. I know that it is because of the while loop, but I don't know how to end it.
import java.util.Random;
import java.util.Scanner;
public class math_questioner_4 {
public static void main(String[] args) {
int firstnumber,secondnumber,operation,answer,answerinput,correctcount = 0,incorrectcount = 0, time, difficulty, max = 0, mixedop;
Scanner input;
System.out.println("What do you want the operation to be? 1 = addition 2 = subtraction 3 = multiplication 4 = division 5 = mixed");
input = new Scanner(System.in);
operation = input.nextInt();
// There is around 30 lines that don't relate to the question here
if (operation == 1) {
long endTime = System.currentTimeMillis() + (time*1000);
while (System.currentTimeMillis() < endTime) {
Random rand = new Random();
firstnumber = rand.nextInt(max) + 1;
secondnumber = rand.nextInt(max) + 1;
answer = firstnumber + secondnumber;
System.out.println("What is " + firstnumber + " + " + secondnumber + "?");
answerinput = input.nextInt();
if (answerinput == answer) {
System.out.println("Correct!");
correctcount++;
} else {
System.out.println("Sorry, " + firstnumber + " + " + secondnumber + " is " + answer + ".");
incorrectcount++;
}
}
// Another 140 lines here that don't matter either, just some operations
if (time == 1) {
System.out.println("You got " + correctcount + " questions correct and " + incorrectcount + " wrong in " + time + " second!");
} else {
System.out.println("You got " + correctcount + " questions correct and " + incorrectcount + " wrong in " + time + " seconds!");
}
}
}
I know that it's because of the while loop that it won't end, but I don't know how. Also please don't yell at me. I'm a beginner that takes classes at my Chinese school, it's only my 9th week (I've been to nine classes) and this is random extra stuff. I get most of my answers from this website and I also have only learned to do things with integers. It's also my first question here.

What can I do to print only the total value?

public static void main(String []args){
Random gen = new Random();
int[] numbers = new int[6];
int sum, product;
for (int i = 1; i < numbers.length; i++){
int pick = gen.nextInt(10);
numbers[i] = pick;
sum = (numbers[1]+numbers[2]+numbers[3]+numbers[4]+numbers[5]);
product = sum *2;
System.out.println("Random number: " + numbers[i]);
System.out.println("Product is: " + product);
}
}
It prints this:
Random number: 0
Product is: 0
Random numbers: 8
Product is: 16
Random number is: 9
Product is: 34
Random number is: 3
Product is 40
Random number is: 9
Product is 58
Which is fine, but I only want the total number, being 58. Something Simple :/ I'm new at this.
When ever you iterate through the loop you're invoking the System.out.println method, that's why you're getting all the output, you need to take the methods out of your for loop
Delete these:
System.out.println("Random number: " + numbers[i]);
System.out.println("Product is: " + product);
Put this one outside the for loop:
System.out.println("Product is: " + product);
Remove the following statements from the loop:
System.out.println("Random number: " + numbers[i]);
System.out.println("Product is: " + product);
And add the following outside the loop:
System.out.println("Product is: " + product);
Get this System.out.println("Product is: " + product); out of your loop

Reading from a txt file in Java

I'm taking a C course right now, but I also want to practice my work in Java as well. I'm having trouble reading from a file in Java (I want to get different types (double, int, etc..) from a file and store it in some variables. I know in C, the code would be like this:
int main(void) {
FILE* fp;
char name[29];
int qty;
char item[20];
float price;
fp= fopen("input.txt","r");
if (fp == NULL) {
printf("Couldn't open the file.");
return;
}
while (fscanf(fp, "%s %d %s %.2f\n", name, &qty, item, &price) != NULL) {
// do something
}
return 0;
}
But what about in Java? I have done this so far but it doesn't work. I did get an output but the format wasn't what I wanted.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main_Class {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = null;
try {
scan = new Scanner(new File("input.txt"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (scan.hasNextLine()) {
String name = "";
int quantity = 0;
String item_name = "";
double price = 0.0;
if(scan.hasNext()) {
name = scan.next();
}
if(scan.hasNextInt()) {
quantity = scan.nextInt();
}
if(scan.hasNext()) {
item_name = scan.next();
}
if(scan.hasNextDouble()) {
price = scan.nextDouble();
}
System.out.println(name + " " + quantity + " " + item_name + " " + price);
}
}
}
EDIT: Sorry guys, I forgot to include the txt file contents. I want my output just to be like this.
Smith 3 Sweater $22.50
Reich 3 Umbrella $12.50
Smith 1 Microwave $230.00
Lazlo 1 Mirror $60.00
Flintstone 5 Plate $10.00
Lazlo 1 Fridge $1200.00
Stevenson 2 Chair $350.00
Smith 10 Candle $3.50
Stevenson 1 Table $500.00
Flintstone 5 Bowl $7.00
Stevenson 2 Clock $30.00
Lazlo 3 Vase $40.00
Stevenson 1 Couch $800.00
My output (In Java, and I'm just going to include some of them since they are quite long):
Smith 3 Sweater 0.0
$22.50 0 Reich 3.0
Umbrella 0 $12.50 0.0
Smith 1 Microwave 0.0
$230.00 0 Lazlo 1.0
Mirror 0 $60.00 0.0
Flintstone 5 Plate 0.0
$10.00 0 Lazlo 1.0
if(scan.hasNextDouble())
{
price = scan.nextDouble();
}
change this to
price = Double.parseDouble(scan.next().substring(1));
And change
System.out.println(name + " " + quantity + " " + item_name + " " + price);
this to
System.out.println(name + " " + quantity + " " + item_name + " $" + price);
If all you care about is printing the data, you might as well read everything as a string and simplify the code to:
while (scan.hasNextLine()) {
String name, quantity, item_name, price;
if(scan.hasNext()) {
name = scan.next();
}
else ...
if(scan.hasNext()) {
quantity = scan.nextInt();
}
else ...
if(scan.hasNext()) {
item_name = scan.next();
}
else ...
if(scan.hasNext()) {
price = scan.nextDouble();
}
else ...
System.out.println(name + "\t" + quantity + "\t" + item_name + "t" + price);
}
The tab character, '\t', makes the output look a little better. Where the else's are, you can set default values in case nothing is found.
If you actually care if something is an int or a double, you can just use the parse methods, i.e.
int int_quantity = Integer.parseInt( quantity );

Categories