Input Validation

One common reason for programs crashing is bad input.
Input Validation is used to check that any data entered by a user is suitable before it is used by the program.
To avoid making the program too complex, validation routines can be written as subprograms.

Subprograms:

  • Must be defined at the start of the program, before they are used by the main program
  • Can be copied and customised between programs
  • Can be tested separately

In Python, all sub-programs are technically known as functions.

  • Functions are defined with the def keyword. The code inside a function definition will not be executed unless you call the function.
  • You must give your functions a name. It should be named in lower case using underscores_to_join_words.
  • When you 'use' your function, you call it. You can call your function as many times as you wish.

Simple Function Example

Here is a pretty basic example of defining and then using a function 'subprogram' in Python.
Run this code and you should see a small part of the two times table, twice over.


In [ ]:
def my_function():
    """print a bit of the two times table"""
    for i in [4,5,6]:
        print("{0} times 2 = {1}".format(i, i*2))
        
print("Part of The 2 Times Table Program")
my_function()
print("\nHere it is again")
my_function()

Simple Function Exercise

To see if you've got the basic idea, finish this little function or subprogram.
Change the empty print() function on the third line to print("A wee hello message!")


In [ ]:
def wee_function():
    """print a wee message"""
    print()
    
print("Let's call your function:")
wee_function()
print("Now call it again:")
wee_function()

What you should see...

If you've done it right your output should look something like this:

Let's call your function: A wee hello message! Now call it again: A wee hello message!

The important thing to notice is that you only need to tell Python how to print("A wee hello message") at one point in the program (i.e. in the function definition). You can then call that function multiple times and have it execute your code.

Function Arguments

To be more useful, functions can accept arguments. Below, there is a function to print a personalised welcome message.

  • The argument in this function is name.
  • Whatever value (string or otherwise) you pass to the function when you call it will be loaded into the variable name.
  • You can see that name gets used 3 times within the function.
  • You can change name to be any variable name you like, as long as you change it everywhere within the function. name's value will not be available outside the function (technically, it has local scope and exists only within the function's stack frame).
  • name is a therefore called a dummy variable.

In [ ]:
def welcome(name):
    if name=="Donald Trump":
        print("Gonnae no dae that?",name,"just, gonnae no?")
    else:
        print("Welcome", name, "great things await no doubt.")
        
print("Welcome to the Welcome Program")
welcome("Boris")
welcome("Donald Trump")
welcome(32)

Functions Can Return Values

Continuing with their desire to be useful, functions can return a value. So what does that mean? Here's a couple of examples. We have a function that returns either True or False depending on what day of the week it is, and another function which returns double it's argument.

  • Notice that both functions take arguments (although functions can return a value whether or not they takes arguments)
  • Notice that neither function prints anything. This is generally good practice - separate processing from output.
  • The values returned from the functions can be assigned to variables (otherwise they are instantly destroyed).
  • The values returned can be passed directly into a print function (or passed into any other function)

Run the code and make sure that you understand why what gets printed in which order.
[Is that bad grammar? Don't tell your English teecher].


In [ ]:
def day_of_the_week(day):
    if day=="Saturday" or day=="Sunday":
        message = "It is the weekend. Yay."
    elif day in ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]:
        message = "It is not the weekend, nay."
    else:
        message = "You are an idiot."
    return message
        
print(day_of_the_week("Saturday")) #this prints immediately.
day_of_the_week("Sunday") #oops, not doing anything with the return value: destroyed.
response = day_of_the_week("Monday") #this doesn't get printed, yet
print(day_of_the_week("Monster Munch")) #this also prints immediately.
print(response) #now that earlier message gets printed

Validating Strings

This function will let the user type in either “Y”, “N”,”Yes” or “No” in any combination of capital and lowercase letters. Either a “Y” or “N” is sent back to the main program.

Run it and enter N at the prompt. Eventually the happy police will wear you down to conformance.


In [ ]:
def get_yes_or_no(prompt):
    """Input validation returning either Y or N"""
    yesno = input(prompt)
    yesno = yesno.upper()
    while not(yesno in ["Y", "N", "YES", "NO"]):
        print("Invalid Input")
        yesno = input(prompt)
        yesno = yesno.upper()
    return yesno[0] # first char of string guaranteed to be Y or N

# Sample program
happy = get_yes_or_no("Are you happy?")
while happy=="N":
    print("Be happy")
    happy = get_yes_or_no("Are you happy?")
print("I'm happy too. ")

Validating Integers

A common validation is to check that only whole numbers within a certain range are entered – a range check. In Python this requires two subprograms:

  • one to stop text or decimal inputs crashing the program
    you should copy this get_integer function exactly as it is.
  • one to check the number is in the range
    you should copy and customise this function for different tasks, giving it a sensible name of your own choosing.

In [ ]:
def get_integer(prompt):
    """Display prompt and get integer without crashing"""
    while True:
        try:
            i = int(input(prompt))
            return i
        except ValueError:
            print("That is not an integer")
            
def get_valid_class_size(prompt):
    """Get a class size from 0 to 30. Uses the get_integer function"""
    class_size =get_integer(prompt)
    while class_size<0 or class_size>30:
        print("Invalid - must be from 0 to 30")
        class_size = get_integer(prompt)
    return class_size

#Sample Program
class1 = get_valid_class_size("How many pupils in Mr T's class?")
class2 = get_valid_class_size("How many pupils in Ms S's class?")
both_classes = class1 + class2
print("Total number of pupils = ", both_classes)

Validating Real Numbers

In Python this requires two subprograms:

  • one to stop text inputs crashing the program
    you should copy this get_decimal function exactly as it is
  • one to check the number is in the range
    you should copy and customise this function for different tasks

In [ ]:
def get_decimal(prompt):
    """Display prompt and get number without crashing"""
    while True:
        try:
            i = float(input(prompt))
            return i
        except ValueError:
            print("That is not a number")
            
def get_valid_price(prompt):
    """Get a price from 0.01 to 100.00"""
    price = get_decimal(prompt)
    while price<0.01 or price>100.00:
        print("Invalid - must be from £0.01 to £100.00")
        price = get_decimal(prompt)
    return price

# Sample program
book1 = get_valid_price("How much is book 1? ")
book2 = get_valid_price("How much is book 2? ")
both_books = book1 + book2
print("Total price £", both_books)

You can now complete tasks 36-38