1

The following code is my code for the vanity plates problem in cs50 introduction to python course. My issue is on the "Punctuation Function". When I enter an input with a punctuation, instead of returning "valid" or "invalid", it returns this attribute error:

Traceback (most recent call last):
  File "plate.py", line 55, in <module>
    main()
  File "plate.py", line 6, in main
    if is_valid(plate):
  File "plate.py", line 13, in is_valid
    if number(s) and length(s) and letter(s) and punctuation(s)==True:
  File "plate.py", line 44, in number
    for j in range(n.start()):
AttributeError: 'NoneType' object has no attribute 'start'

Here is the code:

import re


def main():
    plate = input("Plate: ")
    if is_valid(plate):
        print("Valid")
    else:
        print("Invalid")


def is_valid(s):
    if number(s) and length(s) and letter(s) and punctuation(s)==True:
        return True


def letter(s):
    if s[0:2].isalpha():
        return True
    else:
        return False


def length(s):
    if 2 <= len(s) <= 6:
        return True
    else:
        return False


def punctuation(s):
    for i in s:
        if not(i.isalpha() or i.isdigit()):
            return False
    return True


def number(s):
    if s.isalpha():
        return True
    else:
        n = re.search(r"\d+$", s)
        for m in s:
            for j in range(n.start()):
                if m.isdigit():
                    return False
                else:
                    return True
        if n.group(0) != 0 and n:
            return True
        else:
            return False


main()

1 Answer 1

0

TLDR
In summary your punctuation check should be carried out before the number check in isvalid and your number check is wrong aside from perhaps the s.isalpha() check.

Details
The problems.

  1. You should do the punctuation check before you do the number check this would avoid the problem entirely.
  2. In your number function if you give it input with punctuation and no digits what happens? In short, if there are no digits but punctuation what is n? remember if there is no match for search it returns None. And that's what is happening here, it is returning None. None doesn't have a start method. So you need to check that there is a match before going into that loop OR adjust the earlier pre-regex checks such that its guaranteed that you will have a match.

But frankly if you are going to use a regex there is no need for your loop at all. You can do all of the work from a properly formed regular expression to make sure that the input contains: only letters and numbers, starts with at least two letters, has no letters after numbers, and doesnt have a leading '0'.

  1. Your loop also makes no sense at all. Why are you looping over meaningless j inside loop for m in s:?. You are just going to check each character of the string multiple times and inevitably find a digit and return false. Which is wrong.

  2. The additional check n.group(0) != 0 and n is broken for several reasons. if not n then n.group(0) will throw an exception so at minimum invert the conditions to be n and n.group(0) != 0. Even this is silly as you will have thrown an exception on n.start if n is None. But assuming n was valid, you would have returned false above as I pointed out in flaw 2; but lets say you didn't. n.group(0) is your whole match. Which means it will be not equal to zero if any digit is non zero, but that doesnt mean the first digit isn't zero so you will return true on bad results, and potentially because of short comings elsewhere miss a number in the middle...

Figure out what you are trying to accomplish with each stage, and then set out and do it. Test just this function with sample input by calling it directly instead of calling main for example, add printouts to help you see what the code is doing, and look at the documentation for regular expressions if you are going to use them.

Good luck

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .