Output fails to print all the data i've inputted - java

I've been working on the same piece of java code for over a week now, t used to be a complete mess however i have got it now (through about a million iterations) to a somewhat working stage. The output i need is all three student names at the end with either a pass or fail beside their name, however my code will only output the last students name that i put in, completely ignoring the rest of the data i input.
If someone could teach me where i have gone wrong and also the quality of code i've produced and iterated, it would be much appreciated. Also to those who downvote my posts simply because it may seem easy to you, we aren't all experienced as you and don't forget that you used to be in my position once, so be thoughtful.
class Main extends BIO {
public static void main(String args[]) {
{
int i = 0;
int moduleMark = BIO.getInt();
String first_name = BIO.getString();
while (i++ < 3) {
System.out.print("Enter The Students name : ");
first_name = BIO.getString();
if (first_name.equals("END"))
break;
System.out.print("Their Module mark : ");
moduleMark = BIO.getInt();
}
if (moduleMark >= 40) {
System.out.println(first_name + " Pass");
} else {
System.out.println(first_name + " Fail");
}
}
}
}

first_name gets overwritten inside the loop constantly. When you exit the loop, first_name will be whatever the last name it received was.
If you can print them as you go, just print inside the loop. This will alternate between printing the results and asking for a new name/grade:
while (i++ < 3) {
System.out.print("Enter The Students name : ");
first_name = BIO.getString();
if (first_name.equals("END"))
break;
System.out.print("Their Module mark : ");
moduleMark = BIO.getInt();
if (moduleMark >= 40) {
System.out.println(first_name + " Pass");
} else {
System.out.println(first_name + " Fail");
}
If they must be printed at the end, you'll need to put the names and grades into lists, then iterate over the lists at the end:
// Create lists to hold grades and names
List<String> names = new ArrayList<>();
List<Integer> grades = new ArrayList<>();
while (i++ < 3) {
System.out.print("Enter The Students name : ");
first_name = BIO.getString();
if (first_name.equals("END"))
break;
// Add name to list
names.add(first_name);
System.out.print("Their Module mark : ");
moduleMark = BIO.getInt();
// Add grade to list
grades.add(moduleMark);
}
// Iterate both lists at once, printing inside the loop
for(int i = 0; i < names.size(); i++) {
String name = names.get(i);
Integer grade = grades.get(i);
if (grade >= 40) {
System.out.println(name + " Pass");
} else {
System.out.println(name + " Fail");
}
}

Related

Java for loop running both true and false conditions

I refactored a working project to practice creating callable methods when I broke the app. This app includes a simple String array with a method that matches user input with the array and prints the element name and index.
If I don't include a break at the end of the if else statements the app can match valid input but runs both if and else statements. It actually prints the if statement in the order of the index and prints the else output the number of times as the length of the array. In the attached pic, the input was index 0. if statement output In the pic index 0 was matched and printed with the number of else outputs as in the array. It seems the else statement is reading the array length.
If I add the break, the app only recognizes index 0 and will run the if statement as expected, but also runs the else statement. But only prints out if else output once. I hope this is clear. Trainers have simply said it is impossible to for a for loop to print of which I understand, yet I'm having a different experience.
Here is the code:
import java.util.Scanner;
public class Main {
static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("What are you looking for? ");
//String product = scan.nextLine();
String[] aisles = {"apples", "bananas", "candy", "chocolate", "coffee", "tea"};
searchProduct(aisles);
}
public static void searchProduct(String[] aisles) {
String product = scan.nextLine();
for (int i = 0; i < aisles.length; i++) {
if (product.equals(aisles[i])) {
System.out.println("We have " + aisles[i] + " in aisle " + i);
} else {
System.out.println("Sorry we do not have that product");
}
}
}
}
I expect to match valid user input and run the if statement or run the else statement.
Here is a suggestion.
Change your method to return an int (aisle if the product exists or -1 if not).
Don't do any I/O in the method. Just pass the target of the search as an argument.
String[] aisles = {
"apples","bananas","candy","chocolate","coffee","tea"
};
System.out.println("What are you looking for? ");
String product = scan.nextLine();
int aisle = searchProduct(product, aisles);
if (aisle >= 0) {
System.out.println("We have " + product + " in aisle " + aisle);
} else {
System.out.println("Sorry we do not have that product");
}
public static int searchProduct(String product, String[] aisles) {
for (int aisle = 0; aisle < aisles.length; aisle++) {
if (product.equals(aisles[aisle])) {
return aisle;
}
}
return -1;
}

Using scanner input in enhanced For loop to find indexOf an object in ArrayList

I'm trying to take my Scanner input and use it to find the index of the location of a object/name in an ArrayList of Objects.
The code is made up of two Classes, constructor(setter/getter) and tester class
The array list was created using the following code as example;
List<Detail> details = new ArrayList<>();
details.add(new Detail("Anthony", 26) );; note i used public void setName(String name) and public void setNumber(long number) to identify the objects added to the ArrayList
The arraylist output looks like this
Name: Anthony Age: 26
Name: Thomas Age: 30
Name: Shaun Age: 29
Name: James Age: 28
The code below is what i'm trying to use to find the index location. This code wont compile because i dont know what to put in the parenthesis of details.indexOf())
System.out.print("Type in one of the names listed above to find index of it's location: ");
String name = s.nextLine();
for (Detail d : details){
if (details.contains(s.nextLine()))
System.out.println("The index location of " +(scanner input/name here) " is " + details.indexOf());
My intended output is
The index location of Thomas is 1
I Know how to get the index of an element whenit's defined into the code, id use something like int location = details.get(2);, i believe this would return Name: Shaun Age: 29, but i dont know how to take the input from the Scanner Shaun and return only the Location of 2
Am I going about this in silly way? What am I doing wrong?
You can use the below approach to find the index of the name in the list.
Here,
I have iterated over the list and check the input with the names from the list, once found , assign that index and break from the loop.
If user input not found, then user will be notified with the message "name not found".
Code:
With For loop
public class Test {
public static void main(String[] args) {
List<Detail> list = Arrays.asList(new Detail("Anthony",26),
new Detail("Thomas",30),
new Detail("Shaun",29),
new Detail("James",28));
System.out.print("Type in one of the names listed above to find index of it's location: ");
Scanner s = new Scanner(System.in);
String name = s.nextLine();
int index = -1;
for(int i = 0 ; i < list.size(); i++){
if(name.equals(list.get(i).getName())){
index = i;
break;
}
}
if(index == -1) {
System.out.println("name not found");
} else {
System.out.println("The index location of " + name + " is " + index);
}
}
}
With enhanced For loop
public class Test {
public static void main(String[] args) {
List<Detail> list = Arrays.asList(new Detail("Anthony",26),
new Detail("Thomas",30),
new Detail("Shaun",29),
new Detail("James",28));
System.out.print("Type in one of the names listed above to find index of it's location: ");
Scanner s = new Scanner(System.in);
String name = s.nextLine();
int index = -1;
int counter = 0;
for(Detail d : list){
if(name.equals(d.getName())){
index = counter;
break;
}
counter++;
}
if(index == -1) {
System.out.println("name not found");
} else {
System.out.println("The index location of " + name + " is " + index);
}
}
}
Output::
Input:: Thomas
Output:: The index location of Thomas is 1
Input:: Test
Output:: name not found

Java: Display the complete set of unique values input after the user enters each new value

I need to write a code that "Display the complete set of unique values input after the user enters each new value." Such as:
The·complete·set·of·unique·values·entered·is:↵
Unique·Value·1:·is·100↵
Unique·Value·2:·is·10↵
Unique·Value·3:·is·20↵
I have attached my code below, and have the code completed, however, it seems to come across errors on my very last line to produce the last "this is the first time (user input) has been entered" & the unique value portion results of Unique Value # is (user input that's unique and stored in array). There seems to be an error in the very last System.out.println("Unique...) line.
Any help would be greatly appreciated.
import java.util.Scanner;
import java.util.ArrayList;
public class DisplayUniqueValueInput {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// creating an ArrayList from user input
ArrayList<Integer> userInputs = new ArrayList<Integer>(5);
// prompt user and store input
int count = 0;
while (true) {
int a = 0;
while(true) {
System.out.print("Enter an integer between 10 and 100:");
a = Integer.parseInt(sc.nextLine());
if (a < 10 || a > 100)
System.out.println("Invalid input\n");
else
break;
}
count++;
if (count == 5)
break;
boolean ifExists = false;
for(int i = 0; i<userInputs.size(); i++) {
if (userInputs.get(i) == a) {
ifExists = true;
break;
}
}
if (!ifExists){
System.out.printf("This is the first time %d has been entered\n", a);
userInputs.add(a);
}
} // end while statement
// output unique values
System.out.println("\nThe complete set of unique values entered is:\n");
for(int i = 0; i < 5; i++) {
System.out.println("Unique Value" + userInputs[i] + "is:" + " ");
}
} // end main method
} // end of class
A little off-topic but if you must store unique elements, you normally go for a Set. That being said, in the portion of the code where you collect the user input, you are asking for 5 numbers but storing 4 e.g.:
int count = 0;
while (true) {
int a = 0;
while(true) {
System.out.print("Enter an integer between 10 and 100:");
a = Integer.parseInt(sc.nextLine());
if (a < 10 || a > 100)
System.out.println("Invalid input\n");
else
break;
}
// count++;
// if (count == 5) if you break here, the code below won't be reached
// break; thus you will never store the last user input
// Lists have a method contains that does exactly what you are trying to do
// Consider using ifExists = userInput.contains(a)
boolean ifExists = false;
for(int i = 0; i<userInputs.size(); i++) {
if (userInputs.get(i) == a) {
ifExists = true;
break;
}
}
if (!ifExists){
System.out.printf("This is the first time %d has been entered\n", a);
userInputs.add(a);
}
// consider breaking here after you have collected the last user input
// alternatively, use a do{ ... } while(); loop
count++;
if (count == 5)
break;
} // end while statement
You are not printing the iteration variable i e.g.:
// output unique values
System.out.println("\nThe complete set of unique values entered is:\n");
for(int i = 0; i < userInputs.size(); i++) {
System.out.println("Unique Value " + (i + 1) + ": is " + userInputs.get(i));
}
Also as mentioned in another answer, in your for-loop the variable i must go up to < userInputs.size() since if you try to go up to 5, it will break if the user entered duplicate values.
For the last loop, you should do this instead, because your array is to store unique numbers, right? So if there is less than 5 unique number, your program will break, and why don't use Set instead?
// output unique values
System.out.println("\nThe complete set of unique values entered is:\n");
for(int i = 0; i < userInputs.size(); i++) {
System.out.println("Unique Value" + userInputs.get(i) + "is:" + " ");
}
Your error is because in the last for loop you try to access your list with userInputs[i] instead of userInputs.get(i)
If you want to accept and print only unique value, Perhaps use Set instead of ArrayList. Example:-
public static void main(String args[]){
Set<Integer> numbers = new HashSet<>();
for(String input : args){
Integer num = Integer.parseInt(input);
if(!(numbers.add(num))){
throw new IllegalArgumentException("Number already have");
}
System.out.println("Unique number =" + num);
}
}
A Set is a collection that contains no duplicate elements. Refer to its javadoc for details.
** Sample above just for brevity, you may retrofit your program with Set type.

Is there any way to pass a mutator method as an argument to another method?

I'm creating a text based game, I have a class made for the main character so you can set the characters name, etc. What I'm trying to figure out is, is there any way to pass a mutator (character.setname(input)) as an argument to another method. When I try to do it I'm told that I can't use a void type as an argument to a method. When I was writing out the code for the user to enter their name, and everything else it was repetitive with the error checking so I wanted to create my own method I could call that would error check for me. A couple sentences use the setname method to reset the name if it was entered incorrectly but I can't directly use setname in the error checking method because it's going to be using the same method to check other inputs of data.
Is there any way around this?
Here is the code as requested: I indeed may be overcomplicating the problem, I'm pretty new to java so I'm still learning.
The following code is the code I use to check if the user entered something correctly, it accepts an array which contains all the possible correct answers the user can type in, I've tried to design it in a way that I can error check anything with it, not just "yes" or "no" statements, getVariable is the accessor method, and setVariable is the one I'm trying to get to work, I'm trying to pass the mutator as well so I can reset the error
public void confirmEntry(String question, String[] options, String getVariable, setVariable) throws InterruptedException
{
boolean correctEntry = false;
System.out.print("Is this correct? ");
for(int i = 0; i < options.length - 1; i++)
{
System.out.print(options[i] + ", ");
}
System.out.print("or ");
System.out.print(options[options.length - 1] + ": ");
input = in.nextLine();
for(int i = 0; i < options.length; i++)
{
if(input.equals(options[i]))
{
correctEntry = true;
System.out.println(correctEntry);
}
}
System.out.println(correctEntry);
while(correctEntry == false)
{
Thread.sleep(2000);
System.out.print("You must enter ");
for(int i = 0; i < options.length - 1; i++)
{
System.out.print("\"" + options[i] + "\", ");
}
System.out.print("or ");
System.out.print("\"" + options[options.length - 1] + "\" to continue: ");
Thread.sleep(2000);
System.out.println();
System.out.println("You chose " + getVariable);
Thread.sleep(2000);
System.out.print("Is this correct? ");
for(int i = 0; i < options.length - 1; i++)
{
System.out.print(options[i] + ", ");
}
System.out.print(" or ");
System.out.print(options[options.length - 1] + ": ");
input = in.nextLine();
for(int i = 0; i < options.length; i++)
{
if(input.equals(options[i]))
{
correctEntry = true;
}
}
}
}
The following code is what is currently in the method where you enter information about the character. I'm trying to move more of the code into the error checking method so that each time I ask the user a question, name, age, etc. I just simply need to call the method.
public void characterCreation() throws Exception
{
//create an instance of the class player (your character creation)
Player character = new Player();
//Initial Introduction to the game
System.out.println("Welcome to Stranded!");
Thread.sleep(2000);
System.out.println("Tell us a little about yourself!");
Thread.sleep(2000);
//______________________________________________________________________________________________________________
//SET YOUR CHARACTER'S NAME
String[] yesNo = {"yes", "no"}; //array to feed into confirmEntry method
System.out.print("Enter your character's name: ");
input = in.nextLine(); //asks for input of the name
character.setName(input); //sets name in the player class
System.out.println("You chose " + character.getName()
+ " for your character's name");
Thread.sleep(2000);
confirmEntry("Enter your character's name: ", yesNo, character.getName(), character.setName(input));
while(input.equals("no"))
{
Thread.sleep(2000);
System.out.print("Enter your character's name: "); //prompt to enter name again
input = in.nextLine();
character.setName(input); //sets name in player class
Thread.sleep(2000);
System.out.println("You chose " + character.getName()
+ " for your character's name"); //confirms what user entered for name
Thread.sleep(2000);
confirmEntry("Enter your character's name: ", yesNo, character.getName(), character.setName(input));
}
I'm trying to move more code after the SET CHARACTER NAME comment into the confirmEntry method, however the rest of the code involved with the character's name uses the mutator to set the name. That's the problem. I wanted to try to get as much code into confirmEntry as possible so whenever I ask the user to enter something about their character I basically just have to call the method.
If you are using java 8 you can create your method with a method reference param :
public void functionName(Consumer<String> setter){setter.
accept(string);}
and to call your method you can use : functionName(character::setname);
you can see : http://www.informit.com/articles/article.aspx?p=2171751&seqNum=3
What is an entry? It appears to be some value that the user has entered.
class Entry{
String value;
public Entry(String value){
this.value = value;
}
public boolean confirm(String input){
return value.equals(input);
}
}
How about you store all of your entries.
Map<String, Entry> entries = new HashMap<>();
String message = "Enter your character's name: ";
System.out.println(message);
String input = in.nextLine();
entries.put(message, new Entry(input));
Now when you want to confirm.
public void confirmEntries(){
for(String message: entries.keySet()){
System.out.println(message);
System.out.println(entries.get(message) + "yes/no?");
//get some input and update the value. etc.
}
}
Another way to do it would be to create a Runnables.
List<Runnable> entryRunnables = new ArrayList<>();
Then anytime you want to add an action.
Runnable r = ()->{
System.out.println("Enter your players name, yes/no");
String input = in.readLine();
//check input and do stuff.
}
entryRunnables.add(r);
Now to check entries. (stream method)
entryRunnables.forEach(Runnable::run);
Or
for(Runnable r: entryRunnables){
r.run();
}

delete method with string arrays

I'm trying to write a method that will delete a CD (CD include artist name, album title, and track titles).. there are 5 CDs and I want to delete on of them... this is what the method should do :
void delete() will 1) ask the user for an artist and title, then attempt to find a CD with
matching artist and title, 2) display the CD if found, or tell the user it was not found, and 3)
if found, ask the user to confirm deletion (this needs keyboard input), deleting the CD
entry if the user confirms.
and this is my code:
public void delete() {
Scanner deleteInput = new Scanner(System.in);
System.out.println("Which artist you would like to delete? ");
System.out.println("Enter artist name and title to be deleted:");
String artist = deleteInput.nextLine();
String title = deleteInput.nextLine();
for (int i = 0; i <= CDlist.length - 1; i++) {
if ((CDlist[i].getArtist().equals(artist))
&& (CDlist[i].getTitle().equals(title))) {
System.out.println("Found: " + CDlist[i].getArtist() + " "
+ CDlist[i].getTitle());
if (CDlist[i] == null) {
continue;
}
System.out.println("Would you like to delete it? Yes 0 No 1");
if (deleteInput.nextInt() == 1) {
CDlist[i] = null;
cdnum--;
}
} else {
System.out.println("CD not found in the list.");
}
}
my problem is that when I type the correct Artist and Title to be removed I'm getting output as CD not found ( but it should say found and then removes it) how do I fix this please?
This is what I meant. Also you have an extra { in your first if right after the for loop starts. I hope that isn't causing an issue.
I have added the ignore case part based on some comments.
public void delete() {
Scanner deleteInput = new Scanner(System.in);
System.out.println("Which artist you would like to delete? ");
System.out.println("Enter artist name and title to be deleted:");
String artist = deleteInput.nextLine();
String title = deleteInput.nextLine();
boolean found = false;
int idx = -1;
System.err.println("DEBUG: Input Data");
System.err.println("Artist Name: "+artist+" Length of String: "+artist.length());
System.err.println("Title: "+artist+" Length of String: "+title.length());
System.err.println();
for (int i = 0; i <= CDlist.length - 1; i++) {
if (CDlist[i]!=null) {
System.err.println("DEBUG: Checking Index "+i);
System.err.println("Artist Name: "+CDlist[i].getArtist()+" Length of String: "+CDlist[i].getArtist().length() + " Matches: "+CDlist[i].getArtist().equalsIgnoreCase(artist));
System.err.println("Title: "+CDlist[i].getTitle()+" Length of String: "+CDlist[i].getTitle().length() + " Matches: "+CDlist[i].getTitle().equalsIgnoreCase(title));
System.err.println();
}
if (CDlist[i]!=null && CDlist[i].getArtist().equalsIgnoreCase(artist) && CDlist[i].getTitle().equalsIgnoreCase(title)) {
System.out.println("Found: " + CDlist[i].getArtist() + " " + CDlist[i].getTitle());
found = true;
idx = i;
break;
}
}
if (found) {
System.out.println("Would you like to delete it? Yes 0 No 1");
if (Integer.parseInt(deleteInput.nextLine()) == 1) {
CDlist[idx] = null;
//I am assuming cdnum is a variable of the class that can be accessed.
cdnum--;
}
} else {
System.out.println("CD not found in the list.");
}
}
Note: You need not put CDlist[i] in an if statement on its own you can just merge into the other statement. This can be done because java looks at things left-> right and so it'll check for null before trying to do anything. You can put it on its own but you'll need to put it BEFORE your first if statement.

Categories