Isn't your loop on [CODE]str.charAt(i)[/CODE] looping through on each character in the input string?
Also, I think you want to loop from 0 to the length of the input string, not 0-6. The characters for which you are checking don't have to be in the first 6 characters of a … Read More

Well, if you've got, say, three functions, gotLength(...), gotUpper(...) and gotDigit(...), each of which returns a boolean TRUE if the password meets the requirements and FALSE if it's not a valid password you could verify it from your main program as follows:
[CODE]
if( gotLength(...) && gotUpper(...) && gotDigit(...) ) … Read More

Here is my code again. I still have something wrong because no matter what I put I get that the password is valid.
[CODE]
import java.util.Scanner;
public class PasswordDemo
{
public static void main(String[] args)
{
String input; // To hold input
// Create a Scanner object for keyboard input. … Read More

Also, I think you want to loop from 0 to the length of the input string, not 0-6. The characters for which you are checking don't have to be in the first 6 characters of a longer password.

Also, better logic would be to start off the verification functions with a boolean, "good," set equal to false and then switch it to true and return when you find the special characters you are looking for.

Also, I think you want to loop from 0 to the length of the input string, not 0-6. The characters for which you are checking don't have to be in the first 6 characters of a longer password.

Also, better logic would be to start off the verification functions with a boolean, "good," set equal to false and then switch it to true and return when you find the special characters you are looking for.

Well, if you've got, say, three functions, gotLength(...), gotUpper(...) and gotDigit(...), each of which returns a boolean TRUE if the password meets the requirements and FALSE if it's not a valid password you could verify it from your main program as follows:

Think about what you're doing here. goodSoFar is being set to false, then you have a loop condition that requires it to be true to execute. Will the code inside of your while loop ever execute?

Also, your if statement says to set goodSoFar to true if each character is NOT an uppercase character. I think that if

Character.isUpperCase(str.charAt(i))

is true, then you've met the upper case character requirements, you can set your goodSoFar value to true and stop inspecting the input for this requirement. Check for the same logic error in your other functions as well.

Alright, looks like you're getting on a roll now, but your logic still isn't quite there. You are right though, you were making it more complicated that what it needed to be. The problem isn't your isDigit section, it's the logic of the whole function. Think about what it's doing:

You're not checking the whole input string. I think you were on the right track with the while loops, although I would have used for loops.

What you want to do is to search the whole string (for character i=0 through i=length) to see if it's got an upper case character. If not, return false (it's not valid). If it does have an upper case character, continue on to the next check...Check each character in the input for lower case and use the same behavior as described above for the upper case situation. Once you find a good character for the test in question you can use a break statement to break out of the for (or while) loops.

Another way to do it would be to have a boolean value for each test (hasUpper, hasLower, hasDigit, hasLength) initialized to false, perform each test for the entire string, character by character, in a loop (setting the appropriate boolean variable true if you find a character which satisfies the test conditions). After you've performed all four tests, the booleans for the conditions which have been satisfied will be TRUE and those for conditions not met will be FALSE. Since all conditions must be met to be valid, you can

return (hasUpper && hasLower && hasDigit && hasLength);

which means that for the return value to be TRUE, all four of the arguments there need to be TRUE.

My mind wandered a bit while typing that. If it's not clear, let me know and I'll try to clarify.

So, if I get the for loop correct it should loop through the entire password before it moves on to the next for loop - and does the same thing, etc, etc. lol, I am not sure my brain is cut out for this!

Your loop logic looks good with respect to setting the boolean TRUE/FALSE in the right places, but I would rethink how you're doing your logic and what you do when you pass or fail a test. The above is your code, I would change it to something more like:

for (i = 0; i < str.length(); i++) // for each character in the input string
{
// check the validity condition:
if(Character.isUpperCase(str.charAt(i))) // if this validity condition is met,
break; // break out of this for loop, continue execution below
else // if you get here, then the validity condition has failed
return false; // so you can return FALSE
}
// if you get to this point in the execution, you passed the first validity condition (this is where "break" will put you).
// put in similar for loops for the remaining validity condition tests

Patience is a virtue. Admittedly, I'm sort of dragging it out and it seems to be working in that it looks like you're actually figuring it out on your own and learning from mistakes. I taught a college Java lab for 2.5 years and tried to do the same then. Old habits die hard.

But we don't want it to return false until it has a chance to check all of the letters...right? Or am I misunderstanding?

D'OH! Very good, grasshopper. That was just....uh...a test! You passed :D

I don't know why that made sense to me when I was writing it. I gotta hit the shower and get ready for bed, so the easiest way I could think of would be the solution I suggested earlier with a BOOL for each test condition. That would look something more like:

bool hasLen = FALSE;
bool hasDigit = FALSE;
bool hasUppper = FALSE;
bool hasLower = FALSE;
for (i = 0; i < str.length(); i++) // for each character in the input string
{
// check the validity condition:
if(Character.isUpperCase(str.charAt(i))) // if this validity condition is met,
{
hasUpper = TRUE;
break; //not really necessary I suppose since hasUpper can't turn back to FALSE, but it might save you a few nanoseconds of computation
}
// you don't really need to do anything if the condition isn't met, the bool is initialized to FALSE
}
// you can either check the hasUpper bool and return FALSE if it is FALSE or you can perform the rest of the checks and:
return (hasLen && hasUpper && hasLower && hasDigit);

I'll try to check the thread again before I turn in. Hopefully you stick around and hang out with the "community" even after you finish this assignment.

Gosh, I am not sure I can switch gears like that - what is easy for you is still hard for me. :icon_neutral:

I will give it a shot tomorrow! Thanks for the help today!

No sweat. FWIW, it's not really switching gears too much though. It might be simpler if explained this way:

To be valid, a password must meet four criteria: length must be greater than 6, must contain at least one upper case letter, must contain at least one lower case letter and must contain at least one digit.

Your isValid(...) function must check each of these four conditions and return either TRUE (meaning that all four conditions have been met) or FALSE (meaning that one or more conditions have failed. It doesn't matter how many fail, if any fail, the whole thing fails). This latest thing I'm talking about just breaks it up into smaller, bite size chunks within your isValid function.

We should be in agreement that the four test must all pass, so we want to declare the four booleans, one for each test:

These just provide a way for the program to keep track of each test. They are being initialized to FALSE for convenience's sake.

We then perform each test, in any order, setting each test's boolean value to TRUE if it passes. The format of this will be (don't let the big code block intimidate you, it's mostly comments):

isValid(...)
{
if( inputIsLongEnough ) hasLen = true; // if it's long enough, set the bool accordingly
//when we get here, if the length was long enough, hasLen is TRUE. If it failed that test, then no action was taken and hasLen remains the way it was initialized, FALSE
if( inputHasUpperCase ) hasUpper = true; // if it has any upper case letters, set the bool accordingly
//when we get here, if there were any upper case letters, hasUpper is TRUE. If it failed that test, then no action was taken and hasUpper remains the way it was initialized, FALSE
if( inputHasLowerCase ) hasLower = true; // if it has any lower case letters, set the bool accordingly
//when we get here, if there were any upper case letters, hasLower is TRUE. If it failed that test, then no action was taken and hasLower remains the way it was initialized, FALSE
if( inputHasDigit ) hasDigit = true; // if it has any digits, set the bool accordingly
//when we get here, if there were any numbers, hasDigit is TRUE. If it failed that test, then no action was taken and hasDigit remains the way it was initialized, FALSE
return (hasLen && hasUpper && hasLower && hasDigit); // this logical operator means to return the AND value of these four booleans. If ALL FOUR boolean variables are TRUE (i.e. it passed all tests), then the return value will be TRUE. If any one of them is false (i.e it failed one or more tests, we don't care how many), the return value will be FALSE.
}

Now, note that the lines that say

if( inputHasDigit ) hasDigit = true;

won't necessarily be that actual code and they don't even need to be function calls (which is how you initially did it in your OP). That is just whichever way you choose to do your test. You seemed to have a pretty good grasp of doing it with for loops, so that line would likely be replaced with something like

So what you end up with is a fairly simple isValid function that consits of four boolean variables, one length comparison (which will manipulate one of the booleans) and three for loops to check for the presence of certain characters (each of which will manipulate one of the booleans). The function will then return the results of AND-ing the four booleans together. It may sound complicated, but you've got all the pieces and each of them is simple; it's just a matter of putting them together. The end result isn't all that complicated either.

Brilliant! Thank you so much. I followed your advice and kept my for loops but changed to: hasLength, hasUpper, hasLower and hasDigit as the boolean. I then returned all four values and viola! It works!

Awesome job stepping me through the problem! Thanks for all of your help! I really learned alot!