Conor Hastings Conor Hastings - 8 days ago 6
Python Question

Input Validation in Python

So my friend and I have been working on this problem for a few days now for our Intro to Python class at our college, but we are a bit stuck due to the fact we didn't spend much time on this topic in class. Our problem is this, "Every product ID must be six characters long and starts with three upper case letters followed by three digits. For example ABE123 and PPL334 are valid product IDs but ABE1.2 and P1L3R4 are not. The auction site has a minimum bid price of 5 dollars and caps bids at 500 dollars. Bids with dollars and cents are acceptable. For example 6.78 is a valid bid. The following code reads in bids from the prompt (keyboard inputs) and loads the product ids and bidding prices into two lists products and bids. Unfortunately the code contains no input validation which is your job to complete." Our teacher gave us the code, we just have to validate the inputs. But it has to be done outside of her code, as in its own function. Here is the code:

`def getbids():
products = []
bids = []
answer = "yes"
while answer == "yes":
productid = input("Enter the productID ")
bid = float(input("Enter the bid for one item "))
products.append(productid)
bids.append(bid)
answer = input("Are there more bids? ")
return products, bids`


Basically, our job is to validate the productid and the bid in separate functions. I have our code here but what we have doesn't work completely and is not correct.
Here is the one for productId:

`def validprod(n):
caps="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
nums="0123456789"
m="Error"
if len(n)!=6:
print("Error, productID must be 6 digits,3 capital letters followed by 3 numbers")
return m
else:
while len(n)==6:
for i in range(3):
if n[i] not in caps or n[i+3] not in nums:
print("Error, productID must be 6 digits,3 capital letters followed by 3 numbers")
return m
else:
return n`


Here is the one for bids:

`def validbid(x,y):
bid="Error"
while x=="Error":
return bid
while x!="Error":
if y>500 or y<5:
print("Error, bid must be between 5 and 500(do not include a dollar sign with your bid).")
return bid
else:
return y`


We know there is probably a much simpler way to do it, we just don't know it.

Dev Dev
Answer
import re

pid_regex = re.compile(r'^[A-Za-z]{3}\d{3}$')

def is_valid_pid(pid):
    if pid_regex.match(pid):
        return True
    return False

def is_valid_bid(bid):
    return bid >= 5 and bid <= 500

def getbids():
     products = []
     bids = []
     answer = "yes"
     while answer == "yes":
         productid = input("Enter the productID ")
         products.append(productid)
         bid = float(input("Enter the bid for one item "))
         bids.append(bid)
         answer = input("Are there more bids? ")
     return products, bids

products = dict(zip(*getbids()))

for pid in products:
    bid = products[pid]
    if not is_valid_pid(pid):
        print('PID {} is invalid.'.format(pid))
        break
    elif not is_valid_bid(bid):
        print('PID {} has an invalid bid {}'.format(pid, bid))
        break
    else:
        print('PID {} to bid {} seems OK.'.format(pid, bid))

Note: I needed to fix your getbids() function, because products were not being appended to the products list.

Another note: If you believe I was wrong to provide a complete solution, please let me know. I'm completely open to feedback from the public.