mr Pi
mr Pi

Reputation: 57

Combine multiple while statements python

So I have for example the following while statements and I would like to combine them. Because this can get tiresome if you have 20 of these with all different if statements.

while True:
    name = str(raw_input("NAME PLEASE\n"))
    if name.isalpha():
        break
    print("Please chars dude")

while True:
    age = raw_input("Please type your age\n")
    if age.isdigit():
        break
    print("Please digits only")

If I combine them and someone types a A-Z character with 'age' then the code restarts all over without having saved the 'name' statement. I would like it to save 'name' if it's correct and only start over from the if statement that was false.

while True:
    name = str(raw_input("NAME PLEASE\n"))
    if name.isalpha():
        break
    print("Please chars dude")

    age = raw_input("Please type your age\n")
    if age.isdigit():
        break
    print("Please digits only")

Upvotes: 2

Views: 1284

Answers (7)

Elis Byberi
Elis Byberi

Reputation: 1452

Yes, you can combine both loops in one loop!

Always try to solve the problem line by line.
You will get to learn the language better and it is the most simple way to solve any problem too.

A line by line solution would look like this:

name = ''  # define name outside while loop
while True:
    if not name:
        name = str(raw_input("NAME PLEASE\n"))
        if not name.isalpha():  # validate name
            print("Please chars dude")
            # reset name
            name = ''

    else:
        age = raw_input("Please type your age\n")
        if age.isdigit():  # validate age
            """continue your code here"""
            print('name: ' + name + ' and age: ' + age)
            print('Ok! Goodbye!')
            break  # while loop
        else:
            print("Please digits only")

will print:

NAME PLEASE
Elis
Please type your age
30
name: Elis and age: 30
Ok! Goodbye!

This will help you understand while loop better and how to use it in more difficult cases.

Do not over design using redundant language features. It will make refactoring and debugging difficult.

Upvotes: 0

creativecoding
creativecoding

Reputation: 257

So I have for example the following while statements and I would like to combine them. Because this can get tiresome if you have 20 of these with all different if statements.

I assume the actual problem is "How to reduce tiresome code?" instead of "How to merge two loops into one?". I think keeping two loops is a good idea.

def safe_input(prompt, err_message, validation_fn):
    while True:
        value = raw_input(prompt)
        if validation_fn(value):
            return value
        print err_message

name = safe_input("NAME PLEASE\n", "Please chars dude", str.isalpha)
age = safe_input("Please type your age\n", "Please digits only", str.isdigit)

If you always want the used to enter text in a separate line, you might want to print prompt before raw_input and to not give an argument to raw_input. That way you don't have to supply "\n" in every call of safe_input.

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1121356

Use a function to encapsulate asking for information. You can pass in a validation test function:

def ask(question, validator, errormessage):
    while True:
        result = raw_input(question)
        if not validator(result):
            print(errormessage)
            continue
        return result


name = ask("NAME PLEASE\n", lambda s: s.isalpha(), "Please chars dude")
age = ask("Please type your age\n", lambda s: s.isdigit(), "Please digits only")

This is far more readable then any number of tests to see if the user already entered a correct name and you only need to ask for the age now.

Upvotes: 4

Steve Byrne
Steve Byrne

Reputation: 1360

Try this:

name = None
age = None

while requires_info:
    if name is None:
        temp_name = str(raw_input("NAME PLEASE\n"))
        if temp_name.isalpha():
            name = temp_name
            continue
        else:
            print("Please chars dude")
            continue
    if age is None:
        temp_age = raw_input("Please type your age\n")
        if temp_age.isdigit():
            age = temp_age
            continue
        else:
            print("Please digits only")
            continue
    break

What we do here is use a single continuous loop and a few if statements/variables to track what still needs to be done. Note depending on how you want them to enter the data you may also add logic to not ask for age if the name was invalid.

Upvotes: 0

Chen A.
Chen A.

Reputation: 11280

You can set the variables to None first, and then check them before assignment:

name, age = None, None

while True:
    if name is None:
        name = str(raw_input("NAME PLEASE\n"))
        if not name.isalpha():
            print("Please chars dude")
            name = None
            continue

    if age is None:
        age = raw_input("Please type your age\n")
        if not age.isdigit():
            print("Please digits only")
            age = None
            continue

    print("input is valid")
    break

continue will start the loop over again. This fits better in the logic of your code, since break actually stop and exit the loop code.

Upvotes: 1

John Szakmeister
John Szakmeister

Reputation: 46992

Why not use functions and cut down on some duplication in the process?

def ask_input(prompt, error_msg, validation_fn):
    while True:
        data = raw_input(prompt)
        if validation_fn(data):
            return data
        print(error_msg)

name = ask_input("NAME PLEASE\n", "Please chars dude", lambda x: x.isalpha())
age = ask_input("Please type your age\n", "Please digits only",
                lambda x: x.isdigit())

In this case, the prompt (what to ask the user), an error message (what to provide on invalid input), and a validation function are provided to the ask_input() function. This hides the while loop behind the function call and gives you something more meaningful to read in the code.

The lambda functions are just an easy way to help do the validation. You could do this instead:

def isalpha(x):
    return x.isalpha()


def isdigit(x):
    return x.isdigit()

name = ask_input("NAME PLEASE\n", "Please chars dude", isalpha)
age = ask_input("Please type your age\n", "Please digits only", isdigit)

Upvotes: 3

daemon24
daemon24

Reputation: 1438

Just use flags to track weather valid input is given, if given then exit the loop.

name_input_required = True
name = ''
while name_input_required:
    name = str(raw_input("NAME PLEASE\n"))
    if name.isalpha():
        name_input_required = False
    else:
        print("Please chars dude")

age_input_required = True
age = None
while age_input_required:
    age = raw_input("Please type your age\n")
    if age.isdigit():
        age_input_required = False
    else:
        print("Please digits only")

Upvotes: 0

Related Questions