so I have written a code in my project where I have stored some votes in rows in a separate file. I then read that file and extract the votes in rows into a 1D array, then I have to increment them like if the user enters 1, 1 vote is added to the first row, if the user enters 2, one vote is incremented to the 2 row and so on. After that, I have to store that incremented array with added votes to the same file (overwrite) from where they were originally extracted.
I am facing two issues, first, when the user enters 1, there are actually 7 increments done because the loop runs for 7 times as the array length is 7. The second issue is, after the file is overwritten, it shows results with incremented votes in the output but the file becomes empty and when it is run again, it shows 0,0,0,0 .... even after using output.close() at the end.
Please suggest, I have to submit the project tomorrow and there is still a lot to write, if someone could please lend 2,3 hours to help too would be great.
public static int[] voteCasting(String resultFile) {
String[] votesArray = new String[7];
int[] votesConverted = new int[votesArray.length];
try {
String partyVotes = "";
int castedVotes;
int i = 0;
Scanner uI = new Scanner(System.in);
Scanner rF = new Scanner (new File(resultFile));
int userInput = uI.nextInt();
while (rF.hasNext()) {
partyVotes = rF.next();
votesArray[i]= partyVotes;
votesConverted[i] = Integer.parseInt(votesArray[i]);
i++;
if (userInput == 1) {
votesConverted[0] = ++votesConverted[0];
}
else if (userInput == 2) {
votesConverted[1] = votesConverted[1]++;
}
else if (userInput == 3) {
votesConverted[2] = votesConverted[2]++;
}
else if (userInput == 4) {
votesConverted[3] = votesConverted[3]++;
}
else if (userInput == 5) {
votesConverted[4] = votesConverted[5]++;
}
else if (userInput == 6) {
votesConverted[6] = votesConverted[6]++;
}
else if (userInput == 7) {
votesConverted[7] = votesConverted[7]++;
}
}
PrintWriter wF = new PrintWriter(resultFile);
while ( rF.hasNext()) {
wF.write(votesConverted[i]);
i++;
}
wF.flush();
wF.close();
} catch (IOException ex) {
Logger.getLogger(ProjectTesting.class.getName()).log(Level.SEVERE, null, ex);
}
return votesConverted;
}
Overwriting like this does not work - when the file is opened for writing, it is actually emptied. This does not happen when the file is opened for appending, but this does not seem like you want it. You need to write to a different file, then at the end remove the original file and move the new file to its location.
your problem lies with this loop:
while ( rF.hasNext()) {
wF.write(votesConverted[i]);
i++;
}
in previous loop rF.hasNext() already false.
...
while (rF.hasNext()) {
partyVotes = rF.next();
votesArray[i]= partyVotes;
....
so there was nothing to write. instead you could try:
i=0;
while ( i<7) {
wF.write(votesConverted[i]);
i++;
}
Related
I'm currently working on an assignment that requires me to build a small database for an imaginary toy company. They sell four different types of toys, with all of their toy's data in a single text file. Different toys have varying attributes to them.
My job is to read every line of the text file, find out what toy it is based on it's serial number, create a new instance of that toy, and load it into an array list of Toys.
Here are some examples of a line in the .txt file for every type of toy.
Animal
2835360879;Cow;Game Assassin;19.52;3;7;Plastic;M
Puzzle
4353818087;Eight queens puzzle;Gamescape;15.69;5;6;C
Figure
1147205649;Ninja Turtles;Gamezoid;46.15;10;6;A
Board Game
7235647474;13 Dead End Drive;Game Assassin;55.18;10;9;1-8;Emeli Davis
The following method is in charge of parsing through the text file, to create new instances of Toy, and to add them into the Array List
public void loadData() {
try {
File dataFile = new File("res/toys.txt");
if (dataFile.createNewFile()) {
System.out.println("Data file created!");
}
else {
Scanner readData = new Scanner(dataFile);
readData.useDelimiter(";"); // sets semicolons as the delimiter
while(readData.hasNext()) {
sn = readData.nextDouble(); // reads the next double (serial number) on each line
category = categoryHandler(sn); // setting and returning value for category based on the serial number
nm = readData.next(); // initializes the name of the toy
brd = readData.next();
prc = readData.nextDouble();
availableCnt = readData.nextInt();
ageApp = readData.nextInt();
// creates a new object, dependant on the category
switch(category) {
case "Figures":
char classification = readData.next().charAt(0);
Figure figures = new Figure(sn, nm, brd, prc, availableCnt, ageApp, classification);
data.add(figures);
break;
case "Animals":
String material = readData.next();
char size = readData.next().charAt(0);
Animal animals = new Animal(sn, nm, brd, prc, availableCnt, ageApp, material, size);
data.add(animals);
break;
case "Puzzles":
char puzzleType = readData.next().charAt(0);
Puzzle puzzles = new Puzzle(sn, nm, brd, prc, availableCnt, ageApp, puzzleType);
data.add(puzzles);
break;
case "Board Games":
String playerCount = readData.next(); // holds the player count as a string
int minPlayers = Integer.parseInt(playerCount.substring(0, 1)); // holds the first integer
int maxPlayers = Integer.parseInt(playerCount.substring(playerCount.length() - 1, playerCount.length())); // holds the second integer
String designers = "";
BoardGame boardGames = new BoardGame(sn, nm, brd, prc, availableCnt, ageApp, minPlayers, maxPlayers, designers);
data.add(boardGames);
break;
default:
System.out.println("Invalid toy type selected!");
}
if (readData.hasNext()) {
readData.nextLine(); // skips to the next line if there's a line to skip to
}
}
readData.close();
}
}
catch (IOException e) {
System.out.println("An error occured.");
e.printStackTrace();
}
}
The following method is in charge of categorizing the toy type.
public String categoryHandler(double serialNumber) {
String serialNumCheck = Double.toString(serialNumber); // converting serial number to string to allow the first digit to be checked
double firstDigit;
// setting up the first digit, checking to see if it's zero.
if (serialNumCheck.length() == 12) {
firstDigit = 0;
}
else {
firstDigit = Double.parseDouble(Double.toString(serialNumber).substring(0, 1));
}
// conditionals
if (firstDigit == 0 || firstDigit == 1) {
category = "Figures";
}
else if (firstDigit == 2 || firstDigit == 3) {
category = "Animals";
}
else if (firstDigit == 4 || firstDigit == 5 || firstDigit == 6) {
category = "Puzzles";
}
else if (firstDigit == 7 || firstDigit == 8 || firstDigit == 9) {
category = "Board Games";
}
// this condition should not be possible to achieve, unless the first digit is negative. Still have it just in case.
else {
System.out.println("Invalid serial number created!");
category = "";
}
return category;
}
After running the loadData() method, my array list only contains 128 toys, instead of the expected 225. Almost all of them are categorized properly, but a few toys are not, at seemingly at random indices.
I suspect it has something to with readData.nextLine() at the end of the loadData() method. The problem is that when I remove the line, the program throws a NullPointerException as there nothing left to scan on the current line, so no Toy can be created.
At this point I'm fairly lost as to what is causing this bug.
Some guidance would be appreciated.
The purpose of this project is to make a pokedex that adds and holds all the pokemon passed in by user input. When the user inputs a pokemon that is already stored in the pokedex the word "duplicate" is supposed to be printed to the console. The word duplicate is printed even though there are no actual duplicates within the object array. Here is my output from the console :
Welcome to your new PokeDex!
How many Pokemon are in your region?: 3
Your new Pokedex can hold 3 Pokemon. Let's start using it!
List Pokemon
Add Pokemon
Check a Pokemon's Stats
Sort Pokemon
Exit
What would you like to do? 2
Please enter the Pokemon's Species: red
Duplicate
Now here is all the code used that could possibly be making this error
import java.util.Scanner;
public class Project4 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Welcome to your new PokeDex!");
System.out.print("How many Pokemon are in your region?: ");
int size = input.nextInt();
Pokedex pokedex = new Pokedex(size);
System.out.println("\nYour new Pokedex can hold " + size + " Pokemon. Let's start using it!");
int choice = 0;
boolean done = false;
while (!done) {
System.out.println("\n1. List Pokemon\n2. Add Pokemon\n3. Check a Pokemon's Stats" + "\n4. Sort Pokemon\n5. Exit");
System.out.print("\nWhat would you like to do? ");
choice = input.nextInt();
switch (choice) {
case 1:
String[] pokemonList = pokedex.listPokemon();
if (pokemonList == null)
System.out.println("Empty");
else
for (int i = 0; i < pokemonList.length; i++) {
System.out.println((i + 1) + ". " + pokemonList[i]);
}
break;
case 2:
System.out.print("\nPlease enter the Pokemon's Species: ");
String species = input.next();
pokedex.addPokemon(species);
break;
}
}
}
}
In the following class I have the actual method that adds the pokemon and the constructor for Pokedex
public class Pokedex {
Pokemon[] pokedex;
String pokeArray[];
public Pokedex(int size) {
pokedex = new Pokemon[size];
pokeArray = new String[size];
}
public boolean addPokemon(String species) {
Pokemon stuff = new Pokemon(species);
for (int i = 0; i < pokedex.length; i++) {
if (pokedex[i] == null) {
pokedex[i] = stuff;
}
else if (i < pokedex.length && pokedex[i] != null) {
System.out.println("Max");
}
if (pokedex[i].getSpecies().equalsIgnoreCase(species)) {
System.out.print("Duplicate");
break;
}
}
return false;
}
}
Sorry for the mass amounts of code I just need help tracing where this unexpected result is coming from.
The reason it's doing that is because of this bit of code here:
public boolean addPokemon(String species)
{
Pokemon stuff = new Pokemon(species);
for (int i = 0; i < pokedex.length; i++)
{
if (pokedex[i] == null)
pokedex[i] = stuff;
else if (i < pokedex.length && pokedex[i] !=null)
System.out.println("Max");
if(pokedex[i].getSpecies().equalsIgnoreCase(species))
{
System.out.print("Duplicate");
break;
}
}
return false;
}
The problem is just a little bit of syntax missing. In your for loop, you check to see if
A) there are any empty spots in the array
B) if every element in the array up to the user inputted size is full
and C) if any element in the array matches the one we're trying to add.
The problem you're encountering is because your C is an if instead of an else if. Because A sees the index is null, it assigns the new Pokemon to the Pokedex. Then because C is an if instead of an else if, it runs after you assign the new Pokemon and sees the Pokemon we just added and says it's a duplicate. Changing it to an else if would fix this.
Also, since there was no break; in A, it would assign every element of the array to the first one entered, causing any further additions to call Max. I edited the code and this is what I had that worked for me:
public boolean addPokemon(String species)
{
Pokemon stuff = new Pokemon(species);
for (int i = 0; i < pokedex.length; i++)
{
if(pokedex[i] !=null && pokedex[i].getSpecies().equalsIgnoreCase(species))
{
System.out.println("Duplicate");
break;
}
else if (pokedex[i] == null)
{
pokedex[i] = stuff;
break;
}
else if(i + 1 == pokedex.length)
{
System.out.println("Max");
break;
}
}
return false;
}
Also, out of curiosity, why is the addPokemon() function a boolean? You return a value (albeit arbitrarily) and then never do anything with that value. You could just make it a void, have it return nothing, and it would work just as fine.
public void actionPerformed(ActionEvent e)
{
int clicked = 0;
if(arg == "Enter")
{
clicked++;
}
if (clicked == 0)
{
names[0] = nameField.getText();
numbers[0] = numberField.getText();
}
if( clicked == 1)
{
names[1] = nameField.getText();
numbers[1] = numberField.getText();
}
if(arg == "Print")
{
String name = nameField.getText();
String number = numberField.getText();
JOptionPane.showMessageDialog(null,names[0] + numbers[0] + names[1] + numbers[1] + numbers[2] + names[2],"Info",JOptionPane.INFORMATION_MESSAGE);
}
My program must take multiple names and numbers and be able to enter them into an array. After all of the data is entered, it must be able to be printed. I am having trouble under the Enter method because it continues to reset everytime instead of remaining constant. It only allows me to print the last typed name/number instead of saving all of the content. I am unsure of how to fix this and would be grateful for any suggestions at this point.
You could start by moving int clicked out of this function.
Right now your actionPerformed function each time its called reset your clicked to 0 since you are setting it to 0 at the beggining of it.
public void actionPerformed(ActionEvent e)
{
int clicked = 0; //HERE is your problem
if(arg == "Enter");
...
Making it a variable of class instead of function should help.
EDIT:
You can do something like this:
int clicked = 0
public void actionPerformed(ActionEvent e)
{
if(arg == "Enter"){
names[clicked] = nameField.getText();
numbers[clicked] = numberField.getText();
clicked++;
}
As it was mentioned you could also use List, since it would save problems if you don't know how big of an array u need.
List<String> names = new ArrayList<String>();
List<String> numbers = new ArrayList<String>();
And in use
if(arg == "Enter"){
names.add(nameField.getText());
numbers.add(numberField.getText());
}
Instead of an array, you could use an ArrayList, it will allow you to add elements without having to supply an index.
Without givening away too much, like this:
ArrayList<String> names = new ArrayList<String>();
...
names.add("Johnny"); // Adds to the end of the list
names.add("Frank");
That way you don't need to keep the 'clicked' count.
You can use .get(i) to get the element at index i. Or just loop over the entire list using a for each loop:
for(String name : names) { // i.e. for each 'name' in 'names'
System.out.println(name);
// Or do something else with 'name'
}
I am trying to execute a program after taking user input from the console. [code block below]. However, I do not want to terminate after the program execution finishes. I want the console to always ask me the INITIAL_MESSAGE after the execution finishes. Effectively, after the execution of the program, I want the console to again ask me the INTIAL_MESSAGE so that I can again enter the inputs as I want and execute the program again.
I am actually calling the interactor() in this method, from the main method as the starting point.
Please tell me how do I achieve this
public class ConsoleInteraction {
/**
* #param args
*/
public static int numberOfJavaTrainees ;
public static int numberOfPHPTrainees ;
Barracks trainingBarrack = new Barracks();
public void interactor() throws IOException {
//reading capability from the consolemessages properties file
ResourceBundle bundle = ResourceBundle.getBundle("resources/consolemessages");
// Create a scanner so we can read the command-line input
Scanner scanner = new Scanner(System.in);
// Prompt for training or viewing camp
System.out.print(bundle.getString("INITIAL_MESSAGE"));
//Get the preference as an integer
int preference = scanner.nextInt();
//Show options based on preference
if(preference == 1)
{
//System.out.println("Whom do you want to train?\n 1.Java Guy \n 2.PHP Guy \n 3.Mix \n Enter You preference:");
System.out.print(bundle.getString("WHO_TO_TRAIN"));
int traineepreference = scanner.nextInt();
if (traineepreference == 1)
{
//System.out.println("How many Java guys you want to train ? : ");
System.out.print(bundle.getString("HOW_MANY_JAVA"));
numberOfJavaTrainees = scanner.nextInt();
trainingBarrack.trainTrainees(numberOfJavaTrainees, 0);
}
else if (traineepreference == 2)
{
//System.out.println("How many PHP guys you want to train ? : ");
System.out.print(bundle.getString("HOW_MANY_PHP"));
numberOfPHPTrainees = scanner.nextInt();
trainingBarrack.trainTrainees(0, numberOfPHPTrainees);
}
else if (traineepreference == 3)
{
System.out.print(bundle.getString("HOW_MANY_JAVA"));
numberOfJavaTrainees = scanner.nextInt();
System.out.print(bundle.getString("HOW_MANY_PHP"));
numberOfPHPTrainees = scanner.nextInt();
trainingBarrack.trainTrainees(numberOfJavaTrainees, numberOfPHPTrainees);
}
else
{
System.out.print(bundle.getString("ERROR_MESSAGE1"));
}
}
else if (preference == 2)
{
System.out.println("Showing Camp to You");
System.out.println("Java trained in Trainee Camp : "+ TraineeCamp.trainedJavaGuys);
System.out.println("PHP trained in Trainee Camp : "+ TraineeCamp.trainedPHPGuys);
}
else
{
System.out.print(bundle.getString("ERROR_MESSAGE2"));
}
scanner.close();
}
}
Consider these changes quickly drafted to your class. Might not compile. Might not work as you planned.
Some highlights of what I think you should change:
Use constants for the choice values. Makes your code way more better to read.
Initialize Bundle and Scanner outside of the method. Might be reused.
instead of coding lengthy parts of code inside of the if-else-if cascade, call methods there - angain increasing your readability a long way
public class ConsoleInteraction {
public static int numberOfJavaTrainees ;
public static int numberOfPHPTrainees ;
//Don't read that every time...
ResourceBundle bundle = ResourceBundle.getBundle("resources/consolemessages");
public static void main(String[] args) {
//Moving Scanner out of loop
try {
Scanner scanner = new Scanner(System.in);
ConsoleInteraction ci = new ConsoleInteraction();
//Loop until this returns false
while(ci.interactor(scanner)) {
System.out.println("=== Next iteration ===");
}
} catch (IOException e) {
e.printStackTrace();
}
}
//Constant values to make code readable
public final static int PREF_TRAINING = 1;
public final static int PREF_SHOW_CAMP = 2;
public final static int PREF_QUIT = 99;
public boolean interactor(Scanner scanner) throws IOException {
// Prompt for training or viewing camp
System.out.print(bundle.getString("INITIAL_MESSAGE"));
//Get the preference as an integer
int preference = scanner.nextInt();
//Show options based on preference.
if(preference == PREF_TRAINING) {
//LIKE YOU DID BEFORE OR calling method:
readTraining(scanner);
} else if (preference == PREF_SHOW_CAMP) {
//LIKE YOU DID BEFORE OR calling mathod:
showCamp();
} else if (preference == PREF_QUIT) {
//Last loop
return false;
} else {
System.out.print(bundle.getString("ERROR_MESSAGE2"));
}
//Next loop
return true;
}
}
I want my program to keep asking the question until it gets a response it can use, specifically a number from 0 to 20. I have a lot of other stuff on this class, so here is a small excerpt where the do-while is (I have named the variables and all that for everything).
public static void main(String[] args) {
do {
halp = 1;
System.out.println("What level is your fort?");
Scanner sc = new Scanner(System.in);
try {
fortLevel = Integer.parseInt(sc.nextLine());
}
catch(NumberFormatException e){System.out.println("Numbers only, 0-20"); halp = 0;
}
if(halp < 1) {
work = false;
}
if(halp > 1) {
work = true;
}
while(work = false);
}
while(work = false); // here you are assigning false to work
should be
while(work == false); //here you are checking if work is equal to false
= an assignment operator used to assign value
== an equality operator used to check if two operands have same value.
As work is boolean you could even just use this:
while(!work)
You are using an assignment in your while expression:
while(work = false);
You can replace with
while(work == false);
or better
while(!work);
If variables halp and work are not used anywhere else, they could be eliminated giving you:
do {
System.out.println("What level is your fort?");
Scanner sc = new Scanner(System.in);
try {
fortLevel = Integer.parseInt(sc.nextLine());
} catch (NumberFormatException e) {
System.out.println("Numbers only, 0-20");
}
} while (fortLevel < 0 || fortLevel > 20);
You could also do this:
if(!work) {break;}