faculty.cse.tamu.edufaculty.cse.tamu.edu/slupoli/notes/Python/PythonValidationNotes.docx · Web...

33
Validation and Debugging Why do we validate?? remember users make mistakes and don't follow directions data entered into a database, not good if you have to run back to the user to fix their error!! Some research should go into what value your variable could possibly be o ex: IQ values can be from 0 (brain dead) to over 140 What data type best fits?? Variable/User Input Data type Variable/User Input Data type Telephone (no dashes) Days in a year SSN US Citizen Day within a month (1~31) Passengers on a Cruise Ship Yes/No answer Normal home loan amount When to use integer/float vs. string? integer should be used only if there is math involved o does adding 2 zip codes equal to anything important? ~ NO 1

Transcript of faculty.cse.tamu.edufaculty.cse.tamu.edu/slupoli/notes/Python/PythonValidationNotes.docx · Web...

Validation and DebuggingWhy do we validate??

remember users make mistakes and don't follow directions data entered into a database, not good if you have to run back to the user to fix

their error!! Some research should go into what value your variable could possibly be

o ex: IQ values can be from 0 (brain dead) to over 140

What data type best fits??Variable/User Input Data type Variable/User Input Data typeTelephone (no dashes) Days in a yearSSN US CitizenDay within a month (1~31) Passengers on a Cruise ShipYes/No answer Normal home loan amount

When to use integer/float vs. string? integer should be used only if there is math involved

o does adding 2 zip codes equal to anything important? ~ NOo does adding 3 SSN equal to anything important? ~ NOo does adding 3 days in a year equal to anything important? ~ YES

otherwise a string can hold the value (which looks like an int/float)

1

Avoiding input validation problems Range check

o numbers checked to ensure they are within a range of possible values, e.g., the value for month should lie between 1 and 12.

Reasonable checko values are checked for their reasonableness, e.g. (age > 16) && (age <

100) Divide by Zero

o variables are checked for values that might cause problems such as division by zero.

Length checko variables are checked to ensure they are the appropriate length, for

example, a US telephone number has 10 digits. Format check

o Checks that the data is in a specified format (template), e.g., dates have to be in the format DD/MM/YYYY.

Available optionso Check items selected from a menu or sets of choices to ensure they are

possible options: that is, always include a default

2

Setting up from word problemsThings to remember:

1. What are valid ranges? May have to do some research!!2. What datatype should we be using??3. What should the default value be? (Keep it simple)

a. Default value should make the loop run again!4. What are we checking for??

a. Datatypeb. Range of values within that datatype

Data Possible Ranges (think like a lawyer!!) Datatype

Abbr. State (US) WIDE Range, but 2 letters long StringUS Zip codeRadio (freq) station (FM for car)

SSNAirport codeDigits (Texting)Even number (not going to tell you) (N/A)

3

"Do While" Loops There are none in Python for you experienced programmers!!

While Loops Condition is tested before body of the loop Non-counter loop by default

o can certainly add that feature Loop only runs if the condition is TRUE

o so if we are DONE with the loop, we want the condition to fail (False)

While Loop StructureFlowchart Example

4

Looping for a valid ranged number if we need a range of values this will work for both ints and floats used a "flag" to continue the loop

First Validation Loop with Numbersflag = True

value = -1

while(flag == True): # Loop will only run if Flag is TRUE# but only need while(flag)

value = int(input("Please enter a number between 0 and 100: "))

# determine if input was valid if((value >= 0) and (value <= 100)): #input WAS valid, so end the loop flag = False else: print("Input was invalid. Please try again")

print("The value you entered correctly was " , value)

simpleValidation.py

Why did I have to set the flag to True in line 1?The last line that prints will ONLY happen when?Why didn't I reset the flag to True in the "else" clause?

Create a validation loop that will loop with a String. The loop will continue UNTIL the user types in “Quit” (case-sensative). Name it firstValidation.py. Answerb:

5

Looking for certain input within a slight range

overall set is EXACTLY the same, but we compare the input to a LIST of possible items we are looking foro notice the list isn't TOO BIGo notice, anything is that list, will have the SAME outcome

(flag = False) awesome!!

Validation Loop w/ multiple ending possibilitiesflag = True

value = -1

while(flag == True): # Loop will only run if Flag is TRUE# but only need while(flag)

value = input("Please enter 'Quit' to exit the Loop.")

# determine if input was valid if( value in ["Quit", "quit", "q", "Q", "QUIT"] ): #input WAS valid, so end the loop flag = False else: print("Input was not 'Quit'. Please try again")

print("You have successfully entered 'Quit'. We are out of the loop")

6

Wrong Type of Input Remember

o user make mistakeso the graders will TRY to crash your code

The program will crash if we put in the wrong type of input

Expected type mismatch error

we can use a try/except structureo much like try/catch for Java programmers

this avoids any crashes!! we recover from a mistakes of the user

expected input received input result Use try/except?int int OK Yes

float BOOM!!String BOOM!!

float int OK Yesfloat OKString BOOM!!

String int OK Nofloat OKString OK

7

Using String functions to help ID user input

here we gather input as a String, then determine what numeric value data type it could be

there are great functions for Strings and Integerso but not floats!!!

The world of testing a string for it’s true valueData Datatype isalnum() isdigit() isdecimal() isnumeric() isalpha()123 int True True True True False123.23 float False False False False False123.23.23 crap/String False False False False FalseLupoli String True (?) False False False True

notice NOTHING works for a float (solved-ish below) o if we eliminate that it wasn’t a String or Int, then must be a float

Looking for an Int from a String Inputflag = True#WE WANT A INTEGER! (But receiving as a string 1st)value1 = "" #for now a string, will be converted later

while(flag == True):

# gather input from user as String for now, then try to convert later value1 = input("Enter an INTEGER value: ")

# test to see if the String entered by the user is if (value1.isdigit() == True): print("value is an integer") int(value1) #cast to an integer flag = False #since we got what we wanted elif (value1.isalpha() == True): print("value is a String") else: # because everything else has been checked, must be a float print("value is a float")

print(value1)

8

Looking for an Float from a String Input flag = True #WE WANT A FLOAT! (But receiving as a string 1st) value1 = "" #for now a string, will be converted later

while(flag == True):

# gather input from user as String for now, then try to convert later value1 = input("Enter a FLOAT value: ")

# test to see if the String entered by the user is if (value1.isdigit() == True): print("value is an integer") elif (value1.isalpha() == True): print("value is a String") else: # because everything else has been checked, must be a float print("value is a float") float(value1) flag = False #since we got what we wanted

print(value1)

Try/except Blocks These will contain/recover from errors so not to END your entire application

o used for many items such as: File I/O Input from the keyboard

This will NOT work for Stringso since everything we type could be considered a String!

an error is called an EXCEPTIONo there are many methods we use the THROW an exception

also, where you don’t care what the input waso compared to above

9

First try/except Exampleflag = True

value = -1

while(flag):

try: value = int(input("Please enter a number between 0 and 100: "))

#determine if input was valid if((value >= 0) and (value <= 100)): #input WAS valid, so end the loop flag = False else: print("Input was invalid. Please try again")

except ValueError: print("Numbers only please") except NameError: print("Numbers only please")

Showing the try/except at work

10

try and except are reserved wordso try -> "try to do something that may cause an error"o except -> "catch that error"

you can have SEVERAL "except"o there is a finally clause

won't go over here structure is exactly the same an if-elif

o if Tryo elif except

try/except structure

while(condition):try:

# code that may generate an exception

except (Exception's ):# code to recover from the error

11

Types of errors we can detect there are several common exceptions

Some of the Python Built in error detectorsException DetectsZeroDivisionError divided by zero somewhereValueError receives an argument that has the right type but an

inappropriate valueNameError variable name not foundTypeError wrong data type

See here for full list: http://docs.python.org/release/2.6/library/exceptions.html

you can use SEVERAL exceptions in the same try

This really protecting from errors!!def main(): print(“This program finds the real solutions to a quadratic\n")

while(Flag):

try: a, b, c = int(input("Please enter the coefficients (a, b, c): ")) discRoot = math.sqrt(b * b - 4 * a * c) root1 = (-b + discRoot) / (2 * a) root2 = (-b - discRoot) / (2 * a) print(“\nThe solutions are:", root1, root2 except ValueError, excObj: msg = str(excObj) if msg == "math domain error": print(“No Real Roots") elif msg == "unpack tuple of wrong size": print(“You didn't give me the right number of coefficients.") else: print(“Something went wrong, sorry!") except NameError: print(“\nYou didn't enter three numbers.") except TypeError: print(“\nYour inputs were not all numbers.") except SyntaxError: print(“\nYour input was not in the correct form. Missing comma(s), perhaps?") except: print(“\nSomething went wrong, sorry!")

main()

12

Why NOT to use “except” alone will pick up ANY error!! this really won’t tell us anything!!

But what if we need to check a String? what if a String has bad data with in??!

o everything is a String!!o how can we check for bad data within a String

Good intentions but…We want valid: Good String Data Bad String Data Bad Data a String?

Last name Lupoli Lupoli2 YupLast name Lupoli Lupol i YupLast name Lupoli *Lupoli Yup

The world of testing a string … Version 2Data isalnum() isalpha() isdigit() isdecimal() isnumeric()Lupoli True True False False FalseLupoli2 True False False False FalseLupol i False False False False False*Lupoli False False False False False

Search from Python String Methods, determine which each function above (isalnum, isalpha, etc…) does. Make certain you are looking at Python 3 material.

13

String functions aren’t enough (Bad string data)

the given string methods might not cover what you need to check within a String we must

o look at each charactero know what functions will help us ID an invalid character

you can look at individual chars inside a string use the char functions to determine what is inside that string

string line = “Goodbye, Cruel World”;

G o o d b y e , C r u e l W o r l d ! \0√ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √Total = 17

hasDigits exampledef hasDigits(str1):

for element in str1: # select a character within the string if element.isdigit(): # is that character a digit? return True

# if it made it here, then it did not have any Digits in it return False

14

Using TDD to design a validation program TDD = Top Down Design again, another game-planning design with more details/less code

TDD For Validating a UsernameThe Code The TDD

notice the arrowso mean the call and the return from the function

TDD For Validating a UsernameThe Code The TDD

Draw what the TDD would be for the function validateInput?

15

typo askUserInput()

TDD For Validating a UsernameThe Code The TDD

Exercise: Given a string from the user, validate that it is indeed a valid SSN

a. use the code given to help

http://faculty.cse.tamu.edu/slupoli/notes/Python/code/Validation/TDDValidation.py

b. Find Good and Bad inputsc. within the main, with a simple GOOD example input string:

a. identify what string functions will work (if any) to determine there is an error (use the notes!)

b. identify is the string functions are enoughi. then what will you be looking for individually?

d. Use what you created in the main and the TDD model and finish your codingAnswerb:

16

Detecting Logical Errors Since you are getting more advanced in programming, here are some helpful

hints when things get rough Each may be adapted into what you need

Tracing simple displays USED FOR RUN TIME ERRORS ONLY!!! determine where the program jammed

o great for finding functions that are not working

Example of Tracing…print( "got here\n") # trace statementgreeting()print( "got here 1\n") # trace statementcalculate(x, y)print( "got here 2\n") # trace statement…

1. If you only see "got here" and "got here 1", where did the program jam??2. If you only see "got here", where did the program jam??

17

The Debug Clause Used when in developing the program easy to shut off when done since it uses a global boolean flag

o just set to false when you're done can be used to show values passed in, steps the program is completing, etc.. should be placed in first few lines of EACH function

o except main( )

Debug Clause Example

DEBUG= True # global flag

def main(… ):

..

def calculate( x, y, z)

if(DEBUG): # why not "debug = = 1"?? print ("values passed into CALCULATE are: \n") print( "int x = " + x + "\n") print( "int y = " + y + "\n") print( "int z = " + z + "\n")

… # rest of code

Create validPassword.py that will validate:a. length of received password < 12 charactersb. does not have punctuation (use “in” or find string function) c. has at LEAST 1 uppercase letter

Answerb:

Make sure a response on WHY it is wrong is displayed. No datatype validation is needed!! (But why?)

18

Checking what we DID get from the user here we are using the try/catch mechanism to further break down what type

the value could have been that was typed in from a user outer try/catch identifies if the input was an integer

o if not, then the inner try/catch checks to see if it is a float IF THAT FAILS – then it was a string or something else

What datatype was entered?realValue = None

value = input("Enter a value to be checked")

try: realValue = int(value) print("If it reached here, then it was a int")except ValueError: print("Not an integer")

# yes this validation statement is INSIDE the previous one # this validation will happen ONLY IF the previous threw an exception try: realValue = float(value) print("If it reached here, then it was a float") except ValueError: print("Not an float")

print(realValue)

19

Slowing the display down while debugging, you might want to have some delay feature to be able to

read everything sleep does this must import time

Using sleep in a debug situation# File: password.py# Author: Michael Ravikovitch – CTY ‘15# Date: 7/9/2015# E-mail:# Description:# This code tests your skills as a hacker.

import timedef main(): variable = 0 passWord = input("Enter the secret password: ") for i in range(0,101): time.sleep(0.25) print("Hacking...",variable,"%") variable += 1

print("Hack complete. Im in.")

main()

Create the program "averageValidation.py" to accept 3 float values and average them. You MUST use the ValueError to validate your program. Test your program by trying to break it!! Answersb: Testing thoughts#1 #2 #3 #4 #512.5 Crap 12.5 12 012.5 12.5 Crap 12.5 012.5 12.5 12.5 12.5 0

20

Answer SectionQuit Validation Loop

flag = Truevalue = -1

while(flag == True): # Loop will only run if Flag is TRUE# but only need while(flag)

value = input("Please enter 'Quit' to exit the Loop.")

# determine if input was valid if( value == "Quit"): #input WAS valid, so end the loop flag = False else: print("Input was not 'Quit'. Please try again")

print("You have successfully entered 'Quit'. We are out of the loop")

SSN Checkerhttps://www.youtube.com/watch?v=sxZV8-bccgE

Password checkerVersion #1

# File:    inclass2.py# Author:  …# Date:    1/8/2014# Section:# E-mail:  [email protected]# Description:# This program checks password validity

def main():    flag = True    while(flag):         checkedValue = input("Please input a password that has at least 1 upper case"\                             " no punctuation and a length less than 12\n")        if( any(c.isupper() for c in checkedValue) ):            if( len(checkedValue) < 12):                if(checkedValue.isalnum()):                    print("Congrats! That's a valid password!")                    flag = False #no more looping                else:                    print("Sorry, you have punctuation in your password")            else:                print("Sorry, your length >= 12 characters")        else:            print("Sorry, you need at least one upper case letter")main()

Version #221

Version #3flag = Truepwd = ""

while(flag == True): # Loop will only run if Flag is TRUE# but only need while(flag)

        pwd = input("Please enter a password : ")        upperCase = False        noPunc = True        for i in pwd:            if i.isupper():                upperCase = True            if i == "!" or i == "?":                noPunc = False

        # determine if input was valid        if(len(pwd) < 12 and upperCase and noPunc):                #input WAS valid, so end the loop                flag = False        else:                print("Input requires < 12 char, atleast one uppercase letter \                      and no punctuation. Please try again")

print("The password you entered was " , pwd)

22

Validating 3 values to average#File: averageValidation#Authors: May Levin – CTY ‘15#Section: B#Date: 7/6/15#Email:#Description:#Validate average of three inputted floats

def main(): flag = True value1 = float() value2 = float() value3 = float()

while(flag == True): try:

value1 = float(input("Type first value: ")) value2 = float(input("Type second value: ")) value3 = float(input("Type third value: "))

average = (value1 + value2 + value3)/3 print(average) flag = False

except ValueError: print("Numbers only")

main()

23