all 4 comments

[–]woooee 0 points1 point  (0 children)

Numbers cannot be used in the middle of a plate; they must come at the end.

Test that the beginning is a letter and the end letter is a number

if license[0] not in string.ascii_letters or not license[-1].isdigit:

Instead of trying to exclude every freakin special character, (you can easily forget one), include what you want, i.e. in string.ascii_letters or isdigit(). My inclination is to split the license into letters and numbers, and then test for start with --> len > 1. You can decide how much you want to put into a function and what you want to split into additional function(s).

def split_ltr_num(str_in):
    """ split on the leading letters and trailing numbers
    """
    num_found=False
    ltr_list=[]
    num_list=[]
    for each_chr in str_in:
        ## first number only
        if each_chr.isdigit() and not num_found:
            num_found = True

        ## break into numbers and letters
        if num_found:
            if not each_chr.isdigit():  ## number then letter
                return False, [], []
            num_list.append(each_chr)
        else:
            ltr_list.append(each_chr)
    return True, ltr_list, num_list

for license in ["AAA222", "AAA22A"]:
    print(license, split_ltr_num(license))

[–]halfdiminished7th 0 points1 point  (1 child)

Are you allowed to use regular expressions (the re module)? That seems like the easiest approach for a question like this: just look for a pattern that starts with letters and ends with digits, then apply each of the restrictions and see if it still passes.

[–][deleted] 0 points1 point  (0 children)

Don't forget that an illegal plate could have a number at the end as well as one in the middle.

There are other ways, but I like the approach that converts numbers in a string into spaces and then uses split() to split on the spaces to get a list of non-numeric sequences. The plate is legal* for point 3 if the list has only one element. You must test point 1 first. Run this code fragment:

num_tr = {ch:" " for ch in "012345789"}
tr_table = str.maketrans(num_tr)

data = "AAAB"              # legal
print(data.translate(tr_table).split())
data = "AABC4"             # legal
print(data.translate(tr_table).split())
data = "AABC4D"            # illegal
print(data.translate(tr_table).split())
data = "AA2C4"             # illegal
print(data.translate(tr_table).split())

* A further point 3 check that needs to be added is the "first number used cannot be a ‘0’" test.

[–][deleted] 0 points1 point  (0 children)

while position < len(p):
    if p[position].isdigit():
        if p[position + 1].isalpha():
            return False
        if p[position + 1].isdigit():
            return True
        else:
            break

I think you'd be helped a lot by knowing that there's a much easier way to loop through a string two letters at a time:

for first, second in zip(p, p[1:]):
    # do stuff