Kullanıcıdan geçerli bir yanıt verene kadar girdi istemek
Kullanıcıdan bir girdi kabul eden bir program yazıyorum.
#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.")
Program, kullanıcı anlamlı veriler girdiği sürece beklendiği gibi çalışır.
C:\Python\Projects> canyouvote.py
Please enter your age: 23
You are able to vote in the United States!
Ancak kullanıcı geçersiz veri girerse başarısız olur:
C:\Python\Projects> canyouvote.py
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'
Kilitlenmek yerine, programın girişi tekrar istemesini istiyorum. Bunun gibi:
C:\Python\Projects> canyouvote.py
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!
Anlamsız veriler girildiğinde programın çökmek yerine geçerli girdiler istemesini nasıl sağlayabilirim?
Bu bağlamda -1
geçerli int
ama anlamsız olan gibi değerleri nasıl reddedebilirim ?
Yanıtlar
Bunu başarmanın en basit yolu, input
yöntemi bir süre döngüsüne koymaktır . Kullanım continue
kötü girişini olsun ve break
döngünün dışında size şüpheniz yoksa.
Girişiniz Ne Zaman Bir İstisna Yaratabilir?
Kullanıcının ayrıştırılamayan verileri girdiğini algılamak için try
veexcept
kullanın .
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.")
Kendi Doğrulama Kurallarınızı Uygulama
Python'un başarıyla ayrıştırabildiği değerleri reddetmek istiyorsanız, kendi doğrulama mantığınızı ekleyebilirsiniz.
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
İstisna İşlemeyi ve Özel Doğrulamayı Birleştirme
Yukarıdaki tekniklerin her ikisi de tek bir döngüde birleştirilebilir.
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.")
Hepsini bir Fonksiyonda Kapsülleme
Kullanıcınızdan çok sayıda farklı değer istemeniz gerekiyorsa, bu kodu bir işleve koymanız faydalı olabilir, böylece her seferinde yeniden yazmanıza gerek kalmaz.
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: ")
Hepsini bir araya koy
Çok genel bir girdi işlevi yapmak için bu fikri genişletebilirsiniz:
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
Gibi kullanımlarla:
age = sanitised_input("Enter your age: ", int, 1, 101)
answer = sanitised_input("Enter your answer: ", str.lower, range_=('a', 'b', 'c', 'd'))
Yaygın Tuzaklar ve Neden Onlardan Kaçınmalısınız
Gereksiz input
İfadelerin Gereksiz Kullanımı
Bu yöntem işe yarıyor, ancak genellikle kötü stil olarak kabul ediliyor:
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): ")
Başlangıçta while True
yöntemden daha kısa olduğu için çekici görünebilir , ancak yazılım geliştirmenin Kendini Tekrar Etme ilkesini ihlal ediyor . Bu, sisteminizdeki hata olasılığını artırır. Ya olarak değiştirerek 2.7'ye backport input
yapmak raw_input
, ancak kazara sadece input
yukarıdakini değiştirmek istiyorsanız? Bu SyntaxError
sadece gerçekleşmesini bekliyor.
Özyineleme Yığını Patlatacak
Özyinelemeyi yeni öğrendiyseniz, onu kullanmak isteyebilirsiniz, get_non_negative_int
böylece while döngüsünden kurtulabilirsiniz.
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
Bu, çoğu zaman iyi çalışıyor gibi görünüyor, ancak kullanıcı yeterince geçersiz veri girerse, komut dosyası bir RuntimeError: maximum recursion depth exceeded
. "Hiçbir aptal arka arkaya 1000 hata yapmaz" diye düşünebilirsiniz, ama aptalların yaratıcılığını küçümsüyorsunuz!
Neden bir yapıp while True
sonra bu döngüden çıkarsınız ki, aynı zamanda gereksinimlerinizi while deyimine koyabilirsiniz, çünkü tek istediğiniz yaşınız olduğunda durmaktır?
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.")
Bu, aşağıdakilere neden olur:
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.
bu işe yarayacak çünkü yaş hiçbir zaman anlamsız bir değere sahip olmayacak ve kod "iş sürecinizin" mantığını takip ediyor
Kabul edilen cevap şaşırtıcı olsa da. Ayrıca bu sorun için hızlı bir hack paylaşmak istiyorum. (Bu, negatif yaş sorununu da çözer.)
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: ")))
PS Bu kod python 3.x içindir.
İşlevsel yaklaşım veya " anne bak, döngü yok! ":
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
veya diğer yanıtlarda olduğu gibi bir giriş isteminden ayrılmış bir "hatalı giriş" mesajına sahip olmak istiyorsanız:
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
O nasıl çalışır?
-
Bu kombinasyonuprompts = chain(["Enter a number: "], repeat("Not a number! Try again: "))
itertools.chain
veitertools.repeat
dizeleri verecektir bir yineleyici yaratacak"Enter a number: "
bir kez ve"Not a number! Try again: "
zaman sonsuz sayıda: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
replies = map(input, prompts)
- burada önceki adımdakimap
tümprompts
dizelerinput
işleve uygulanacaktır. Örneğin: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...
- Yalnızca rakam içeren dizeleri filtrelemek için
filter
ve kullanırızstr.isdigit
:only_digits = filter(str.isdigit, replies) for reply in only_digits: print(reply)
Ve sadece ilk rakamlardan oluşan dizeyi elde etmek için kullandığımızEnter 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...
next
.
Diğer doğrulama kuralları:
Dize yöntemleri: Elbette
str.isalpha
, yalnızca alfabetik dizelerstr.isupper
elde etmek veya yalnızca büyük harf almak gibi diğer dize yöntemlerini kullanabilirsiniz . Tam liste için belgelere bakın .Üyelik testi:
Bunu gerçekleştirmenin birkaç farklı yolu vardır. Bunlardan biri__contains__
yöntemi kullanmaktır :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
Sayı karşılaştırması:
Burada kullanabileceğimiz yararlı karşılaştırma yöntemleri vardır. Örneğin,__lt__
(<
) için: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
Ya da, dunder yöntemlerini kullanmayı sevmiyorsanız (dunder = çift alt çizgi), her zaman kendi işlevinizi tanımlayabilir veya
operator
modülden olanları kullanabilirsiniz .Yol varlığı:
Buradapathlib
kitaplık vePath.exists
yöntemi kullanılabilir: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
Deneme sayısını sınırlama:
Bir kullanıcıya sonsuz sayıda bir şey sorarak işkence yapmak istemiyorsanız, bir çağrıda bir sınır belirleyebilirsiniz itertools.repeat
. Bu, next
işleve varsayılan bir değer sağlamakla birleştirilebilir :
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!
Giriş verilerini ön işleme:
Bazen, kullanıcı yanlışlıkla CAPS İÇİNDE sağladıysa veya dizenin başında veya sonunda bir boşluk bıraktıysa , bir girişi reddetmek istemeyiz . Bu basit hataları hesaba katmak için, girdi verilerini str.lower
ve str.strip
yöntemlerini uygulayarak önceden işleyebiliriz . Örneğin, üyelik testi durumunda kod şu şekilde görünecektir:
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
Önişleme için kullanabileceğiniz çok sayıda işleviniz olması durumunda, bir işlev bileşimi gerçekleştiren bir işlevi kullanmak daha kolay olabilir . Örneğin, buradakini kullanarak :
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
Doğrulama kurallarını birleştirmek:
Basit bir durum için, örneğin, program 1 ile 120 arasında yaş sorduğunda, biri başka bir tane ekleyebilir 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)
Ancak birçok kuralın olduğu durumda, mantıksal bir birleşim gerçekleştiren bir işlevi uygulamak daha iyidir . Aşağıdaki örnekte buradan hazır olanı kullanacağım :
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
Ne yazık ki, başarısız olan her vaka için birisinin özel bir mesaja ihtiyacı varsa, o zaman korkarım, oldukça işlevsel bir yol yoktur . Ya da en azından bir tane bulamadım.
Son zamanlarda buna benzer bir şeyle uğraşıyordum ve mantıksal bir şekilde kontrol edilmeden önce gereksiz verileri reddeden bir girdi elde etmenin bir yolunu kullanan aşağıdaki çözümü buldum.
read_single_keypress()
nezaket 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()
Modülün tamamını burada bulabilirsiniz .
Misal:
$ ./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!
$ _
Bu gerçeklenmenin doğası gereği, basamak olmayan bir şey okunduğu anda stdin'i kapatır. Daha sonra enter tuşuna basmadım a
ama rakamlardan sonra girmem gerekiyordu.
Bunu, thismany()
yalnızca, örneğin üç basamağa izin vermek için aynı modüldeki işlevle birleştirebilirsiniz .
Click Kullanımı :
Tıklama , komut satırı arayüzleri için bir kitaplıktır ve bir kullanıcıdan geçerli bir yanıt istemek için işlevsellik sağlar.
Basit örnek:
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
Dize değerini otomatik olarak bir kayan noktaya nasıl dönüştürdüğüne dikkat edin.
Bir değerin bir aralıkta olup olmadığını kontrol etme:
Sağlanan farklı özel türler vardır . Belirli bir aralıkta bir sayı elde etmek için kullanabiliriz 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
Ayrıca sınırlardan yalnızca birini de belirtebiliriz min
veya 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
Üyelik testi:
click.Choice
Tür kullanarak . Varsayılan olarak bu kontrol büyük / küçük harfe duyarlıdır.
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
Yollar ve dosyalarla çalışma:
Bir click.Path
tür kullanarak mevcut yolları kontrol edebilir ve bunları çözebiliriz:
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
Dosyaları okuma ve yazma şu şekilde yapılabilir 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!
Diğer örnekler:
Şifre onayı:
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
Varsayılan değerler:
Bu durumda, Enterbir değer girmeden (veya kullandığınız herhangi bir tuşa) basmanız size varsayılan bir değer verecektir:
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
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."
Daniel Q'nun ve Patrick Artner'ın mükemmel önerilerine dayanarak, işte daha da genelleştirilmiş bir çözüm.
# 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)
Bir yerine açık if
ve raise
ifadeleri tercih ettim assert
, çünkü onaylama kontrolü kapatılabilir, oysa sağlamlık sağlamak için doğrulama her zaman açık olmalıdır.
Bu, farklı doğrulama koşulları ile farklı türde girdiler elde etmek için kullanılabilir. Örneğin:
# 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!"})
Veya orijinal soruyu cevaplamak için:
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.")
Bunu dene:-
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')
Evet, 🎉'dan 6 yıl geciktim ama bu soru daha güncel bir cevabı hak ediyor.
Endişelerin ayrılması
Unix felsefesinin büyük bir hayranıyım "Bir şeyi yap ve onu iyi yap" . Bu tür bir problemde, problemi ikiye bölmek daha iyi bir uygulamadır.
- Giriş
get_input
tamam olana kadar giriş isteyin . validator
İşlev olarak doğrulayın . Farklı giriş sorguları için farklı doğrulayıcılar yazabilirsiniz.
Girdi sormak
(Python 3+) kadar basit tutulabilir
def myvalidator(value):
try:
value = int(value)
except ValueError:
return False
return value >= 0
def get_input(prompt, validator, on_validationerror):
while True:
value = input(prompt)
if validator(value):
return value
print(on_validationerror)
Misal
In [2]: get_input('Give a positive number: ', myvalidator, 'Please, try again')
Give a positive number: foobar
Please, try again
Give a positive number: -10
Please, try again
Give a positive number: 42
Out[2]: '42'
Python 3.8+ Not
Python 3.8+ sürümünde mors operatörünü kullanabilirsiniz
def get_input(prompt, validator, on_validationerror):
while not validator(value := input(prompt)):
print(on_validationerror)
return value
A try
/ except
block çalışırken, bu görevi gerçekleştirmenin çok daha hızlı ve temiz bir yolu kullanmak olacaktır 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.")
İyi soru! Bunun için aşağıdaki kodu deneyebilirsiniz. =)
Bu kod, kullanımları ast.literal_eval () için giriş veri yapısını ( age
). Ardından aşağıdaki algoritmayı takip eder:
Kullanıcıdan kendisini girmesini isteyin
age
.1.1. Eğer
age
birfloat
ya daint
veri türü:
Kontrol edin
age>=18
. Eğerage>=18
, uygun çıktıyı yazdırın ve çıkın.Kontrol edin
0<age<18
. Eğer0<age<18
, uygun çıktıyı yazdırın ve çıkın.Eğer
age<=0
, yaş için geçerli bir sayı tekrar girişine kullanıcıya sor, ( yani geri adım 1. gidin)1.2. Eğer
age
değilfloat
yaint
veri türü, daha sonra onu / yeniden kendi yaş (giriş için kullanıcı sormak yani 1. adımda geri dönmek)
İşte kod.
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.")
Her zaman basit aksi takdirde if
mantığını uygulayabilir ve kodunuza bir for
döngü ile birlikte bir mantık daha ekleyebilirsiniz .
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
Bu sonsuz bir tuvalet olacak ve sizden süresiz olarak çağa girmeniz istenecek.
Aşağıdaki kod yardımcı olabilir.
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='')
Maksimum deneme yapmak istiyorsanız, 3 diyelim, aşağıdaki kodu kullanın
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='')
Not: Bu, özyinelemeyi kullanır.
Hatayı işlemek ve tekrarlamak için try-hariç'i kullanın:
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")