source

유효한 답변을 할 때까지 사용자에게 입력을 요구합니다.

factcode 2022. 9. 20. 23:52
반응형

유효한 답변을 할 때까지 사용자에게 입력을 요구합니다.

사용자 입력을 받을 수 있는 프로그램을 쓰고 있습니다.

#note: Python 2.7 users should use `raw_input`, the equivalent of 3.X's `input`
age = int(input("Please enter your age: "))
if age >= 18: 
    print("You are able to vote in the United States!")
else:
    print("You are not able to vote in the United States.")

사용자가 의미 있는 데이터를 입력하면 프로그램은 예상대로 작동합니다.

Please enter your age: 23
You are able to vote in the United States!

그러나 사용자가 잘못된 데이터를 입력하면 실패합니다.

Please enter your age: dickety six
Traceback (most recent call last):
  File "canyouvote.py", line 1, in <module>
    age = int(input("Please enter your age: "))
ValueError: invalid literal for int() with base 10: 'dickety six'

크래시가 아니라 프로그램에서 다시 입력을 요청해 주셨으면 합니다.다음과 같이 합니다.

Please enter your age: dickety six
Sorry, I didn't understand that.
Please enter your age: 26
You are able to vote in the United States!

값을 대신 유효한 ( " " " )-1

거예요.input메서드를 지정합니다.입력이 잘못되었을 때 사용합니다.break당신이 만족할 때 고리를 벗어날 수 있습니다.

입력 시 예외가 발생할 수 있는 경우

및 를 사용하여 사용자가 구문 분석할 수 없는 데이터를 입력할 때 탐지합니다.

while True:
    try:
        # Note: Python 2.x users should use raw_input, the equivalent of 3.x's input
        age = int(input("Please enter your age: "))
    except ValueError:
        print("Sorry, I didn't understand that.")
        #better try again... Return to the start of the loop
        continue
    else:
        #age was successfully parsed!
        #we're ready to exit the loop.
        break
if age >= 18: 
    print("You are able to vote in the United States!")
else:
    print("You are not able to vote in the United States.")

자체 검증 규칙 구현

Python이 성공적으로 구문 분석할 수 있는 값을 거부하려면 자체 검증 로직을 추가할 수 있습니다.

while True:
    data = input("Please enter a loud message (must be all caps): ")
    if not data.isupper():
        print("Sorry, your response was not loud enough.")
        continue
    else:
        #we're happy with the value given.
        #we're ready to exit the loop.
        break

while True:
    data = input("Pick an answer from A to D:")
    if data.lower() not in ('a', 'b', 'c', 'd'):
        print("Not an appropriate choice.")
    else:
        break

예외 처리와 커스텀 검증의 조합

위의 두 가지 기술을 하나의 루프로 조합할 수 있습니다.

while True:
    try:
        age = int(input("Please enter your age: "))
    except ValueError:
        print("Sorry, I didn't understand that.")
        continue

    if age < 0:
        print("Sorry, your response must not be negative.")
        continue
    else:
        #age was successfully parsed, and we're happy with its value.
        #we're ready to exit the loop.
        break
if age >= 18: 
    print("You are able to vote in the United States!")
else:
    print("You are not able to vote in the United States.")

함수에 모두 캡슐화

사용자에게 다양한 값을 요청해야 하는 경우 이 코드를 함수에 넣는 것이 유용할 수 있으므로 매번 다시 입력할 필요가 없습니다.

def get_non_negative_int(prompt):
    while True:
        try:
            value = int(input(prompt))
        except ValueError:
            print("Sorry, I didn't understand that.")
            continue

        if value < 0:
            print("Sorry, your response must not be negative.")
            continue
        else:
            break
    return value

age = get_non_negative_int("Please enter your age: ")
kids = get_non_negative_int("Please enter the number of children you have: ")
salary = get_non_negative_int("Please enter your yearly earnings, in dollars: ")

모든 것을 종합하다

이 아이디어를 확장하여 매우 일반적인 입력 함수를 만들 수 있습니다.

def sanitised_input(prompt, type_=None, min_=None, max_=None, range_=None):
    if min_ is not None and max_ is not None and max_ < min_:
        raise ValueError("min_ must be less than or equal to max_.")
    while True:
        ui = input(prompt)
        if type_ is not None:
            try:
                ui = type_(ui)
            except ValueError:
                print("Input type must be {0}.".format(type_.__name__))
                continue
        if max_ is not None and ui > max_:
            print("Input must be less than or equal to {0}.".format(max_))
        elif min_ is not None and ui < min_:
            print("Input must be greater than or equal to {0}.".format(min_))
        elif range_ is not None and ui not in range_:
            if isinstance(range_, range):
                template = "Input must be between {0.start} and {0.stop}."
                print(template.format(range_))
            else:
                template = "Input must be {0}."
                if len(range_) == 1:
                    print(template.format(*range_))
                else:
                    expected = " or ".join((
                        ", ".join(str(x) for x in range_[:-1]),
                        str(range_[-1])
                    ))
                    print(template.format(expected))
        else:
            return ui

다음과 같은 용도:

age = sanitised_input("Enter your age: ", int, 1, 101)
answer = sanitised_input("Enter your answer: ", str.lower, range_=('a', 'b', 'c', 'd'))

일반적인 함정과 이를 피해야 하는 이유

용장 input

이 방법은 작동하지만 일반적으로 스타일이 좋지 않은 것으로 간주됩니다.

data = input("Please enter a loud message (must be all caps): ")
while not data.isupper():
    print("Sorry, your response was not loud enough.")
    data = input("Please enter a loud message (must be all caps): ")

도 있어요. 때문에 매력적일 수도 있어요.왜냐하면 길이가 짧기 때문에while True그러나 소프트웨어 개발의 Don't Repeat Yourself 원칙에는 위배됩니다.이것에 의해, 시스템의 버그가 발생할 가능성이 높아집니다.를 변경하여 2.7로 백포트를 하려면 어떻게 해야 합니까?input로로 합니다.raw_input첫 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.input?? 위? 건?SyntaxError일어나길 기다리고 있어

재귀로 인해 스택이 날아가다

에 대해 지 안 '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다', '재귀하다 '에서 수 .get_non_negative_int한편, 루프를 반복하고 있습니다.

def get_non_negative_int(prompt):
    try:
        value = int(input(prompt))
    except ValueError:
        print("Sorry, I didn't understand that.")
        return get_non_negative_int(prompt)

    if value < 0:
        print("Sorry, your response must not be negative.")
        return get_non_negative_int(prompt)
    else:
        return value

은 대부분의가 비활성 충분히 됩니다.RuntimeError: maximum recursion depth exceeded 않을 할 수 바보는 1000번 연속 실수를 하지 않을 것'이라고 생각할 수 있지만, 바보의 독창성을 과소평가하고 있다.

왜 하필이면while True그리고 이 고리에서 벗어나면, 그리고 당신이 원하는 것은 일단 나이가 들면 멈추는 것이기 때문에 당신의 요구사항을 while 스테이트먼트에 넣을 수 있습니다.

age = None
while age is None:
    input_value = input("Please enter your age: ")
    try:
        # try and convert the string input to a number
        age = int(input_value)
    except ValueError:
        # tell the user off
        print("{input} is not a number, please enter a number only".format(input=input_value))
if age >= 18:
    print("You are able to vote in the United States!")
else:
    print("You are not able to vote in the United States.")

그 결과, 다음과 같은 결과가 됩니다.

Please enter your age: *potato*
potato is not a number, please enter a number only
Please enter your age: *5*
You are not able to vote in the United States.

나이에는 이치에 맞지 않는 값이 존재하지 않으며 코드는 비즈니스 프로세스의 논리를 따르기 때문에 이 방법은 효과가 있습니다.

비록 받아들여진 답변은 놀랍지만.또한 이 문제에 대한 빠른 해킹을 공유하고자 합니다.(이는 음의 나이 문제도 해결합니다.)

f=lambda age: (age.isdigit() and ((int(age)>=18  and "Can vote" ) or "Cannot vote")) or \
f(input("invalid input. Try again\nPlease enter your age: "))
print(f(input("Please enter your age: ")))

추신. 이 코드는 python 3.x용입니다.

기능적 접근 또는 "루프 없음"":

from itertools import chain, repeat

prompts = chain(["Enter a number: "], repeat("Not a number! Try again: "))
replies = map(input, prompts)
valid_response = next(filter(str.isdigit, replies))
print(valid_response)
Enter a number:  a
Not a number! Try again:  b
Not a number! Try again:  1
1

또는 다른 응답과 같이 입력 프롬프트에서 "bad input" 메시지를 분리하는 경우:

prompt_msg = "Enter a number: "
bad_input_msg = "Sorry, I didn't understand that."
prompts = chain([prompt_msg], repeat('\n'.join([bad_input_msg, prompt_msg])))
replies = map(input, prompts)
valid_response = next(filter(str.isdigit, replies))
print(valid_response)
Enter a number:  a
Sorry, I didn't understand that.
Enter a number:  b
Sorry, I didn't understand that.
Enter a number:  1
1

어떻게 작동합니까?

  1. prompts = chain(["Enter a number: "], repeat("Not a number! Try again: "))
    
    이 조합에 의해 스트링이 생성되는 반복기가 생성됩니다."Enter a number: " 번, 한 번, 한 번, 한 번"Not a number! Try again: " : an::
    for prompt in prompts:
        print(prompt)
    
    Enter a number: 
    Not a number! Try again: 
    Not a number! Try again: 
    Not a number! Try again: 
    # ... and so on
    
  2. replies = map(input, prompts)- 여기에서는 모든 것을 적용합니다.prompts이전 단계에서 함수에 대한 문자열입니다.예:
    for reply in replies:
        print(reply)
    
    Enter a number:  a
    a
    Not a number! Try again:  1
    1
    Not a number! Try again:  it doesn't care now
    it doesn't care now
    # and so on...
    
  3. 숫자만을 포함하는 문자열을 필터링하려면 및 을 사용합니다.
    only_digits = filter(str.isdigit, replies)
    for reply in only_digits:
        print(reply)
    
    Enter a number:  a
    Not a number! Try again:  1
    1
    Not a number! Try again:  2
    2
    Not a number! Try again:  b
    Not a number! Try again: # and so on...
    
    첫 번째 자리수 문자열만 가져오려면 을 사용합니다.

기타 검증 규칙:

  1. 문자열 방식: 물론 알파벳 문자열만 가져오거나 대문자만 가져오는 등의 다른 문자열 방식을 사용할 수 있습니다.전체 목록은 문서를 참조하십시오.

  2. 다음 중 하나:
    그것을 실행하는 방법에는 여러 가지가 있습니다.그 중 하나는 다음과 같은 방법을 사용하는 것입니다.

    from itertools import chain, repeat
    
    fruits = {'apple', 'orange', 'peach'}
    prompts = chain(["Enter a fruit: "], repeat("I don't know this one! Try again: "))
    replies = map(input, prompts)
    valid_response = next(filter(fruits.__contains__, replies))
    print(valid_response)
    
    Enter a fruit:  1
    I don't know this one! Try again:  foo
    I don't know this one! Try again:  apple
    apple
    
  3. 치치: :
    여기서 사용할 수 있는 유용한 비교 방법이 있습니다.예를 들어 (의 경우)<

    from itertools import chain, repeat
    
    prompts = chain(["Enter a positive number:"], repeat("I need a positive number! Try again:"))
    replies = map(input, prompts)
    numeric_strings = filter(str.isnumeric, replies)
    numbers = map(float, numeric_strings)
    is_positive = (0.).__lt__
    valid_response = next(filter(is_positive, numbers))
    print(valid_response)
    
    Enter a positive number: a
    I need a positive number! Try again: -5
    I need a positive number! Try again: 0
    I need a positive number! Try again: 5
    5.0
    

    또는 던더 방법(던더 = 이중 언더스코어)을 사용하지 않으려면 언제든지 자체 함수를 정의하거나 모듈의 함수를 사용할 수 있습니다.

  4. 로로: :
    여기서 사용할 수 있습니다.pathlib라이브러리 및 그 방법:

    from itertools import chain, repeat
    from pathlib import Path
    
    prompts = chain(["Enter a path: "], repeat("This path doesn't exist! Try again: "))
    replies = map(input, prompts)
    paths = map(Path, replies)
    valid_response = next(filter(Path.exists, paths))
    print(valid_response)
    
    Enter a path:  a b c
    This path doesn't exist! Try again:  1
    This path doesn't exist! Try again:  existing_file.txt
    existing_file.txt
    

시행 횟수 제한:

유저에게 무한회 질문으로 고문하고 싶지 않은 경우는, 의 호출로 제한을 지정할 수 있습니다.이는 함수에 기본값을 제공하는 것과 결합할 수 있습니다.

from itertools import chain, repeat

prompts = chain(["Enter a number:"], repeat("Not a number! Try again:", 2))
replies = map(input, prompts)
valid_response = next(filter(str.isdigit, replies), None)
print("You've failed miserably!" if valid_response is None else 'Well done!')
Enter a number: a
Not a number! Try again: b
Not a number! Try again: c
You've failed miserably!

입력 데이터 전처리:

사용자가 실수로 IN CAPS 또는 문자열의 선두 또는 끝에 공백이 있는 경우 입력을 거부하지 않을 수 있습니다.이러한 단순한 실수를 고려하여 및 방법을 적용하여 입력 데이터를 전처리할 수 있습니다.예를 들어 멤버십 테스트의 경우 코드는 다음과 같습니다.

from itertools import chain, repeat

fruits = {'apple', 'orange', 'peach'}
prompts = chain(["Enter a fruit: "], repeat("I don't know this one! Try again: "))
replies = map(input, prompts)
lowercased_replies = map(str.lower, replies)
stripped_replies = map(str.strip, lowercased_replies)
valid_response = next(filter(fruits.__contains__, stripped_replies))
print(valid_response)
Enter a fruit:  duck
I don't know this one! Try again:     Orange
orange

전처리에 사용할 함수가 많은 경우에는 함수 합성을 수행하는 함수를 사용하는 것이 더 쉬울 수 있습니다.예를 들어, 여기서부터의 것을 사용합니다.

from itertools import chain, repeat

from lz.functional import compose

fruits = {'apple', 'orange', 'peach'}
prompts = chain(["Enter a fruit: "], repeat("I don't know this one! Try again: "))
replies = map(input, prompts)
process = compose(str.strip, str.lower)  # you can add more functions here
processed_replies = map(process, replies)
valid_response = next(filter(fruits.__contains__, processed_replies))
print(valid_response)
Enter a fruit:  potato
I don't know this one! Try again:   PEACH
peach

검증 규칙 조합:

프로그램에서120살 의 나이를 때, 120살, 120살, 120살, 120살 정도의 나이를 .filter:

from itertools import chain, repeat

prompt_msg = "Enter your age (1-120): "
bad_input_msg = "Wrong input."
prompts = chain([prompt_msg], repeat('\n'.join([bad_input_msg, prompt_msg])))
replies = map(input, prompts)
numeric_replies = filter(str.isdigit, replies)
ages = map(int, numeric_replies)
positive_ages = filter((0).__lt__, ages)
not_too_big_ages = filter((120).__ge__, positive_ages)
valid_response = next(not_too_big_ages)
print(valid_response)

그러나 규칙이 많은 경우에는 논리적인 결합을 수행하는 함수를 구현하는 것이 좋습니다.다음 예에서는 ready를 사용합니다.

from functools import partial
from itertools import chain, repeat

from lz.logical import conjoin


def is_one_letter(string: str) -> bool:
    return len(string) == 1


rules = [str.isalpha, str.isupper, is_one_letter, 'C'.__le__, 'P'.__ge__]

prompt_msg = "Enter a letter (C-P): "
bad_input_msg = "Wrong input."
prompts = chain([prompt_msg], repeat('\n'.join([bad_input_msg, prompt_msg])))
replies = map(input, prompts)
valid_response = next(filter(conjoin(*rules), replies))
print(valid_response)
Enter a letter (C-P):  5
Wrong input.
Enter a letter (C-P):  f
Wrong input.
Enter a letter (C-P):  CDE
Wrong input.
Enter a letter (C-P):  Q
Wrong input.
Enter a letter (C-P):  N
N

유감스럽게도 실패한 케이스마다 커스텀메시지가 필요한 경우는 기능적인 방법이 없습니다.아니면, 적어도, 나는 찾을 수 없었다.

클릭 사용:

Click은 명령줄 인터페이스용 라이브러리로, 사용자에게 유효한 응답을 요청하기 위한 기능을 제공합니다.

간단한 예:

import click

number = click.prompt('Please enter a number', type=float)
print(number)
Please enter a number: 
 a
Error: a is not a valid floating point value
Please enter a number: 
 10
10.0

문자열 값을 플로트로 자동 변환한 방법에 주목하십시오.

값이 범위 내에 있는지 확인:

제공되는 사용자 지정 유형이 다릅니다.특정 범위의 번호를 얻으려면IntRange:

age = click.prompt("What's your age?", type=click.IntRange(1, 120))
print(age)
What's your age?: 
 a
Error: a is not a valid integer
What's your age?: 
 0
Error: 0 is not in the valid range of 1 to 120.
What's your age?: 
 5
5

중 도 있습니다.min ★★★★★★★★★★★★★★★★★」max:

age = click.prompt("What's your age?", type=click.IntRange(min=14))
print(age)
What's your age?: 
 0
Error: 0 is smaller than the minimum valid value 14.
What's your age?: 
 18
18

멤버십 테스트:

「」를 사용합니다.click.Choice이 검사는 기본적으로 대소문자를 구분합니다.

choices = {'apple', 'orange', 'peach'}
choice = click.prompt('Provide a fruit', type=click.Choice(choices, case_sensitive=False))
print(choice)
Provide a fruit (apple, peach, orange): 
 banana
Error: invalid choice: banana. (choose from apple, peach, orange)
Provide a fruit (apple, peach, orange): 
 OrAnGe
orange

경로 및 파일 작업:

「」의 click.Path도 있습니다.type은 기존 경로를 확인할 수 있습니다.

path = click.prompt('Provide path', type=click.Path(exists=True, resolve_path=True))
print(path)
Provide path: 
 nonexistent
Error: Path "nonexistent" does not exist.
Provide path: 
 existing_folder
'/path/to/existing_folder

을 읽고 은 다 같이 할 수 있어요.click.File:

file = click.prompt('In which file to write data?', type=click.File('w'))
with file.open():
    file.write('Hello!')
# More info about `lazy=True` at:
# https://click.palletsprojects.com/en/7.x/arguments/#file-opening-safety
file = click.prompt('Which file you wanna read?', type=click.File(lazy=True))
with file.open():
    print(file.read())
In which file to write data?: 
         # <-- provided an empty string, which is an illegal name for a file
In which file to write data?: 
 some_file.txt
Which file you wanna read?: 
 nonexistent.txt
Error: Could not open file: nonexistent.txt: No such file or directory
Which file you wanna read?: 
 some_file.txt
Hello!

기타 예:

비밀번호 확인:

password = click.prompt('Enter password', hide_input=True, confirmation_prompt=True)
print(password)
Enter password: 
 ······
Repeat for confirmation: 
 ·
Error: the two entered values do not match
Enter password: 
 ······
Repeat for confirmation: 
 ······
qwerty

기본값:

이 경우 값을 입력하지 않고 단순히 (또는 어떤 키를 사용하든) 누르면 기본값이 됩니다.

number = click.prompt('Please enter a number', type=int, default=42)
print(number)
Please enter a number [42]: 
 a
Error: a is not a valid integer
Please enter a number [42]: 
 
42

저는 Unix 철학을 매우 좋아합니다. "한 가지 일을 잘 해내세요.사용자 입력을 캡처하고 검증하는 절차는 두 가지입니다.

  • 에게 " " 입력 "로 요구get_input이 OK가 될
  • validator 할 수 get_input

다음과 같이 단순하게 유지할 수 있습니다(Python 3.8+, 바다코끼리 연산자 사용).

def get_input(
    prompt="Enter a value: ",
    validator=lambda x: True,
    error_message="Invalid input. Please try again.",
):
    while not validator(value := input(prompt)):
        print(error_message)
    return value

def is_positive_int(value):
    try:
        return int(value) >= 0
    except ValueError:
        return False

if __name__ == "__main__":
    val = get_input("Give a positive number: ", is_positive_int)
    print(f"OK, thanks for {val}")

샘플 실행:

Give a positive number: -5
Invalid input. Please try again.
Give a positive number: asdf
Invalid input. Please try again.
Give a positive number:
Invalid input. Please try again.
Give a positive number: 42
OK, thanks for 42

Python . 8 、 Python < 3 . 8 서 in 。get_input음음음같 뭇매하다

def get_input(
    prompt="Enter a value: ",
    validator=lambda x: True,
    error_message="Invalid input. Please try again.",
):
    while True:
        value = input(prompt)
        if validator(value):
            return value
        print(error_message)

때, 이거나, 이거나, 이거나, 이거나, 이거나, 이거나, 이거나, 이거나, 이거나, 이거나, 이거나, 이거나, 이거나, 것들을 다룰 수 있습니다.KeyboardInterrupt응용 프로그램을 종료하기 전에 종료 메시지를 인쇄합니다.필요에 따라 카운터를 사용하여 허용되는 재시도를 제한할 수 있습니다.

그래서 저는 최근에 이와 비슷한 것을 만지작거리다가 다음과 같은 해결책을 생각해 냈습니다. 정크푸드를 거부하는 방법을 이용해서 논리적인 방법으로 확인되기도 전에 말이죠.

read_single_keypress()customy https://stackoverflow.com/a/6599441/4532996

def read_single_keypress() -> str:
    """Waits for a single keypress on stdin.
    -- from :: https://stackoverflow.com/a/6599441/4532996
    """

    import termios, fcntl, sys, os
    fd = sys.stdin.fileno()
    # save old state
    flags_save = fcntl.fcntl(fd, fcntl.F_GETFL)
    attrs_save = termios.tcgetattr(fd)
    # make raw - the way to do this comes from the termios(3) man page.
    attrs = list(attrs_save) # copy the stored version to update
    # iflag
    attrs[0] &= ~(termios.IGNBRK | termios.BRKINT | termios.PARMRK
                  | termios.ISTRIP | termios.INLCR | termios. IGNCR
                  | termios.ICRNL | termios.IXON )
    # oflag
    attrs[1] &= ~termios.OPOST
    # cflag
    attrs[2] &= ~(termios.CSIZE | termios. PARENB)
    attrs[2] |= termios.CS8
    # lflag
    attrs[3] &= ~(termios.ECHONL | termios.ECHO | termios.ICANON
                  | termios.ISIG | termios.IEXTEN)
    termios.tcsetattr(fd, termios.TCSANOW, attrs)
    # turn off non-blocking
    fcntl.fcntl(fd, fcntl.F_SETFL, flags_save & ~os.O_NONBLOCK)
    # read a single keystroke
    try:
        ret = sys.stdin.read(1) # returns a single character
    except KeyboardInterrupt:
        ret = 0
    finally:
        # restore old state
        termios.tcsetattr(fd, termios.TCSAFLUSH, attrs_save)
        fcntl.fcntl(fd, fcntl.F_SETFL, flags_save)
    return ret

def until_not_multi(chars) -> str:
    """read stdin until !(chars)"""
    import sys
    chars = list(chars)
    y = ""
    sys.stdout.flush()
    while True:
        i = read_single_keypress()
        _ = sys.stdout.write(i)
        sys.stdout.flush()
        if i not in chars:
            break
        y += i
    return y

def _can_you_vote() -> str:
    """a practical example:
    test if a user can vote based purely on keypresses"""
    print("can you vote? age : ", end="")
    x = int("0" + until_not_multi("0123456789"))
    if not x:
        print("\nsorry, age can only consist of digits.")
        return
    print("your age is", x, "\nYou can vote!" if x >= 18 else "Sorry! you can't vote")

_can_you_vote()

전체 모듈은 여기에서 찾을 수 있습니다.

예:

$ ./input_constrain.py
can you vote? age : a
sorry, age can only consist of digits.
$ ./input_constrain.py 
can you vote? age : 23<RETURN>
your age is 23
You can vote!
$ _

이 구현의 특성은 숫자가 아닌 것을 읽는 즉시 stdin을 닫는다는 점에 유의하십시오.이후 Enter 키를 누르지 않았습니다.a하지만 숫자 뒤에 와야 했어요

해서 ''과 ''을 요.thismany()예를 들어, 3자리만 허용하도록 같은 모듈에서 기능합니다.

오류를 처리하고 반복하려면 try-except를 사용합니다.

while True:
    try:
        age = int(input("Please enter your age: "))
        if age >= 18:
            print("You are able to vote in the United States!")
        else:
            print("You are not able to vote in the United States.")
    except Exception as e:
        print("please enter number")

Daniel Q와 Patrick Artner의 훌륭한 제안을 바탕으로 더욱 일반화된 솔루션을 소개합니다.

# Assuming Python3
import sys

class ValidationError(ValueError):  # thanks Patrick Artner
    pass

def validate_input(prompt, cast=str, cond=(lambda x: True), onerror=None):
    if onerror==None: onerror = {}
    while True:
        try:
            data = cast(input(prompt))
            if not cond(data): raise ValidationError
            return data
        except tuple(onerror.keys()) as e:  # thanks Daniel Q
            print(onerror[type(e)], file=sys.stderr)

는 명시적인 .if ★★★★★★★★★★★★★★★★★」raise""가 " assert어설션 체크는 오프인 경우가 있습니다만, 견고성을 실현하기 위해서는 검증을 항상 온으로 할 필요가 있습니다.

이것은, 다른 검증 조건과 함께, 다른 종류의 입력을 취득하기 위해서 사용할 수 있습니다.예를 들어 다음과 같습니다.

# No validation, equivalent to simple input:
anystr = validate_input("Enter any string: ")

# Get a string containing only letters:
letters = validate_input("Enter letters: ",
    cond=str.isalpha,
    onerror={ValidationError: "Only letters, please!"})

# Get a float in [0, 100]:
percentage = validate_input("Percentage? ",
    cast=float, cond=lambda x: 0.0<=x<=100.0,
    onerror={ValidationError: "Must be between 0 and 100!",
             ValueError: "Not a number!"})

또는 원래 질문에 답하려면:

age = validate_input("Please enter your age: ",
        cast=int, cond=lambda a:0<=a<150,
        onerror={ValidationError: "Enter a plausible age, please!",
                 ValueError: "Enter an integer, please!"})
if age >= 18: 
    print("You are able to vote in the United States!")
else:
    print("You are not able to vote in the United States.")
def validate_age(age):
    if age >=0 :
        return True
    return False

while True:
    try:
        age = int(raw_input("Please enter your age:"))
        if validate_age(age): break
    except ValueError:
        print "Error: Invalid age."

이것을 사용해 보세요:-

def takeInput(required):
  print 'ooo or OOO to exit'
  ans = raw_input('Enter: ')

  if not ans:
      print "You entered nothing...!"
      return takeInput(required) 

      ##  FOR Exit  ## 
  elif ans in ['ooo', 'OOO']:
    print "Closing instance."
    exit()

  else:
    if ans.isdigit():
      current = 'int'
    elif set('[~!@#$%^&*()_+{}":/\']+$').intersection(ans):
      current = 'other'
    elif isinstance(ans,basestring):
      current = 'str'        
    else:
      current = 'none'

  if required == current :
    return ans
  else:
    return takeInput(required)

## pass the value in which type you want [str/int/special character(as other )]
print "input: ", takeInput('str')

좋은 질문입니다!이 경우 다음 코드를 사용해 보십시오.=)

이 코드는 입력의 데이터 유형을 검색하기 위해 ast.literal_eval()을 사용합니다.age하다

  1. 에게 입력 age.

    1 1.1의 경우agefloat ★★★★★★★★★★★★★★★★★」int다음 중 하나:

    • age>=18.age>=18하여 종료합니다

    • 0<age<18.0<age<18하여 종료합니다

    • ifage<=0유효한 에이징 번호를 다시 입력하도록 사용자에게 요청합니다(즉, 순서 1로 돌아갑니다).

    1 1.2의 경우agefloat ★★★★★★★★★★★★★★★★★」int데이터 유형을 선택한 후 사용자에게 나이를 다시 입력하도록 요청합니다(즉, 1단계로 돌아갑니다).

여기 암호가 있습니다.

from ast import literal_eval

''' This function is used to identify the data type of input data.'''
def input_type(input_data):
    try:
        return type(literal_eval(input_data))
    except (ValueError, SyntaxError):
        return str

flag = True

while(flag):
    age = raw_input("Please enter your age: ")

    if input_type(age)==float or input_type(age)==int:
        if eval(age)>=18: 
            print("You are able to vote in the United States!") 
            flag = False 
        elif eval(age)>0 and eval(age)<18: 
            print("You are not able to vote in the United States.") 
            flag = False
        else: print("Please enter a valid number as your age.")

    else: print("Sorry, I didn't understand that.") 

사용자가 참 값을 입력할 때까지 "while" 문을 사용하여 입력 값이 숫자가 아니거나 null 값인 경우 건너뛰고 다시 물어봅니다.예를 들어, 저는 당신의 질문에 진정으로 답하려고 노력했습니다.연령이 1에서 150 사이라고 가정하면 입력값이 받아들여집니다.그렇지 않으면 잘못된 값입니다.프로그램을 종료할 경우 사용자는 0 키를 사용하여 값으로 입력할 수 있습니다.

주의: 코드의 맨 위에 있는 코멘트를 읽습니다.

# If your input value is only a number then use "Value.isdigit() == False".
# If you need an input that is a text, you should remove "Value.isdigit() == False".
def Input(Message):
    Value = None
    while Value == None or Value.isdigit() == False:
        try:        
            Value = str(input(Message)).strip()
        except Exception:
            Value = None
    return Value

# Example:
age = 0
# If we suppose that our age is between 1 and 150 then input value accepted,
# else it's a wrong value.
while age <=0 or age >150:
    age = int(Input("Please enter your age: "))
    # For terminating program, the user can use 0 key and enter it as an a value.
    if age == 0:
        print("Terminating ...")
        exit(0)
        
if age >= 18 and age <=150: 
    print("You are able to vote in the United States!")
else:
    print("You are not able to vote in the United States.")

하여 if-else 로직을 하나 더할 수 .if과 '로직'을합니다.forloopsyslog.syslog..syslog.

while True:
     age = int(input("Please enter your age: "))
     if (age >= 18)  : 
         print("You are able to vote in the United States!")
     if (age < 18) & (age > 0):
         print("You are not able to vote in the United States.")
     else:
         print("Wrong characters, the input must be numeric")
         continue

이것은 무한한 화장실이고 당신은 나이를 무한히 입력하도록 요구받을 것이다.

try/except이할 수 있는 은 '블럭'을 사용하는 것입니다.를 사용하는 것입니다.이 작업을 수행하는 보다 빠르고 깨끗한 방법은str.isdigit().

while True:
    age = input("Please enter your age: ")
    if age.isdigit():
        age = int(age)
        break
    else:
        print("Invalid number '{age}'. Try again.".format(age=age))

if age >= 18: 
    print("You are able to vote in the United States!")
else:
    print("You are not able to vote in the United States.")

많은 실제 애플리케이션에서 동일한 사용 사례가 발생하기 때문에 사용자가 특정 횟수만 입력할 수 있도록 보다 일반적인 논리를 작성할 수 있습니다.

def getValidInt(iMaxAttemps = None):
  iCount = 0
  while True:
    # exit when maximum attempt limit has expired
    if iCount != None and iCount > iMaxAttemps:
       return 0     # return as default value

    i = raw_input("Enter no")
    try:
       i = int(i)
    except ValueError as e:
       print "Enter valid int value"
    else:
       break

    return i

age = getValidInt()
# do whatever you want to do.

입력문을 True 루프 상태에서 잠시 설정할 수 있습니다.이것에 의해, 유저의 입력을 반복해 요구해, 유저가 원하는 응답을 입력했을 때에 루프가 끊어집니다.또한 시행 및 제외 블록을 사용하여 잘못된 응답을 처리할 수 있습니다.

while True:

    var = True

    try:
        age = int(input("Please enter your age: "))

    except ValueError:
        print("Invalid input.")
        var = False

    if var == True:
        if age >= 18:
                print("You are able to vote in the United States.")
                break
        else:
            print("You are not able to vote in the United States.")

var 변수는 사용자가 정수 대신 문자열을 입력하면 프로그램에서 "You cannot to balling in the United States"를 반환하지 않도록 하는 것입니다.

을 사용한 하기 위한 ValidationError의 (: integer (sublic) " " " " :

class ValidationError(ValueError): 
    """Special validation error - its message is supposed to be printed"""
    pass

def RangeValidator(text,num,r):
    """Generic validator - raises 'text' as ValidationError if 'num' not in range 'r'."""
    if num in r:
        return num
    raise ValidationError(text)

def ValidCol(c): 
    """Specialized column validator providing text and range."""
    return RangeValidator("Columns must be in the range of 0 to 3 (inclusive)", 
                          c, range(4))

def ValidRow(r): 
    """Specialized row validator providing text and range."""
    return RangeValidator("Rows must be in the range of 5 to 15(exclusive)",
                          r, range(5,15))

사용방법:

def GetInt(text, validator=None):
    """Aks user for integer input until a valid integer is given. If provided, 
    a 'validator' function takes the integer and either raises a 
    ValidationError to be printed or returns the valid number. 
    Non integers display a simple error message."""
    print()
    while True:
        n = input(text)
        try:
            n = int(n)

            return n if validator is None else validator(n)

        except ValueError as ve:
            # prints ValidationErrors directly - else generic message:
            if isinstance(ve, ValidationError):
                print(ve)
            else:
                print("Invalid input: ", n)


column = GetInt("Pleased enter column: ", ValidCol)
row = GetInt("Pleased enter row: ", ValidRow)
print( row, column)

출력:

Pleased enter column: 22
Columns must be in the range of 0 to 3 (inclusive)
Pleased enter column: -2
Columns must be in the range of 0 to 3 (inclusive)
Pleased enter column: 2
Pleased enter row: a
Invalid input:  a
Pleased enter row: 72
Rows must be in the range of 5 to 15(exclusive)
Pleased enter row: 9  

9, 2

재귀 함수를 사용한 지속적 사용자 입력:

스트링

def askName():
    return input("Write your name: ").strip() or askName()

name = askName()

정수

def askAge():
    try: return int(input("Enter your age: "))
    except ValueError: return askAge()

age = askAge()

마지막으로 질문요건은 다음과 같습니다.

def askAge():
    try: return int(input("Enter your age: "))
    except ValueError: return askAge()

age = askAge()

responseAge = [
    "You are able to vote in the United States!",
    "You are not able to vote in the United States.",
][int(age < 18)]

print(responseAge)

정수로 변환할 수 있지만, 작동하지 않으면 반복하도록 사용자에게 요청할 수 있습니다.

while True:
    age = input('Please enter your age: ')
    try:
        age_int = int(age)
        if age_int >= 18:
            print('You can vote in the United States!')
        else:
            print('You cannot vote in the United States.')
        break
    except:
        print('Please enter a meaningful answer.')
        

while 루프는 사용자가 의미 있는 답변을 입력하지 않은 한 실행되지만 의미가 있을 경우 끊어집니다.

isdigit()문자열이 유효한 정수를 나타내는지 여부를 확인합니다.

재귀 함수를 사용할 수 있습니다.

def ask():
    answer = input("Please enter amount to convert: ")
    if not answer.isdigit():
        print("Invalid")
        return ask()

    return int(answer)

Gdp = ask()

또는 while 루프

while True:
    answer = input("Please enter amount to convert: ")
    if not answer.isdigit():
        print("Invalid")
        continue

    Gbp = int(answer)

아래 코드가 도움이 될 수 있습니다.

age=(lambda i,f: f(i,f))(input("Please enter your age: "),lambda i,f: i if i.isdigit() else f(input("Please enter your age: "),f))
print("You are able to vote in the united states" if int(age)>=18 else "You are not able to vote in the united states",end='')

최대 시도 횟수(예: 3)를 원할 경우 아래 코드를 사용하십시오.

age=(lambda i,n,f: f(i,n,f))(input("Please enter your age: "),1,lambda i,n,f: i if i.isdigit() else (None if n==3 else f(input("Please enter your age: "),n+1,f)))
print("You are able to vote in the united states" if age and int(age)>=18 else "You are not able to vote in the united states",end='')

주의: 재귀가 사용됩니다.

언급URL : https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response

반응형