Need a refresher. I'm sure I know this already but I'm wracking my mind for a more efficient way to do this:
In short, the user is asked how many inputs they'd like to input (up to a certain maximum). For example, let's say they say 10.
Next, they're asked to input a number of single-digit integers equal to the number of inputs they wanted to input (in this case, they'd put in 10 different single-digit integers).
My issue is that I haven't coded Java in a while so I'm rusty. My immediate thoughts go to two options:
int input1 = 0, input 2=0, input3=0 ... inputN=0;
use an array
While option 1 is incredibly sophomoric it gets the job done. I'm just unsure if there's a simpler way to do it without using arrays.
import java.util.Scanner;
public class Histogram
{
public static void main(String[] args)
{
//variables
Scanner keyboard = new Scanner(System.in);
int numInputs = 0;
boolean success = false;
//start of program
System.out.println("How many input values [max:20]?");
while (!success)
{
try
{
numInputs = keyboard.nextInt();
numInputChecker(numInputs);
success = true;
}
catch (Exception e)
{
keyboard.nextLine();
System.out.println("Single-digit integers only, please.");
}
}
System.out.println("Enter " + numInputs + " numbers.");
for(int i = 0; i < numInputs; i++)
{
// ?????????
}
}
static void numInputChecker(int integer) throws Exception
{
if ((integer < 1) || (integer > 20))
{
throw new Exception();
}
}
static void numberChecker(int integer) throws Exception
{
if ((integer < 0) || (integer >= 10))
{
throw new Exception();
}
}
}```
i) If you're using multiple values, you're either going to need multiple variables or a collection of some sort. Agree with previous comments on choice of collection. (ii) If the amount of repetition required is counter controlled, why not set the loop to iterate that number of times? You would then need to nest while loops to ensure that your exception handling works but then you could limit the number of inputs. (iii) keyboard.nextInt() may be problematic because nextInt() does not discard the '\n'. It's better to Integer.parseInt(keyboard.nextLine()). (iv) If you're willing to work with strings, then you can do I/O once only and use the split() and Integer.parseInt() methods to get the necessary values.
Related
I need to validate that user inputs two integers and as such, I need to continue asking him for input until he provides both inputs that are integers. Not sure how to implement it, but I came up with something like that but now struggling to implement the part that checks if coord1 and coord2 get correct types. If not, it of course gives me the NumberFormatException:
while (true) {
System.out.print("Enter the coordinates: ");
int coord1 = Integer.parseInt(scanner.next());
int coord2 = Integer.parseInt(scanner.next());
if (coord1 < 1 || coord1 > 3 || coord2 < 1 || coord2 > 3) {
System.out.println("Coordinates should be from 1 to 3!");
continue;
} else if (cellOccupied(field, coord1, coord2)) {
System.out.println("This cell is occupied! Choose another one!");
continue;
}
break;
}
Can I solve it without using try / catch, since I haven't learned that yet, or is this the only way?
Thank you in advance and sorry, since I'm still learning Java syntax and ways of validation.
Instead of manually checking if the input is the right type, you could rely on the Scanner's methods hasNextInt() and nextInt().
The first one will check whether your input is an actual int and then you can proceed reading it with nextInt(). For further details about placing a nextLine() after reading a numeric type read the following question asked here on stack overflow.
Here I've also included your code in a sample main. I know yours was just a snippet with much more code around (I didn't have the cellOccupied method, for example) but I've just pasted it like so for a minimal testing. Besides, I've also parameterized your use case. It was a bit odd and redundant to repeat the same code for reading the user input applying the same coordinate-logic.
public class Main {
public static void main(String[] args) {
int coord1 = 0, coord2 = 0;
do {
coord1 = readCoordinate("Enter first coordinate: ");
coord2 = readCoordinate("Enter second coordinate: ");
//Showing an error message if the coords refer to an occupied cell
if (cellOccupied(field, coord1, coord2)) {
System.out.println("This cell is occupied! Choose another one!");
}
} while (cellOccupied(field, coord1, coord2));
}
private static int readCoordinate(String message) {
int coord;
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print(message);
if (scanner.hasNextInt()) {
coord = scanner.nextInt();
//getting rid of the new line character after reading the int
scanner.nextLine();
//Checking coordinate value
if (coord < 1 || coord > 3) {
System.out.println("Coordinates should be from 1 to 3!");
continue;
}
} else {
//assigning an undesired value (since your coords must be between 1 and 3
coord = 0;
//getting rid of the wrong user input
scanner.nextLine();
//Showing an error message
System.out.println("Please enter an int value");
//Skipping directly to the loop's condition
continue;
}
break;
}
return coord;
}
}
On a side note, avoid declaring fields in a loop.
You can find here several suggestions. For example, you can use regular expressions. Create an isNumeric function that will tell you whether a given string is an integer:
public boolean isNumeric(String strNum) {
Pattern pattern = Pattern.compile("\\d+");
if (strNum == null) {
return false;
}
return pattern.matcher(strNum).matches();
}
And before pushing the scanner.next() to the integer parser, check it with the function.
I was given the task of splitting my program which which allows the user to enter an array of numbers and after an odd number between 1 and 10 to check whether the odd number is a factor of each of the 5 numbers in the array. I keep on trying out different ways but none seem to work. Could someone help me out or send a sample of how I should sort it? This is the program:
import java.util.Scanner;
public class CheckboxExample{
public static void main(String args[]) {
CheckBox c = new CheckBox();
new CheckboxExample(); // links to checkbox class
Scanner s = new Scanner(System.in);
int array[] = new int[10];
System.out.println ("Please enter 10 random numbers"); // prompts the user to enter 10 numbers
int num; // declares variable num
try{
for (int i = 0; i < 10; i++) {
array[i] = s.nextInt(); // array declaration
}
}catch (Exception e){
System.out.println ("You have an error");
}
System.out.println ("Please enter an odd number between 1 and 10");
try{
num = s.nextInt ();
if (num % 2 == 0){
do{
System.out.println ("\nYour number is even, enter an odd one");
num = s.nextInt ();
}while (num % 2 == 0);
}
if (num < 0 | num > 10){
do{
System.out.println ("Your number is outside of the range, try again");
num = s.nextInt ();
}while (num < 0 | num > 10);
}
for (int i = 0; i < 5 ; i++){
if (array[i] % num == 0) {
System.out.println("Your number is a factor of " + array[i] );
}
}
}catch (Exception e){
System.out.println ("error");
}
}
}
A method should ideally be responsible for one task. In your case you should think about the different things your code try to do and organize them in a sense that each of the methods you call does one thing of the list of things you try to do.
As an example: As far as I understand your code does the following things:
Read an array of 10 values
Read an odd number
Verify the number is odd
Verify the number is in range
Calculate if the number is a factor of one of the 10 numbers in the array
Now one possible approach would be to separate your code in 5 methods that do exactly these things.
At first you call the method that reads the 10 numbers.
Then you call the method to read the odd number.
3. and 4. are actually part of reading the number, since you need to retry on an invalid input, so you could write your method for inputting the odd number in a way that it uses the methods for verifying the input.
Finally when you have all the valid input, you call the method which produces your result (ie. if the number is a factor of the numbers in the list).
A general outlier for your code could look like:
public class CheckboxExample {
public static void main(String args[]) {
CheckBox c = new CheckBox();
new CheckboxExample(); // links to checkbox class
Scanner s = new Scanner(System.in);
int array[] = readInputArray();
int number = readOddValue();
calculateFactors(array, number);
}
private int[] readInputArray() {...}
private int readOddValue() {...}
private void calculateFactors(int[] array, int number) {...}
//additional methods used by readOddValue which verify if the value is actually odd
}
Please note that this is just one way to split your code into methods and there are several ways to design and implement each of these methods.
I just wanted to say first that I'm a beginner so I apologize for my (really) horrible code.
I'm creating a program where you input an int and print out the square root using a do while loop. And when you input "0" the program will stop.
How do you stop it?
public static void main(String[] args)
{
Scanner InputNum = new Scanner(System.in);
DecimalFormat formatTenths = new DecimalFormat("0.0");
do {
System.out.println("Please enter an integer.");
int sqroot = InputNum.nextInt();
double Finalsqroot = Math.sqrt(sqroot);
System.out.println("Your Square Root is: " + (formatTenths.format(Finalsqroot)));
} while (sqroot==0);
System.out.println("Closing...");
InputNum.close();
}
}
You need to test if the value entered was 0 (I would test less than or equal to zero, because the square root of a negative number is imaginary). If so, break the loop. Like,
int sqroot = InputNum.nextInt();
if (sqroot <= 0) {
break;
}
try this
public static void main(String[] args) {
Scanner InputNum = new Scanner(System.in);
DecimalFormat formatTenths = new DecimalFormat("0.0");
int sqroot = 0;
do {
System.out.println("Please enter an integer.");
sqroot = InputNum.nextInt();
double Finalsqroot = Math.sqrt(sqroot);
System.out.println("Your Square Root is: " + (formatTenths.format(Finalsqroot)));
} while (sqroot != 0);
System.out.println("Closing...");
InputNum.close();
}
I just initialize sqroot outside of your while and change == to !=
This academic exercise may demand use of a do/while loop, but if you're not constrained to using it, a for loop would also work:
public static void main(String[] args)
{
Scanner InputNum = new Scanner(System.in);
DecimalFormat formatTenths = new DecimalFormat("0.0");
System.out.println("Please enter an integer.");
for(int sqroot = InputNum.nextInt(); sqroot > 0; sqroot = InputNum.nextInt()) {
double Finalsqroot = Math.sqrt(sqroot);
System.out.println("Your Square Root is: " + (formatTenths.format(Finalsqroot)));
}
System.out.println("Closing...");
InputNum.close();
}
Your program as presented in the question has an intrinsic flaw: you ask for input and then immediately try and do something with it (calc the square root) without determining if it is suitable to use.
Switching to a for loop is one way this can be overcome, because it encourages a program flow of "ask for input", "check if input is acceptable", "use input", "repeat"
If you're constrained to using a do/while loop then you still need to follow this flow, which Elliott Frish addresses in his answer, recommending you add in the "check if input is acceptable" part as a dual purpose test of whether the input is <= 0.. Such values are not acceptable for a square root op, and you also want to end the program when you encounter them, so the test can be used to achieve both goals
Side trivia, for loops can be used pretty much exclusively:
for(;;) //same as while(true)
for(;test;) //same as while(test)
for(bool do = true; do; do = test) //same as do..while(test)
..though using while or do is probably more readable than using a for loop for the same job
Note, your while(sqroot==0) is a bug.. you don't want to continue looping while the user entered 0, you want to continue looping while they DIDN'T enter a 0...
The program reads values from scanner until the value 0 is given, which finishes the process. The program will compile the sum only if all the numbers given are integers. In all the other situations (where not all of the values are integers) the program won't give anything out.
So i noticed my program gives out the sum of the integers even if there are other non integer values given and sometimes when they are all integers given it doesn't show the real sum just one of the numbers or something.
import java.util.Scanner;
public class Testing3{
public static void main(String[] args) {
int sum1 = 0;
Scanner input = new Scanner(System.in);
System.out.println("Enter number");
String number = input.nextLine();
int value =Integer.parseInt(number);
while(true) {
if (value!=0) {
number = input.nextLine();
if (Math.round(value)==value)//condition to integer{
sum1 = sum1 + value;
} else {
System.out.println(sum1);
break;
}
}
}
}
First of all, use while(true) or for(;;) to make in infinite loop
Second use nextInt() to read integers instead of doubles because you have no use for doubles. Alternatively, read strings with readLine and check their validity with Integer.parseInt.
Thirdly, you have a syntax error (so it shouldn't compile). You have an unmatched close brace near the else.
Lastly, remove the if (number != 0) because that will cause your program to continuously repeat in the loop without doing anything forever. Change the inside of the loop to:
number = input.nextInt();
if (number != 0){
sum1 = sum1 + number; //or use sum1 += number
} else {
System.out.println(sum1);
break;
}
I think your problem is at the place where you test for an integer. I don't think x mod 1 == 0 is correct suitable here. What I'll do when I am asked to check whether a number is an integer, I round the number and check if it equals to the original number.
Let's say we have a double variable called x and this evaluates to true if x is an integer:
Math.round(x) == x
I don't know whether there is a better way to do it but that's how I would do it and I like it.
I am a beginner in Java and had a question regarding an assignment I was doing.
I am trying to read a sequence of integer inputs and print out the largest and the smallest number. Though I already wrote the code, but the problem is that when I run it, it doesn't print the largest nor the smallest number. The code seems right even though its not! Any help would be appreciated.
import java.util.Scanner;
public class Practice {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter integers: ");
int largest = in.nextInt();
int smallest = largest;
while (in.hasNextInt()) {
int input = in.nextInt();
if (input > largest) {
largest = input;
} else if (input < smallest) {
smallest = input;
}
System.out.println();
}
System.out.println(largest);
System.out.println(smallest);
}
}
To Stop Waiting for an input :
Enter A character as input : in.hasNextInt() return False
Your code will not stop accepting numbers until it get something other than a number.
Like a alphabetical character. Enter an alphabetical character or keep something as a terminator.
Like enter -99 to quit or something.
Reading the code I would say that you expect the user to enter a set of numbers separated by space (the default separator chosen by the Scanner)
The scanner will loop endless parsing the input.
Now you need to decide a condition to exit and make your code safer.
When I say make your vode safer I mean put a try catch around your code in case the user doesn't write a number. Moreover you should close the scanner in a finally.
If you write something like the code below, the cycle is broken whenever u write a letter. E.g 1 2 4 6 A will print 2 and 6. Take it as a suggestion to work out a bit. Actually. you need to still protect the first nextInt, which, as it is, could throw exception if you don't start with a number and ideally decide an exit character handling the other exceptions. But these are implementation details. The code below will work provided that you start with a number and finish with a character different from a number
import java.util.Scanner;
public class Practise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter integers: ");
int largest = in.nextInt();
int smallest = largest;
try {
while (in.hasNextInt()||in.hasNext()) {
int input = in.nextInt();
if (input > largest) {
largest = input;
} else if (input < smallest) {
smallest = input;
}
System.out.println("Computing "+input);
}
System.out.println(largest);
System.out.println(smallest);
} catch (Exception ex) {
System.out.print("Exception caught: " + ex);
} finally {
in.close();
}
}
}