I want to write a program that checks the inserted password for:
Length is minimum of 8
At least 1 uppercase letter
At least 1 lowercase letter
At least 3 digits
I wrote this program, but it doesn't give me the right output:
import java.util.Scanner;
public class Question5 {
public static void main(String[] args) {
Scanner in = new Scanner (System.in);
System.out.println("Please enter your password: ");
String input = in.nextLine();
boolean flag = validate(input);
if (flag = true) {
System.out.println("password verified");
}
else {
System.out.println("not a good password");
}
}
public static boolean validate(String input) {
boolean flag = false;
int uppercaseCounter = 0;
int lowercaseCounter = 0;
int digitCounter = 0;
int letterCounter = 0;
for (int i = 0; i<(input.length()); i++) {
int totalCounter = digitCounter + letterCounter;
if (totalCounter >= 8 && digitCounter >= 3 && uppercaseCounter > 0 && lowercaseCounter > 0) {
flag = true;
}
else {
if (Character.isDigit(i)) {
digitCounter++;
}
if (Character.isLetter(i)) {
letterCounter++;
}
if (Character.isUpperCase(i)) {
uppercaseCounter++;
}
if (Character.isLowerCase(i)) {
lowercaseCounter++;
}
}
}
return flag;
}
}
Can someone help me with this? Thank you very much!
Here is the catch:
if (flag = true)
{
System.out.println("password verified");
}
= is an assignment operator == is the relational operator. To fix, do flag==true.
Also, in your method, you are comparing i, which is the counter, and not the
char At i. So do this
if(Character.isDigit(input.charAt(i))){ //Do this for all Character.isSomething() Methods
for all the checks you make.
You are actually checking the i counter in your various if instead of the input string...
use something like
char c = s.charAt(i);
and check the input chars
moreover you should change the check if(flag = true) with if(flag)
Change
if (flag = true)
{
System.out.println("password verified");
}
else
{
System.out.println("not a good password");
}
to
if (flag)
{
System.out.println("password verified");
}
else
{
System.out.println("not a good password");
}
When you write if(flag=true) then you are doing an assignment operation and not an equality comparison.
Also, the logic should be Character.isDigit(input.charAt(i)) since you want to check the character at i and not i itself.
To conclude, I would like to say that this problem would be fun to solve with Regular Expressions. Check this tutorial on regular expressions in Java.
In addition to other answers, this code should be moved below the counter increments:
int totalCounter = digitCounter + letterCounter;
if (totalCounter >= 8 && digitCounter >= 3 && uppercaseCounter > 0 && lowercaseCounter > 0) {
flag = true;
}
Otherwise, you run the risk of returning false when your password would become valid on the last character.
Related
I wrote a code about primes and would hear your opinion or any suggestions how i can improve my code. I'm a beginner in Java.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
boolean a;
System.out.println("Please enter a number: ");
int zahl = s.nextInt();
if(zahl <= 0) {
System.out.println("Please enter a positive number without zero.");
return;
}
a = true;
for (int i = 2; i < zahl; i++) {
if (zahl % i == 0) {
a = false;
}
}
if (a == true) {
System.out.println("Is Prim");
}
if (a==false){
System.out.println("Not a prim");
}
}
The easiest thing to do is the following
Instead of
for (int i = 2; i < zahl; i++) {
if (zahl % i == 0) {
a = false;
}
}
change the for loop the
for (int i = 2; i < Math.sqrt(zahl); i++)
If no numbers up to the square root divide zahl, then no numbers beyond the square root will divide it either (they would have been the result of earlier divisions).
Also, for outputing the answer you could do:
System.out.println(zahl + " is " + ((a) ? "prime"
: "not prime"));
That's using the ternary operator ?:
some hints :
You do
System.out.println("Please enter a positive number without zero.");
return;
the println suggests the user can enter a new value, but no, in that case better to say the number was invalid so you exit
When you do a = false; it is useless to continue, no chance for a to be back true
It is useless to try to divide by more than sqrt the number
It is necessary to try to divide by 2 but not by an other even number, so add 2 to i rather than 1
If if (a == true) false it is useless to check if (a==false)
Your code is good. I have made three small improvements:
The input asks at once (and not only after a bad input) for a
positive int.
The input is repeated until correct.
The for loop runs only up to sqrt(zahl) which is sufficient.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
boolean a;
int zahl = 0;
while (zahl <= 0) {
System.out.println("Please enter a positive int without zero.");
zahl = s.nextInt();
}
a = true;
for (int i = 2; i <= Math.sqrt(zahl); i++) {
if (zahl % i == 0) {
a = false;
break;
}
}
if (a == true) {
System.out.println("Is Prim");
} else {
System.out.println("Not a prim");
}
}
Coding a simple HiLo card game where the user is given a card value from a deck of cards and then inputs 'higher', 'lower' or 'equal' trying to guess the balue of the next card.
Just really can't get my head around user input validation with iteration ie. not moving on until a string with the required parameters has been entered.
My code so far:
import java.util.Scanner;
import java.util.Random;
public class HiLoGame {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
Random randomCard = new Random();
int numberOfSuccesses = 0;
boolean finished = false;
int card = (randomCard.nextInt(13) + 2);
while (finished != true) {
int nextCard = (randomCard.nextInt(13) + 2);
String pictureCard = "";
if (((numberOfSuccesses < 0) ? nextCard : card) == 11) {
pictureCard = "Jack";
} else if (((numberOfSuccesses < 0) ? nextCard : card) == 12) {
pictureCard = "Queen";
} else if (((numberOfSuccesses < 0) ? nextCard : card) == 13) {
pictureCard = "King";
} else if (((numberOfSuccesses < 0) ? nextCard : card) == 14) {
pictureCard = "Ace";
}
System.out.println("The card is a " + ((card > 10) ? pictureCard : card));
if (numberOfSuccesses == 4) {
System.out.println("Congratulations. You got them all correct");
finished = true;
break;
}
while (!reader.nextLine().toLowerCase().equals("higher")
|| !reader.nextLine().toLowerCase().equals("lower")
|| !reader.nextLine().toLowerCase().equals("equal")) {
System.out.println("Try again!");
reader.next();
}
String userGuess = reader.nextLine().toLowerCase();
//TODO validate input
if (userGuess.equals("higher")) {
if (nextCard > card) {
numberOfSuccesses++;
} else {
finished = true;
break;
}
} else if (userGuess.equals("lower")) {
if (nextCard < card) {
numberOfSuccesses++;
} else {
finished = true;
break;
}
} else if (userGuess.equals("equal")) {
if (nextCard == card) {
numberOfSuccesses++;
} else {
finished = true;
break;
}
}
System.out.println(numberOfSuccesses);
card = nextCard;
}
if (numberOfSuccesses < 4) {
System.out.println("Sorry, incorrect!");
}
}
}
and the relevant code extract:
while (!reader.nextLine().toLowerCase().equals("higher")
|| !reader.nextLine().toLowerCase().equals("lower")
|| !reader.nextLine().toLowerCase().equals("equal")) {
System.out.println("Try again!");
reader.next();
}
It kinda just gets stuck at the above part giving "Try again" over and. I've completed programs having to use .hasNextInt() but I'm struggling with this string validation.
Thanks for any and all help/comments!
You are calling reader.nextLine() up to 3 times and so you are comparing 3 different strings.
If I enter "xxx" your code says "xxx != higher so read another line" - it never compares "xxx" to "lower" or "equal".
Also pay attention to && vs ||.
Solution is to read one line into a variable and use that variable for each condition. I'm not going to write it out as this is clearly homework or a self learning exercise, so best for you to do it yourself.
I think your condition logic needs to change. You are checking if input not equal to "higher" or not equal to "lower" or not equal to "equal" so it will always be false overall even if you enter expected value - if you enter "higher" it's not equal to lower. You need to change ors to ands.
folks. I'm doing every problem on codebyte.com (I suggest website to everyone who wants to practice coding skills :)) and got stuck at this problem: return true if the characters a and b are separated by exactly ``3 places anywhere in the string at least once; else return false.
Examples:
Input = "after badly" Output = "false"
Input = "Laura sobs" Output = "true"
My code is giving me false every time I write any string when in some cases it should return true. Could smb please take a look?
public static void main(String[] args)
{
Scanner kbd = new Scanner(System.in);
System.out.println("Please enter any String: ");
String myString = kbd.nextLine();
char[] myArray = myString.toCharArray();
boolean result = false;
for(int i = 0; i < myArray.length; i++)
{
if(myArray[i] == 'a' && myArray[i+4] == 'b')
result = true;
else
result = false;
}
System.out.println(result);
}
Once you find it is true, you are going to want to print True and exit from the for loop. As of now you continue going through the string even if you find a true value!
public static void main(String[] args)
{
Scanner kbd = new Scanner(System.in);
System.out.println("Please enter any String: ");
String myString = kbd.nextLine();
char[] myArray = myString.toCharArray();
boolean result = false;
for(int i = 0; i < myArray.length; i++)
{
if(myArray[i] == 'a' && myArray[i+4] == 'b'){
result = true;
break;
}
}
System.out.println(result);
}
Also it is unclear if you are looking for strings like "adddb" or "addb"
because the former is i+4 and the latter is i+3
A simple break statement will help you here. In your for loop, just place in under the if condition right after you set the result to true. If we find the case where there is 3 spaces between 'a' and 'b' we want to get out of the loop and tell the user! The break statement will automatically terminate the loop for you.
for(int i = 0; i < myArray.length; i++){
if(myArray[i] == 'a' && myArray[i+4] == 'b'){
result = true;
break;
}
else
result = false;
}
i+4 is four spaces, if you want three use i+3. Also, check the length - 3. Also, break; if you set result to true (or the next iteration will reset it). Like
boolean result = false;
for(int i = 0; i < myArray.length - 3; i++) {
if (myArray[i] == 'a' && myArray[i+3] == 'b') {
result = true;
break;
}
}
If you play with array index you might end with arrayIndexOutOfBoundException. Rather use regular expressions
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
System.out.println("Please enter any String: ");
String myString = kbd.nextLine();
boolean result = false;
if(myString.matches("^(.)*(a)(.){3}(b)(.)*$")){
result = true;
}
System.out.println(result);
}
How do I convert my do-while loop to a while loop?
int numAttempts = 0;
do
{
System.out.println("Do you want to convert to Peso or Yen?");
pesoOrYen = readKeyboard.nextLine();
if(pesoOrYen.equalsIgnoreCase("Peso")||pesoOrYen.equalsIgnoreCase("Yen"))
{
notPesoOrYen = false;
}
else if (numAttempts < 2)
{
System.out.println("Sorry, but '"+pesoOrYen+"' is not a valid currency type. Try again:");
notPesoOrYen = true;
}
numAttempts++;
} while(notPesoOrYen==true && numAttempts < 3);
I tried to do while(notPesoOrYen==true && numAttempts < 3) then the statement but it did not work.
MY FULL CODE
package currencyconverter;
import java.util.Scanner;
import java.text.NumberFormat;
public class CurrencyConverter
{
public static void main(String[] args)
{
Scanner readKeyboard = new Scanner(System.in);
double doubleUsersCaptial;
boolean notPesoOrYen=true;
String pesoOrYen;
double usersConvertedCapital;
boolean userInputToRunProgramAgain=true;
final double US_DOLLAR_TO_PESO = 13.14;
final double US_DOLLAR_TO_YEN = 106.02;
do
{
System.out.println ("How much money in US dollars do you have?");
String usersCaptial = readKeyboard.nextLine();
doubleUsersCaptial = Double.parseDouble(usersCaptial);
int numAttempts = 0;
do
{
System.out.println ("Do you want to convert to Peso or Yen?");
pesoOrYen = readKeyboard.nextLine();
if(pesoOrYen.equalsIgnoreCase("Peso")||pesoOrYen.equalsIgnoreCase("Yen"))
{
notPesoOrYen = false;
}
else if (numAttempts < 2)
{
System.out.println("Sorry, but '"+pesoOrYen+"' is not a valid currency type. Try again:");
notPesoOrYen = true;
}
numAttempts++;
}while(notPesoOrYen==true && numAttempts < 3);
if(numAttempts==3)
{
System.out.println("Sorry, but '"+pesoOrYen+"' is not a valid currency type.");
System.out.println("You entered the wrong currency type too many times\nGood Bye");
System.exit(0);
}
if (pesoOrYen.equalsIgnoreCase("Peso"))
{
usersConvertedCapital = doubleUsersCaptial*US_DOLLAR_TO_PESO;
}
else
{
usersConvertedCapital = doubleUsersCaptial*US_DOLLAR_TO_YEN;
}
NumberFormat formatter = NumberFormat.getCurrencyInstance();
String formatUsersCaptial = formatter.format(doubleUsersCaptial);
String formatUsersConvertedCapital = formatter.format(usersConvertedCapital);
System.out.println(formatUsersCaptial+"US Dollars = "
+formatUsersConvertedCapital+" "+pesoOrYen);
System.out.println("Would you like to run the Program Again?(enter 'yes' or 'no')");
String runProgramAgain = readKeyboard.nextLine();
if (runProgramAgain.equalsIgnoreCase("yes"))
{
userInputToRunProgramAgain = true;
}
else if (runProgramAgain.equalsIgnoreCase("no"))
{
System.out.println("Goood Bye");
System.exit(0);
}
else
{
System.out.println ("You entered something other than 'yes' or 'no'\n"
+"Good Bye");
System.exit(0);
}
}while (userInputToRunProgramAgain==true);
}
}
while and do... while are almost the same, do... while simply performs an iteration before evaluating for the first time the exit condition, whereas while evaluates it even for the first iteration (so eventually the body of a while loop can never be reacher whereas a do... while body will always be executed at least once).
Your code snippet is not complete but I guess you didn't initialized notPesoOrYen to true before the loop and that's why it is not working. Finally, don't write while(notPesoOrYen==true && numAttempts < 3) but while(notPesoOrYen && numAttempts < 3), the == true comparison is unnecessary.
Initialise your boolean variable outside while loop:
int numAttempts = 0;
boolean notPesoOrYen=true;
while (notPesoOrYen && numAttempts < 3) {
System.out.println("Do you want to convert to Peso or Yen?");
pesoOrYen = readKeyboard.nextLine();
if (pesoOrYen.equalsIgnoreCase("Peso") || pesoOrYen.equalsIgnoreCase("Yen")) {
notPesoOrYen = false;
} else if (numAttempts < 2) {
System.out.println("Sorry, but '" + pesoOrYen + "' is not a valid currency type. Try again:");
notPesoOrYen = true;
}
++numAttempts;
};
I am creating a Hangman Game in Java and it almost works perfectly. So I have two problems. The first being that:
When the user inputs a letter and the word has repeated letters, how can I make it print both instances of the letter.
I have created a while loop however this loop does not output the Modified word until after the next go. If that makes sense?
The second problem:
I need to be able to prevent the user from entering the same letter twice
I have attempted Lists and arrays and hash sets. All sorts but none seem to work.
My code is below:
There may be other threads with same questions but none seem to help as I cannot implement it into this person's code.
import java.util.Scanner;
import java.util.Arrays;
public class Hangman{
public static void main(String []args){
Scanner Input = new Scanner(System.in);
String[] CollectionOfWords = {"","gravity","banana","gate","processor","momentum","earth","star","light","television","pan","cupboard"};
int radmNumber = (int) Math.ceil (Math.random() * CollectionOfWords.length);
int counter = 10;
String radmWord = CollectionOfWords[radmNumber];
char[] genRadmLetter = radmWord.toCharArray();
char[] genRadmLetter2 = radmWord.toCharArray();
for (int x = 0; x<genRadmLetter.length; x++){
genRadmLetter[x]='?';
}
System.out.println(String.valueOf(genRadmLetter));
System.out.println("Hello. Guess a letter.");
char guessedLetter = Input.next().charAt(0);
int RW = radmWord.indexOf(guessedLetter);
if (RW >= 0 ){
genRadmLetter[RW] = guessedLetter;
System.out.println(genRadmLetter);
}
if (RW == -1){
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
}
while (counter != 0) {
System.out.println("Guess a letter.");
guessedLetter = Input.next().charAt(0);
RW = radmWord.indexOf(guessedLetter);
if (RW >= 0 ){
genRadmLetter[RW] = guessedLetter;
System.out.println(genRadmLetter);
}
if (RW == -1){
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
} else {
System.out.println(genRadmLetter);
while (RW >= 0 ){
genRadmLetter[RW] = guessedLetter;
RW = radmWord.indexOf(guessedLetter, RW+1);
}
}
boolean result = Arrays.equals(genRadmLetter, genRadmLetter2);
if (result == true){
break;
}
if (counter == 0){
break;
}
}
if (counter == 0){
System.out.println("You lose. The word was: " + radmWord);
}
else {
System.out.println("Well done, you have guessed the word.");
System.out.println("Your final score is: " + counter);
}
}
}
Instead of using...
int RW = radmWord.indexOf(guessedLetter);
To determine if the entered value matches a character, which will only return the first index, you should, instead, use a loop of some kind to check every character
boolean found = false;
for (int rw = 0; rw < genRadmLetter2.length; rw++) {
if (genRadmLetter2[rw] == guessedLetter) {
genRadmLetter[rw] = guessedLetter;
found = true;
}
}
Now, because you're relying on the value of RW to determine if a match was found or not, I changed it so that the boolean found flag can used instead, for example...
if (!found) {
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
}
You also have duplicate sets of code, which can be reduced to a single do-while loop instead, which will make it easier to read and make changes, for example...
do {
//...
} while (counter != 0);
To your second problem, a Set of some kind would be the simplest solution...
Set<Character> guesses = new HashSet<Character>();
//...
char guessedLetter = Input.next().charAt(0);
if (guesses.contains(guessedLetter)) {
System.out.println("You've used this guess, guess again");
} else {
guesses.add(guessedLetter);
For example...
And because it's not always easy to translate code snippets ... this is my test code...
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Hangman {
public static void main(String[] args) {
Scanner Input = new Scanner(System.in);
String[] CollectionOfWords = {"", "gravity", "banana", "gate", "processor", "momentum", "earth", "star", "light", "television", "pan", "cupboard"};
int radmNumber = (int) Math.ceil(Math.random() * CollectionOfWords.length);
int counter = 10;
String radmWord = "banana"; //CollectionOfWords[radmNumber];
char[] genRadmLetter = radmWord.toCharArray();
char[] genRadmLetter2 = radmWord.toCharArray();
for (int x = 0; x < genRadmLetter.length; x++) {
genRadmLetter[x] = '?';
}
Set<Character> guesses = new HashSet<Character>();
do {
System.out.println("Guess a letter.");
System.out.println(String.valueOf(genRadmLetter));
System.out.println("Hello. Guess a letter.");
char guessedLetter = Input.next().charAt(0);
if (guesses.contains(guessedLetter)) {
System.out.println("You've used this guess, guess again");
} else {
guesses.add(guessedLetter);
boolean found = false;
for (int rw = 0; rw < genRadmLetter2.length; rw++) {
if (genRadmLetter2[rw] == guessedLetter) {
genRadmLetter[rw] = guessedLetter;
found = true;
}
}
if (!found) {
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
}
}
boolean result = Arrays.equals(genRadmLetter, genRadmLetter2);
if (result == true) {
break;
}
if (counter == 0) {
break;
}
} while (counter != 0);
if (counter == 0) {
System.out.println("You lose. The word was: " + radmWord);
} else {
System.out.println("Well done, you have guessed the word.");
System.out.println("Your final score is: " + counter);
}
}
}
There are multiple issues with the code:
the typical beginners problem of length vs. max element number
unnecessary duplicate code
a logic issue with the output
as for 1.:
you are using this:
int radmNumber = (int) Math.ceil (Math.random() * CollectionOfWords.length)
if you use
int radmNumber = (int) Math.ceil (Math.random() * CollectionOfWords.length-1)
you can start the arrey without a empty string and it wont randomly crash
on to 2.
you wont need to duplicate the input code if you use this:
System.out.println(String.valueOf(genRadmLetter));
System.out.print("Hello.");
char guessedLetter;
int RW;
while (counter != 0)
{
System.out.println("Guess a letter.");
...
and finally 3.(your main question)
you do the output before changing it. so this fixes your problem:
...
else
{
while (RW >= 0)
{
genRadmLetter[RW] = guessedLetter;
RW = radmWord.indexOf(guessedLetter, RW + 1);
}
System.out.println(genRadmLetter);
}
So simply move the output behind the while.
I made a little helper clas that could help you...
static class GuessString {
private char[] mask;
private String solution;
private boolean lastGuessResult;
GuessString(String word) {
this.solution = word;
this.mask=word.toCharArray();
Arrays.fill(mask, '?'); // Build a mask like: ??????
}
public String guess(char guess) {
char c = Character.toLowerCase(guess); // case insensitive
int i = solution.indexOf(c);
lastGuessResult = i != -1; // -1 means "not found)
if (lastGuessResult)
while (i != -1) { // this will loop till c is replaced everywhere.
mask[i] = c;
i = solution.indexOf(c, i+1);
}
return new String(mask); // return the updated mask.
}
public boolean lastGuessIsRight() {
return lastGuessResult;
}
public String getCurrent() {
return new String(mask);
}
public boolean isSolved() {
return getCurrent().equals(solution);
}
}