Reputation: 165
The question I'm answering requires you to validate a Car Reg Plate. It must look for a sequence of two letters, then three numbers, then three letters, otherwise return a message like "not a valid postcode"
I need to know how to check if a string contains a certain letter, or number, by comparing it with a list.
So far, I've got this:
# Task 2
import random
import re
def regNumber():
# Generate a Car Reg Number
letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
numbers = ["1","2","3","4","5","6","7","8","9","0"]
letter1 = random.choice(letters)
letter2 = random.choice(letters)
number1 = random.choice(numbers)
number2 = random.choice(numbers)
letter3 = random.choice(letters)
letter4 = random.choice(letters)
letter5 = random.choice(letters)
licensePlate = (letter1 + letter2 + number1 + number2 + letter3 + letter4 + letter5)
return licensePlate, letters, numbers
carReg, letters, numbers = regNumber()
print(carReg)
if letters not in carReg: print("Success")
However, I get this error:
TypeError: 'in <string>' requires string as left operand, not list
Any help appreciated.
Upvotes: 1
Views: 4456
Reputation: 23743
You could do it without regular expressions:
Define the pattern you want using str
methods in a list
pattern = [str.isalpha, str.isalpha,
str.isdigit, str.isdigit, str.isdigit,
str.isalpha, str.isalpha, str.isalpha]
Use that pattern to check a string.
def is_foo(pattern, s):
'''Return True if s matches pattern
s is a string
pattern is a list of functions that return a boolean
len(s) == len(pattern)
each function in pattern is applied to the corresponding character in s
'''
# assert len(s) == len(pattern)
return all(f(c) for f, c in zip(pattern, s))
Usage
if is_foo(pattern, 'aa111aaa'):
print 'yes!!!'
if not is_foo(pattern, '11aa111'):
print ':('
Upvotes: 0
Reputation: 5281
change
if letters not in carReg: print("Success")
to
for l in letters:
if l not in carReg:
print("Success")
in your code you are having a list of strings and, that is why I have changed your if condition to a for loop so that each element of the list is checked for occurance in carReg string.
alternatively, i think you should be using a flag to solve your probem. Like so:
flag = 0
for l in letters:
if l in carReg:
flag = 1
break
if flag == 0:
print("Success")
Upvotes: 1
Reputation: 55
Another way in which you could generate a certain number of letters rather than having to use so many variables would be to use just two variables that would allow the generation of, for the first one, 2 letters and for the second 3 letters. An example of how I would implement this would be:
def randomLetters1(y):
return ''.join(random.choice(string.ascii_uppercase) for x in range(y))
firstLetters = (randomLetters1(2))
secondLetters = (randomLetters1(3))
I know this because I have had to do this exact same task.
Upvotes: 0
Reputation: 55952
The error is telling you the exact issue in this case,
letters
is a list being returend from regNumber
but in
requires a string on the leftside
like 'ASD111' in carReg
Upvotes: 1
Reputation: 3386
You need to be checking for characters in your string with this method, it will not simply iterate over your list for you.
Try using something like this instead, to check every character in your list of strings:
if any(letter in carReg for letter in letters):
This will cut out on the first True
, which is I think what you're looking for.
Note: If using any
like this is unfamiliar territory for you, you can also always just iterate over every string within your list of strings to check for those given characters.
Update: If you're attempting to match a given format of letters and numbers, it would make much more sense (IMHO) for you to familiarize yourself with Python's regex methods to pattern match to a valid license plate than attempt to use loops to validate one. I won't write the regex for your particular case, but to give you an idea, the following would allow you to match 3 letters followed by 1-4 digits (valid license plate where I live)
match_plate = re.compile(r"^[A-Z]{3}\d{1,4}$",re.I)
If you really must use a list to check, you will have to use a series of conditional statements to split the license plate into parts over which you can validate with iterations.
Upvotes: 5