If Yes Is Entered Run the Program Again Python3
8
INPUT VALIDATION
Input validation code checks that values entered by the user, such every bit text from the input() function, are formatted correctly. For example, if you want users to enter their ages, your code shouldn't take nonsensical answers such as negative numbers (which are outside the range of adequate integers) or words (which are the wrong data type). Input validation can too prevent bugs or security vulnerabilities. If you implement a withdrawFromAccount() function that takes an statement for the amount to subtract from an account, y'all need to ensure the corporeality is a positive number. If the withdrawFromAccount() function subtracts a negative number from the account, the "withdrawal" will cease up adding coin!
Typically, we perform input validation by repeatedly asking the user for input until they enter valid text, equally in the following instance:
while True:
impress('Enter your age:')
historic period = input()
try:
age = int(historic period)
except:
print('Please use numeric digits.')
keep
if age < 1:
impress('Please enter a positive number.')
go on
break
print(f'Your age is {historic period}.')
When you run this program, the output could look like this:
Enter your age:
five
Please use numeric digits.
Enter your historic period:
-two
Delight enter a positive number.
Enter your age:
30
Your age is xxx.
When you run this code, y'all'll exist prompted for your age until you enter a valid ane. This ensures that by the time the execution leaves the while loop, the historic period variable will incorporate a valid value that won't crash the program subsequently on.
However, writing input validation code for every input() phone call in your program quickly becomes tedious. Also, yous may miss sure cases and allow invalid input to pass through your checks. In this affiliate, you'll acquire how to use the 3rd-party PyInputPlus module for input validation.
The PyInputPlus Module
PyInputPlus contains functions similar to input() for several kinds of data: numbers, dates, email addresses, and more. If the user always enters invalid input, such as a badly formatted engagement or a number that is outside of an intended range, PyInputPlus will reprompt them for input just similar our code in the previous section did. PyInputPlus also has other useful features like a limit for the number of times information technology reprompts users and a timeout if users are required to respond inside a time limit.
PyInputPlus is not a office of the Python Standard Library, so you must install information technology separately using Pip. To install PyInputPlus, run pip install --user pyinputplus from the command line. Appendix A has consummate instructions for installing third-party modules. To check if PyInputPlus installed correctly, import it in the interactive shell:
>>> import pyinputplus
If no errors appear when y'all import the module, it has been successfully installed.
PyInputPlus has several functions for different kinds of input:
inputStr() Is like the born input() function but has the general PyInputPlus features. You can also pass a custom validation function to it
inputNum() Ensures the user enters a number and returns an int or bladder, depending on if the number has a decimal signal in it
inputChoice() Ensures the user enters one of the provided choices
inputMenu() Is similar to inputChoice(), just provides a menu with numbered or lettered options
inputDatetime() Ensures the user enters a date and time
inputYesNo() Ensures the user enters a "yes" or "no" response
inputBool() Is like to inputYesNo(), but takes a "True" or "Fake" response and returns a Boolean value
inputEmail() Ensures the user enters a valid e-mail address
inputFilepath() Ensures the user enters a valid file path and filename, and tin can optionally check that a file with that name exists
inputPassword() Is like the built-in input(), but displays * characters equally the user types so that passwords, or other sensitive data, aren't displayed on the screen
These functions volition automatically reprompt the user for as long as they enter invalid input:
>>> import pyinputplus equally pyip
>>> response = pyip.inputNum()
five
'5' is not a number.
42
>>> response
42
The as pyip lawmaking in the import statement saves us from typing pyinputplus each time nosotros desire to phone call a PyInputPlus function. Instead we can employ the shorter pyip proper name. If you take a wait at the example, you see that dissimilar input(), these functions return an int or float value: 42 and 3.14 instead of the strings '42' and '3.14'.
Only as you can pass a string to input() to provide a prompt, you can pass a cord to a PyInputPlus function's prompt keyword argument to brandish a prompt:
>>> response = input('Enter a number: ')
Enter a number: 42
>>> response
'42'
>>> import pyinputplus as pyip
>>> response = pyip.inputInt(prompt='Enter a number: ')
Enter a number: cat
'true cat' is not an integer.
Enter a number: 42
>>> response
42
Employ Python'south assistance() function to find out more about each of these functions. For instance, assistance(pyip.inputChoice) displays assistance data for the inputChoice() function. Consummate documentation tin be found at https://pyinputplus.readthedocs.io/.
Dissimilar Python's built-in input(), PyInputPlus functions have several additional features for input validation, as shown in the next section.
The min, max, greaterThan, and lessThan Keyword Arguments
The inputNum(), inputInt(), and inputFloat() functions, which accept int and float numbers, also have min, max, greaterThan, and lessThan keyword arguments for specifying a range of valid values. For example, enter the post-obit into the interactive beat:
>>> import pyinputplus every bit pyip
>>> response = pyip.inputNum('Enter num: ', min=four)
Enter num:three
Input must be at minimum 4.
Enter num:four
>>> response
4
>>> response = pyip.inputNum('Enter num: ', greaterThan=4)
Enter num: 4
Input must be greater than 4.
Enter num: five
>>> response
five
>>> response = pyip.inputNum('>', min=4, lessThan=vi)
Enter num: 6
Input must be less than 6.
Enter num: 3
Input must exist at minimum 4.
Enter num: 4
>>> response
4
These keyword arguments are optional, merely if supplied, the input cannot be less than the min argument or greater than the max argument (though the input can be equal to them). Also, the input must be greater than the greaterThan and less than the lessThan arguments (that is, the input cannot be equal to them).
The bare Keyword Statement
Past default, blank input isn't immune unless the blank keyword argument is prepare to Truthful:
>>> import pyinputplus as pyip
>>> response = pyip.inputNum('Enter num: ')
Enter num:(blank input entered here)
Blank values are not immune.
Enter num: 42
>>> response
42
>>> response = pyip.inputNum(bare=True)
(bare input entered here)
>>> response
''
Use bare=Truthful if you'd like to make input optional so that the user doesn't need to enter anything.
The limit, timeout, and default Keyword Arguments
By default, the PyInputPlus functions will continue to ask the user for valid input forever (or for as long as the program runs). If you'd like a function to stop asking the user for input after a sure number of tries or a certain amount of time, you tin can use the limit and timeout keyword arguments. Pass an integer for the limit keyword statement to make up one's mind how many attempts a PyInputPlus function will make to receive valid input before giving up, and pass an integer for the timeout keyword statement to decide how many seconds the user has to enter valid input earlier the PyInputPlus function gives upwards.
If the user fails to enter valid input, these keyword arguments will cause the function to raise a RetryLimitException or TimeoutException, respectively. For case, enter the following into the interactive shell:
>>> import pyinputplus every bit pyip
>>> response = pyip.inputNum(limit=2)
apathetic
'blah' is not a number.
Enter num: number
'number' is not a number.
Traceback (most recent call last):
--snip--
pyinputplus.RetryLimitException
>>> response = pyip.inputNum(timeout=10)
42 (entered later 10 seconds of waiting)
Traceback (about recent call last):
--snip--
pyinputplus.TimeoutException
When you use these keyword arguments and likewise pass a default keyword statement, the function returns the default value instead of raising an exception. Enter the following into the interactive beat:
>>> response = pyip.inputNum(limit=ii, default='N/A')
hullo
'howdy' is not a number.
world
'world' is not a number.
>>> response
'Northward/A'
Instead of raising RetryLimitException, the inputNum() function simply returns the string 'North/A'.
The allowRegexes and blockRegexes Keyword Arguments
Yous tin can also utilise regular expressions to specify whether an input is allowed or not. The allowRegexes and blockRegexes keyword arguments take a list of regular expression strings to determine what the PyInputPlus function volition accept or reject as valid input. For instance, enter the following lawmaking into the interactive shell so that inputNum() volition accept Roman numerals in addition to the usual numbers:
>>> import pyinputplus equally pyip
>>> response = pyip.inputNum(allowRegexes=[r'(I|V|X|Fifty|C|D|Grand)+', r'goose egg'])
XLII
>>> response
'XLII'
>>> response = pyip.inputNum(allowRegexes=[r'(i|5|x|fifty|c|d|yard)+', r'naught'])
xlii
>>> response
'xlii'
Of course, this regex affects only what letters the inputNum() office will accept from the user; the function volition notwithstanding accept Roman numerals with invalid ordering such as 'XVX' or 'MILLI' considering the r'(I|V|X|L|C|D|M)+' regular expression accepts those strings.
You can as well specify a listing of regular expression strings that a PyInputPlus function won't accept by using the blockRegexes keyword statement. Enter the following into the interactive shell so that inputNum() won't accept even numbers:
>>> import pyinputplus equally pyip
>>> response = pyip.inputNum(blockRegexes=[r'[02468]$'])
42
This response is invalid.
44
This response is invalid.
43
>>> response
43
If you specify both an allowRegexes and blockRegexes argument, the allow listing overrides the block listing. For example, enter the following into the interactive vanquish, which allows 'caterpillar' and 'category' but blocks anything else that has the word 'cat' in it:
>>> import pyinputplus every bit pyip
>>> response = pyip.inputStr(allowRegexes=[r'caterpillar', 'category'],
blockRegexes=[r'cat'])
cat
This response is invalid.
catastrophe
This response is invalid.
category
>>> response
'category'
The PyInputPlus module'southward functions tin can salvage you from writing irksome input validation lawmaking yourself. But there's more to the PyInputPlus module than what has been detailed here. Y'all can examine its total documentation online at https://pyinputplus.readthedocs.io/.
Passing a Custom Validation Role to inputCustom()
You tin can write a function to perform your ain custom validation logic past passing the part to inputCustom(). For instance, say you desire the user to enter a series of digits that adds up to 10. There is no pyinputplus.inputAddsUpToTen() function, but you can create your own function that:
- Accepts a single string statement of what the user entered
- Raises an exception if the string fails validation
- Returns None (or has no return argument) if inputCustom() should return the string unchanged
- Returns a non-None value if inputCustom() should render a different string from the one the user entered
- Is passed every bit the beginning argument to inputCustom()
For instance, we can create our ain addsUpToTen() role, and then pass it to inputCustom(). Note that the office phone call looks like inputCustom(addsUpToTen) and non inputCustom(addsUpToTen()) because we are passing the addsUpToTen() office itself to inputCustom(), not calling addsUpToTen() and passing its return value.
>>> import pyinputplus as pyip
>>> def addsUpToTen(numbers):
...numbersList = list(numbers)
...for i, digit in enumerate(numbersList):
...numbersList[i] = int(digit)
...if sum(numbersList) != ten:
...raise Exception('The digits must add up to 10, not %s.' %
(sum(numbersList)))
...return int(numbers) # Return an int class of numbers.
...
>>> response = pyip.inputCustom(addsUpToTen) # No parentheses after
addsUpToTen hither.
123
The digits must add upwardly to x, not 6.
1235
The digits must add up to 10, not 11.
1234
>>> response # inputStr() returned an int, non a string.
1234
>>> response = pyip.inputCustom(addsUpToTen)
howdy
invalid literal for int() with base 10: 'h'
55
>>> response
The inputCustom() office also supports the general PyInputPlus features, such as the blank, limit, timeout, default, allowRegexes, and blockRegexes keyword arguments. Writing your ain custom validation function is useful when it's otherwise difficult or impossible to write a regular expression for valid input, as in the "adds upwardly to 10" example.
Projection: How to Keep an Idiot Busy for Hours
Allow'southward utilize PyInputPlus to create a simple program that does the following:
- Ask the user if they'd like to know how to continue an idiot busy for hours.
- If the user answers no, quit.
- If the user answers yes, go to Step ane.
Of course, nosotros don't know if the user will enter something besides "yep" or "no," so we need to perform input validation. Information technology would likewise be convenient for the user to be able to enter "y" or "north" instead of the full words. PyInputPlus's inputYesNo() function will handle this for u.s. and, no matter what case the user enters, return a lowercase 'yes' or 'no' string value.
When y'all run this program, information technology should look like the following:
Want to know how to go along an idiot busy for hours?
sure
'sure' is not a valid yes/no response.
Want to know how to go on an idiot busy for hours?
yes
Want to know how to keep an idiot decorated for hours?
y
Want to know how to keep an idiot busy for hours?
Yes
Desire to know how to continue an idiot busy for hours?
Yes
Desire to know how to go on an idiot decorated for hours?
YES!!!!!!
'Yep!!!!!!' is not a valid yeah/no response.
Desire to know how to go along an idiot decorated for hours?
TELL ME HOW TO KEEP AN IDIOT BUSY FOR HOURS.
'TELL ME HOW TO Continue AN IDIOT BUSY FOR HOURS.' is not a valid yes/no response.
Want to know how to proceed an idiot busy for hours?
no
Give thanks y'all. Take a nice day.
Open up a new file editor tab and salvage it as idiot.py. And so enter the following code:
import pyinputplus every bit pyip
This imports the PyInputPlus module. Since pyinputplus is a bit much to type, we'll use the proper name pyip for brusque.
while True:
prompt = 'Desire to know how to keep an idiot busy for hours?\n'
response = pyip.inputYesNo(prompt)
Next, while True: creates an infinite loop that continues to run until information technology encounters a break statement. In this loop, we call pyip.inputYesNo() to ensure that this part call won't render until the user enters a valid answer.
if response == 'no':
interruption
The pyip.inputYesNo() phone call is guaranteed to only return either the string yep or the string no. If information technology returned no, and so our program breaks out of the infinite loop and continues to the last line, which cheers the user:
impress('Give thanks you. Accept a nice day.')
Otherwise, the loop iterates in one case once again.
You can as well make employ of the inputYesNo() function in non-English language languages by passing yesVal and noVal keyword arguments. For example, the Spanish version of this program would take these ii lines:
prompt = '¿Quieres saber cómo mantener ocupado a un idiota durante horas?\due north'
response = pyip.inputYesNo(prompt, yesVal='sí', noVal='no')
if response == 'sí':
Now the user can enter either sí or southward (in lower- or uppercase) instead of aye or y for an affirmative respond.
Project: Multiplication Quiz
PyInputPlus's features tin be useful for creating a timed multiplication quiz. By setting the allowRegexes, blockRegexes, timeout, and limit keyword argument to pyip.inputStr(), y'all can leave most of the implementation to PyInputPlus. The less code you need to write, the faster y'all tin write your programs. Permit's create a program that poses x multiplication issues to the user, where the valid input is the problem's right answer. Open up a new file editor tab and save the file every bit multiplicationQuiz.py.
First, nosotros'll import pyinputplus, random, and time. We'll keep rail of how many questions the program asks and how many correct answers the user gives with the variables numberOfQuestions and correctAnswers. A for loop volition repeatedly pose a random multiplication trouble x times:
import pyinputplus as pyip
import random, time
numberOfQuestions = ten
correctAnswers = 0
for questionNumber in range(numberOfQuestions):
Inside the for loop, the programme will pick ii single-digit numbers to multiply. We'll use these numbers to create a #Q: North × N = prompt for the user, where Q is the question number (ane to 10) and N are the two numbers to multiply.
# Pick two random numbers:
num1 = random.randint(0, 9)
num2 = random.randint(0, 9)
prompt = '#%s: %due south x %due south = ' % (questionNumber, num1, num2)
The pyip.inputStr() part will handle most of the features of this quiz plan. The argument we pass for allowRegexes is a list with the regex cord '^%southward$', where %s is replaced with the correct reply. The ^ and % characters ensure that the answer begins and ends with the correct number, though PyInputPlus trims any whitespace from the start and end of the user's response beginning but in case they inadvertently pressed the spacebar before or later their answer. The argument we pass for blocklistRegexes is a listing with ('.*', 'Incorrect!'). The showtime string in the tuple is a regex that matches every possible string. Therefore, if the user response doesn't match the correct answer, the programme volition reject whatever other answer they provide. In that example, the 'Incorrect!' string is displayed and the user is prompted to answer again. Additionally, passing 8 for timeout and three for limit will ensure that the user only has 8 seconds and 3 tries to provide a correct answer:
endeavour:
# Correct answers are handled by allowRegexes.
# Wrong answers are handled past blockRegexes, with a custom message.
pyip.inputStr(prompt, allowRegexes=['^%s$' % (num1 * num2)],
blockRegexes=[('.*', 'Incorrect!')],
timeout=8, limit=three)
If the user answers after the eight-2d timeout has expired, even if they answer correctly, pyip.inputStr() raises a TimeoutException exception. If the user answers incorrectly more than than 3 times, information technology raises a RetryLimitException exception. Both of these exception types are in the PyInputPlus module, so pyip. needs to prepend them:
except pyip.TimeoutException:
impress('Out of time!')
except pyip.RetryLimitException:
impress('Out of tries!')
Remember that, just similar how else blocks can follow an if or elif block, they can optionally follow the final except block. The code inside the following else block will run if no exception was raised in the try cake. In our case, that ways the lawmaking runs if the user entered the correct answer:
else:
# This block runs if no exceptions were raised in the endeavour block.
print('Correct!')
correctAnswers += 1
No matter which of the three messages, "Out of fourth dimension!", "Out of tries!", or "Correct!", displays, permit's identify a one-second pause at the terminate of the for loop to give the user fourth dimension to read it. Afterwards the plan has asked x questions and the for loop continues, permit's show the user how many correct answers they fabricated:
time.sleep(ane) # Brief pause to let user run across the result.
print('Score: %south / %due south' % (correctAnswers, numberOfQuestions))
PyInputPlus is flexible enough that you can use information technology in a wide diverseness of programs that take keyboard input from the user, equally demonstrated past the programs in this affiliate.
Summary
It'due south easy to forget to write input validation code, but without it, your programs will almost certainly have bugs. The values you look users to enter and the values they actually enter can be completely different, and your programs need to be robust enough to handle these infrequent cases. Y'all can utilize regular expressions to create your own input validation code, only for mutual cases, it's easier to employ an existing module, such equally PyInputPlus. You lot tin import the module with import pyinputplus equally pyip then that yous tin can enter a shorter name when calling the module's functions.
PyInputPlus has functions for entering a multifariousness of input, including strings, numbers, dates, yep/no, True/Simulated, emails, and files. While input() always returns a string, these functions return the value in an appropriate information type. The inputChoice() office permit you to select one of several pre-selected options, while inputMenu() also adds numbers or letters for quick selection.
All of these functions have the following standard features: stripping whitespace from the sides, setting timeout and retry limits with the timeout and limit keyword arguments, and passing lists of regular expression strings to allowRegexes or blockRegexes to include or exclude particular responses. Yous'll no longer need to write your own tedious while loops that bank check for valid input and reprompt the user.
If none of the PyInputPlus module's, functions fit your needs, simply you'd still like the other features that PyInputPlus provides, you tin call inputCustom() and laissez passer your own custom validation function for PyInputPlus to use. The documentation at https://pyinputplus.readthedocs.io/en/latest/ has a complete listing of PyInputPlus's functions and additional features. In that location's far more in the PyInputPlus online documentation than what was described in this chapter. There'south no use in reinventing the bicycle, and learning to employ this module will save you from having to write and debug code for yourself.
Now that you lot have expertise manipulating and validating text, it'due south time to larn how to read from and write to files on your computer's difficult bulldoze.
Practice Questions
i. Does PyInputPlus come up with the Python Standard Library?
2. Why is PyInputPlus commonly imported with import pyinputplus every bit pyip?
three. What is the difference between inputInt() and inputFloat()?
4. How can you ensure that the user enters a whole number between 0 and 99 using PyInputPlus?
5. What is passed to the allowRegexes and blockRegexes keyword arguments?
6. What does inputStr(limit=3) exercise if blank input is entered three times?
seven. What does inputStr(limit=3, default='hello') exercise if blank input is entered three times?
Practice Projects
For practice, write programs to practise the following tasks.
Sandwich Maker
Write a program that asks users for their sandwich preferences. The program should use PyInputPlus to ensure that they enter valid input, such as:
- Using inputMenu() for a bread blazon: wheat, white, or sourdough.
- Using inputMenu() for a poly peptide blazon: chicken, turkey, ham, or tofu.
- Using inputYesNo() to inquire if they want cheese.
- If then, using inputMenu() to inquire for a cheese type: cheddar, Swiss, or mozzarella.
- Using inputYesNo() to enquire if they desire mayo, mustard, lettuce, or tomato.
- Using inputInt() to inquire how many sandwiches they want. Make sure this number is ane or more.
Come up with prices for each of these options, and accept your program display a full cost afterward the user enters their selection.
Write Your Ain Multiplication Quiz
To encounter how much PyInputPlus is doing for you, effort re-creating the multiplication quiz project on your own without importing it. This program will prompt the user with 10 multiplication questions, ranging from 0 × 0 to ix × 9. You'll need to implement the following features:
- If the user enters the correct reply, the plan displays "Correct!" for ane second and moves on to the adjacent question.
- The user gets iii tries to enter the correct reply before the program moves on to the next question.
- Eight seconds subsequently outset displaying the question, the question is marked equally wrong even if the user enters the correct respond after the 8-2nd limit.
Compare your code to the code using PyInputPlus in "Project: Multiplication Quiz" on page 196.
Source: https://automatetheboringstuff.com/2e/chapter8/
Post a Comment for "If Yes Is Entered Run the Program Again Python3"