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
หรือหากคุณต้องการให้มีข้อความ "อินพุตไม่ถูกต้อง" แยกจากพรอมต์อินพุตเหมือนกับคำตอบอื่น ๆ :
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
มันทำงานยังไง?
prompts = chain(["Enter a number: "], repeat("Not a number! Try again: "))
การรวมกันของitertools.chain
และitertools.repeat
จะสร้างตัววนซ้ำซึ่งจะให้ผลสตริง"Enter a number: "
หนึ่งครั้งและ"Not a number! Try again: "
จำนวนอนันต์:
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)
- ที่นี่map
จะใช้prompts
สตริงทั้งหมดจากขั้นตอนก่อนหน้ากับinput
ฟังก์ชั่น เช่น:
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...
- เราใช้
filter
และstr.isdigit
กรองสตริงที่มีตัวเลขเท่านั้น:
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...
next
และเพื่อให้ได้เพียงตัวเลขเพียงครั้งแรกที่ใช้สตริงเรา
กฎการตรวจสอบอื่น ๆ :
วิธีการสตริง:แน่นอนคุณสามารถใช้วิธีการสตริงอื่น ๆ ที่str.isalpha
จะได้รับเพียงสตริงตัวอักษรหรือstr.isupper
เพื่อให้ได้ตัวพิมพ์ใหญ่เท่านั้น ดูเอกสารสำหรับรายการทั้งหมด
การทดสอบความเป็นสมาชิก:
มีหลายวิธีในการดำเนินการ หนึ่งในนั้นคือโดยใช้__contains__
วิธีการ:
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
การเปรียบเทียบตัวเลข:
มีวิธีการเปรียบเทียบที่มีประโยชน์ซึ่งเราสามารถใช้ได้ที่นี่ ตัวอย่างเช่นสำหรับ__lt__
( <
):
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
หรือถ้าคุณไม่ชอบการใช้วิธีการ dunder (dunder = double-underscore) คุณสามารถกำหนดฟังก์ชั่นของคุณเองหรือใช้สิ่งที่อยู่ในoperator
โมดูล
เส้นทางที่อยู่: ที่
นี่หนึ่งสามารถใช้pathlib
ไลบรารีและPath.exists
วิธีการ:
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
จำนวนครั้งที่ จำกัด :
หากคุณไม่ต้องการที่จะทรมานผู้ใช้โดยขอให้เขาบางสิ่งบางจำนวนอนันต์ครั้งคุณสามารถระบุขีด จำกัด itertools.repeat
ในการเรียกของ สิ่งนี้สามารถใช้ร่วมกับการให้ค่าเริ่มต้นกับnext
ฟังก์ชั่น:
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!
การประมวลผลข้อมูลอินพุตล่วงหน้า:
บางครั้งเราไม่ต้องการปฏิเสธอินพุตหากผู้ใช้ป้อนโดยไม่ตั้งใจในCAPSหรือมีช่องว่างในการเริ่มต้นหรือสิ้นสุดของสตริง ในการพิจารณาความผิดพลาดง่าย ๆ เหล่านี้เราสามารถประมวลผลข้อมูลอินพุตล่วงหน้าได้โดยการใช้str.lower
และstr.strip
วิธีการ ตัวอย่างเช่นสำหรับกรณีของการเป็นสมาชิกการทดสอบรหัสจะมีลักษณะเช่นนี้:
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
การรวมกฎการตรวจสอบ:
ตัวอย่างเช่นกรณีที่เมื่อโปรแกรมถามอายุระหว่าง 1 ถึง 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)
แต่ในกรณีที่มีกฎระเบียบมากจะดีกว่าที่จะใช้ฟังก์ชั่นการดำเนินการร่วมตรรกะ ในตัวอย่างต่อไปนี้ฉันจะใช้พร้อมจากที่นี่ :
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
แต่ถ้ามีคนต้องการที่ข้อความที่กำหนดเองสำหรับแต่ละกรณีล้มเหลวแล้วฉันกลัวไม่มีสวยวิธีการทำงาน หรืออย่างน้อยฉันก็หาไม่เจอ