What I'm assigned to do is create an object-oriented validator. The user is prompted to input an integer, and the application validates it. The end result will display on the console as follows (first 3 inputs being invalid, 4th being valid):
Welcome to the Validation Tester application
Int Test
Enter an integer between -100 and 100: X
Error! Invalid integer value. Try again.
Enter an integer between -100 and 100: -101
Error! Number must be greater than -101
Enter an integer between -100 and 100: 101
Error! Number must be less than 101
Enter an integer between -100 and 100: 100
I've been assigned to create a validation class before but never in the way I'm being asked to now. Before, I've been able to pass the sc and the prompt to the Validation class and have the methods process them accordingly. For example:
//MAIN
Scanner sc = new Scanner(System.in);
int x = Validator.getInt(sc, "Enter an integer: ", 0, 1000);
//VALIDATION CLASS
public class Validator{
public static int getInt(Scanner sc, String prompt)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
System.out.print(prompt);
if (sc.hasNextInt())
{
i = sc.nextInt();
isValid = true;
}
else
{
System.out.println("Error! Invalid integer value. Try again.");
}
sc.nextLine(); // discard any other data entered on the line
}
return i;
}
public static int getInt(Scanner sc, String prompt,
int min, int max)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
i = getInt(sc, prompt);
if (i <= min)
System.out.println(
"Error! Number must be greater than " + min + ".");
else if (i >= max)
System.out.println(
"Error! Number must be less than " + max + ".");
else
isValid = true;
}
return i;
}
Done as above, I understand what is happening.
However now I'm assigned get the same results using similar methods but this time the sc has its own constructor.
public class OOValidator
{
public OOValidator(Scanner sc){}
public int getInt(String prompt){}
public int getIntWithinRange(String prompt, int min, int max){}
}
I'm not asking anyone to do the assignment for me in its entirety, but I'm at a loss as to how I can both prompt the user and pass the user's input using a class that has the sc and prompt separated.
I've tried several to code it several difference ways, non of which compile.
Just create an instance of your class
//MAIN
Scanner sc = new Scanner(System.in);
OOValidator val = new OOValidator(sc);
int x = val.getInt("Enter an integer: ");
// ...
int y = val.getIntWithinRange("Enter an integer: ", 0, 1000);
//VALIDATION CLASS
public class OOValidator {
private Scanner sc;
private static final String ERROR = "Error! Invalid integer value."
+ "Try again.";
public OOValidator(Scanner sc) {
this.sc = sc;
}
public int getInt(String prompt) {
while (true) {
System.out.print(prompt);
if (sc.hasNextInt()) {
i = sc.nextInt();
sc.nextLine(); // discard any other data entered on the line
break;
} else {
System.out.println(ERROR);
sc.nextLine(); // discard any other data entered on the line
}
}
return i;
}
public int getIntWithinRange(String prompt, int min, int max) {
// same logic - use directly sc which is an instance field
}
}
Related
So my biggest problem is that I cannot seem to remember how to parse a string into an int so that I can idiot proof my code. My goal here is to find out if the user enters in a word instead of an int and then I can explain to them what an integer is. Can someone please help? I just need a simple list of parsing commands so that I can study them for use in the future, once there is a simple list I think I'll be able to figure all the others out from there.
import java.util.Scanner;
import java.util.*;
public class SelfTestNumberNine
{
public static void main(String[] args)
{
boolean test = false;
int num = 0;
int sum = 0;
int count = 0;
int pos = 0;
int neg = 0;
Scanner in = new Scanner(System.in);
while(!test)
{
num = 0;
System.out.print("Enter in an Integer Value: ");
String letta = in.next();
if(??parsing stuff goes here!!)
{
num = in.nextInt();
count++;
if(num > 0)
{
pos++;
sum = sum + num;
}
else if(num < 0)
{
neg++;
sum = num + sum;
}
else
{
test = true;
}
}
else
{
System.out.println("An Integer is a number that is positive or
negative,\nand does not include a decimal point.");
}
}//end while
System.out.println("Total: " + sum);
double avg = sum / count;
System.out.println("Average: " + avg);
}//end main
}//end class
Basically, the program asks the user to input integers, counts the number of positive and negatives, and prints out the total and average (Ignoring 0). The program ends when the user inputs a 0.
P.S. Thanks for your time!! ]:-)
If you want to ensure that the user has entered an int without throwing an exception if they don't you can use the hasNextInt() method:
System.out.println("Enter an int (0) to quit");
//While the user has not entered a valid int
while (!input.hasNextInt()) {
System.out.println("Please enter an integer: ");
//Consume the bad input
input.nextLine();
}
Which will loop until they enter a valid int. A sample run (- denotes user input):
Enter an int (0 to quit)
-No
Please enter an integer:
-Never!!
Please enter an integer:
-Ok ok fine
Please enter an integer:
-3
You can do this in two ways.
- Integer.parseInt()
- Integer.valueOf()
String myStr = "1";
int parsedInt = Integer.parseInt(myStr);
int valueOf = Integer.valueOf(myStr);
System.out.println("Parse Int: " + parsedInt);
System.out.println("Value Of: " + valueOf);
Note: You might get exception if the input is not parseable. NumberFormatException.
You can use a Boolean method and a try-catch to check if you can parse the string to an Integer.
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
} catch(NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
I'm trying to create a method that uses a while loop that includes a look ahead method to handle wrong user input: input out of 1-10 range or input a string. I am trying to do this with out throwing exceptions or using try{}catch{}; if possible. I haven't found a post that does not use these and all my attempts have failed so far. A basic idea will work.
will not stop if input is correct
import java.util.*;
public class UserErrors{
public static Scanner console = new Scanner(System.in);
public static void main(String[]args){
String s = "Enter a integer between 1-10: ";
get(s);
}
public static int get(String prompt){
System.out.print(prompt);
while(console.hasNext()){
while(!console.hasNextInt()){
console.next();
System.out.println("Invalid data type");
System.out.print(prompt);
}
if(console.nextInt() > 10 || console.nextInt() <1){
System.out.println("not in range");
System.out.print(prompt);
}
}
return console.nextInt();
}
}
requires the right answer to be imputed 3 times before it stops
import java.util.*;
public class UserErrors{
public static Scanner console = new Scanner(System.in);
public static void main(String[]args){
String s = "Enter a integer between 1-10: ";
get(s);
}
public static int get(String prompt){
System.out.print(prompt);
boolean b = false;
while(!b){
if(!console.hasNextInt()){
console.next();
System.out.println("Invalid data type");
System.out.print(prompt);
console.nextInt();
}
else if(console.nextInt() < 10 && console.nextInt() >1){
b = true;
}
else{
System.out.println("not in range");
System.out.print(prompt);
console.nextInt();
}
}
return console.nextInt();
}
}
I deleted some other failed attempts too. What do I need to fix (basic idea will do)?
There's an error:
if(console.nextInt() > 10 || console.nextInt() <1){ ... }
change this line to:
int i = console.nextInt();
if(i > 10 || i <1){ ... }
You can not reuse console.next...() just like that :)
Each nextInt call is a blocking call and it waits for user input.
For your code when you write below line:
if(console.nextInt() < 10 && console.nextInt() >1)
Essentially the console waits for first user input, checks it against 10 and then waits for next input which could be any (which you type second), not necessarily the same, waits for that and then finally enters the if condition.
The console input should always be taken upfront and assigned to our local variable and then it needs to be checked for your conditions like below:
int userInput = console.nextInt();
then the checking goes below with the userInput variable:
if(userInput < 10 && userInput >1)
The method nextInt() of the Scanner class read the standard exit
import java.util.*;
public class UserErrors{
public static Scanner console = new Scanner(System.in);
public static void main(String[]args){
String s = "Enter a integer between 1-10: ";
get(s);
}
public static int get(String prompt){
boolean b = false;
int number;
while(!b){
System.out.print(prompt);
if(!console.hasNextInt()){
console.next();
System.out.println("Invalid data type");
System.out.print(prompt);
console.nextInt();
}else {
number = console.nextInt();
if(nb<1 || nb>10){
System.out.println("not in range");
}else{
b=true;
}
}
}
return nb;
}
}
Note: Desire to move this to Code Review with a clearer structure for answer and my modified code which was very similar to the answer besides calcmin method.
I'm trying to break this code up into multiple methods and I was successful with the first bit but the other two I can't seem to figure out.
With the second method I was trying to make it so it would ask the user for an integer and continually prompts them until a proper integer is entered.
With the third method I was trying to make it so that it takes three integer parameters and returns the minimum value of those parameters.
I'd really appreciate the help on this. I've looked through examples in my book and can't seem to get it.
My code:
import java.util.Scanner;
public class MinOfThreeInts
{
public static void intro ()
{
System.out.println("This program determines the minimum of three ints");
System.out.println("It gracefully reports errors when erroneous data is entered ");
System.out.println("For example, if you type in 'abc' when this program asked for an int");
System.out.println("the program will report the error & ask for another int");
System.out.println("Try giving it bad input ! \n\n");
}
public static void readInt (int value1, int value2, int value3)
{
System.out.print(" Please enter an integer value ");
Scanner console = new Scanner(System.in);
String input = console.nextLine();
Boolean goodInt;
int parsedValue = 0;
goodInt = false;
while (!goodInt)
{
try
{
parsedValue = Integer.parseInt(input);
goodInt = true;
}
catch(NumberFormatException ex)
{
System.out.print(" Invalid input, please enter Int ");
input = console.nextLine();
}
}
value1 = parsedValue;
// Get the second integer
System.out.print(" Please enter an integer value ");
input = console.nextLine();
goodInt = false;
while (!goodInt)
{
try
{
parsedValue = Integer.parseInt(input);
goodInt = true;
}
catch(NumberFormatException ex)
{
System.out.print(" Invalid input, please enter Int ");
input = console.nextLine();
}
}
value2 = parsedValue;
// Get the third integer
System.out.print(" Please enter an integer value ");
input = console.nextLine();
goodInt = false;
while (!goodInt)
{
try
{
parsedValue = Integer.parseInt(input);
goodInt = true;
}
catch(NumberFormatException ex)
{
System.out.print(" Invalid input, please enter Int ");
input = console.nextLine();
}
}
value3 = parsedValue;
}
public static void calcMin (min)
{
int min = value1;
if (value2 < min)
{
min = value2;
}
if (value3 < min)
{
min = value3;
}
// Now report the results
System.out.println(" The minimum value of the three ints is " + min);
}
public static void main(String[] args)
{
value1 = readInt(console);
value2 = readInt(console);
value3 = readInt(console);
min = calcMin(value1,value2,value3);
}
}
You have a couple of issues. I refactored your code and added comments, I stayed close to your code in order to give you insights on where you can improve.
First, the code:
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class MinOfThreeInts {
//the main method, things start here
public static void main(String[] args) {
//initialize a new scanner that the application will use
Scanner console = new Scanner(System.in);
//print the intro
intro();
//read the values one by one and save them in a variable
int value1 = readInt(console);
int value2 = readInt(console);
int value3 = readInt(console);
//calculate the minimum and save it in the min variable
int min = calcMin(Arrays.asList(value1,value2,value3));
// Now report the results
System.out.println(" The minimum value of the three ints is " + min);
}
/**
* Reads an integer from the given console
*/
public static int readInt(Scanner console) {
System.out.print(" Please enter an integer value ");
//read the input
int parsedValue = 0;
boolean goodInt = false;
//as long as we don't find a valid number
while (!goodInt)
{
try
{
//read the input
String input = console.nextLine();
//try to parse the value
parsedValue = Integer.parseInt(input);
//set goodInt to true so that the while loop will end
goodInt = true;
}
catch(NumberFormatException ex)
{
//if the provivded value was not an integer, print a message and return to the start of the while loop
System.out.print(" Invalid input, please enter Int ");
}
}
return parsedValue;
}
/**
* calculates the minimum of a list of values
*/
public static int calcMin (List<Integer> values) {
//find the minimum and return the value
return Collections.min(values);
}
/**
* prints an intro message
*/
public static void intro () {
System.out.println("This program determines the minimum of three ints");
System.out.println("It gracefully reports errors when erroneous data is entered ");
System.out.println("For example, if you type in 'abc' when this program asked for an int");
System.out.println("the program will report the error & ask for another int");
System.out.println("Try giving it bad input ! \n\n");
}
}
Now, on what you can do to improve:
compile the code does not compile, always take care your code compiles and then slightly edit it until it compiles again
scope your code has multiple declared integers, the problem was that the values were not visible in other methods, if you declare a variable, say int value1 in some method, another method will not be able to see it. If you have another int value1 in that other method, it will only be visible in that specific method and it will actually be another variable
arguments vs return types methods take arguments and return something. The arguments are the input of the method and the returned value is the result of the method. Take for example your method: public static void readInt (int value1, int value2, int value3). This is a method that should read an integer value from the console. However, this method signature says it takes 3 integers as parameter. These integers would be passed by value, since they are primitive types, so you can not pass them, then fill them and then return them. There is also no return type, so the method is not returning something. Since the integer parameters value1, value2 and value3 are only visible in the method scope, you will loose your data. Compare with the new signature: public static int readInt(Scanner console). This method takes a console to read from as a parameter and returns an integer, the number that has been read. This method encapsulates the retry.
I want to display the statement inside the else whenever the user type a negative number, I know this while loop will be infinite loop but I don't know how to break it. I try to type in "break", but it shows error:
need a return statement.
Should I use only if-statement or am I writing the right code?
import java.util.Scanner;
class number{
public static void main(String[] args){
workers();
int numEmployee;
}
public static int workers(){
System.out.println("How many employees do you have?");
Scanner input = new Scanner(System.in);
int number = input.nextInt();
int numEmployee;
while(true){
if(number >= 0){
numEmployee = number;
return numEmployee;
}else{
System.out.println("Please enter a positive number");
}
}
}
}
Suggested changes:
import java.util.Scanner;
// Always capitalize your public class name (and the corresponding source file)
public class Number{
public static void main(String[] args){
// Get #/employees
int numEmployee = Number.workers();
System.out.println ("#/employees=" + numEmployee);
}
public static int workers(){
// Loop until we get a valid number
int number;
do {
System.out.println("How many employees do you have?");
Scanner input = new Scanner(System.in);
number = input.nextInt();
} while (number <= 0)
// Return the final value
return number;
}
}
First thing you want is to ask for input every loop. Also, you should have a return in your method for every condition. A compiler doesn't know your loop is infinite so it expects a return:
import java.util.Scanner;
class Number{
public static void main(String[] args){
int numEmployee = workers();
System.out.println("Number of empoyees: " + numEmployee);
}
public static int workers(){
int number = 0;
System.out.println("How many employees do you have?");
Scanner input = new Scanner(System.in);
while(true){
number = input.nextInt();
if(number >= 0){
return number;
}else{
System.out.println("Please enter a positive number");
}
}
return 0; //Added this
}
}
Your method should be:
public static int workers() {
System.out.println("How many employees do you have?");
Scanner input = new Scanner(System.in);
int number;
boolean isValid = false;
int numEmployee = 0;
while (!isValid) {
number = input.nextInt();
if (number >= 0) {
numEmployee = number;
isValid = true;
} else {
System.out.println("Please enter a positive number");
}
}
return numEmployee;
}
I'm having some troubles with the beginning of this program.
It's supposed to take a number and determine whether or not it is perfect.
Currently I have it asking how many numbers to check, whenever I input any positive number, it asks again.
AND, whenever I input a negative number for the second question, the program ends and doesn't prompt again.
Any ideas on how to fix this?
import java.util.Scanner;
public class aermel_Perfect
{
public static void main ( String args [] )
{
int gN = getNum();
int gP = getPerfect();
}
public static int getNum() //Get amount of numbers to check
{
Scanner input = new Scanner ( System.in );
System.out.print( "How many numbers would you like to test? " );
int count = input.nextInt();
int perfect = 1;
boolean vN = validateNum(count, perfect);
return count;
}
public static boolean validateNum( int count, int perfect ) //Check if number is valid
{
if (( count <= 0) || ( perfect <= 0))
{
System.out.print( "Non-positive numbers are not allowed.\n");
}
else
{
return true;
}
return false;
}
public static int getPerfect() //Gets the numbers to test
{
Scanner input = new Scanner ( System.in );
int perfect = -1;
int count = getNum();
System.out.print("Please enter a perfect number: " );
perfect = input.nextInt();
boolean vN = validateNum(perfect, count);
return perfect;
}
}
Use a while loop in your get methods e.g. to repeatedly ask for input until a valid number is entered.
public static int getNum() //Get amount of numbers to check
{
Scanner input = new Scanner ( System.in );
System.out.print( "How many numbers would you like to test? " );
int count = input.nextInt();
int perfect = 1;
boolean vN = validateNum(count, perfect);
while(!vN ){
System.out.println("Invalid input. Try again");
count = input.nextInt();
vN = validateNum(count, perfect);
}
return count;
}
Simiilarly, update the getPerfect method and remove int count = getNum(); statement from this method.
EDIT: To repeatedly ask for perfect number count times, update your main method as below:
public static void main ( String args [] )
{
int gN = getNum();
for(int indx=0; indx <gN; indx++){
int gP = getPerfect();
//use your gP numbers in the way you want
}
}
EDIT1: To call How many numbers would you like to test? " tow times, I think you can simply call your getNum() method two times in the main method as below:
public static void main ( String args [] )
{
int gN = getNum();//first call
gN = getNum(); //second call
int gP = getPerfect();
}
int count = getNum();
System.out.print("Please enter a perfect number: " );
perfect = input.nextInt();
You get two numbers here.