0

I am writing a simple code that should determine the license plates of the car and say if it is of an old or a new type. The user inputs a string (example: "ABC123" or "1234POW") and the program should return a string with a corresponding value: "New" or "Old"

So, the problem is:

l = input("Enter your license plate: ")
if len(l) == 6:
    if l[0] and l[1] and l[2] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
        if l[3]and l[4]and l[5] in "1234567890":
            print("You have a license plate of an old type")
        else:
            print("The plate is not valid. Check your input")
    else:
        print("The plate is not valid. Check your input")
elif len(l) == 7:
    if l[0:4] in "1234567890":
        if l[4:7] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
        print("You have a license plate of a new type")
    else:
        print("Your plate is not valid, check your input+")

else: print("This doesn't look like a valid plate number")

Lines 11 and 12: I have no idea why, but instead of printing the "New Type" message I get "Your plate is not valid, check your input+".

But if I change the line 12 to "if l[4] and l[5] and l[6] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - everything works fine.

Would be grateful for explanation, and I beg my pardon, if I posted something or somehow wrong - I'm new here :D Thank you.

sshashank124
  • 31,495
  • 9
  • 67
  • 76
  • 1
    `if l[4] and l[5] and l[6] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"` is equivalent to `if (bool(l[4])) and (bool(l[5])) and (l[6] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ")`. – eugenhu Feb 20 '18 at 14:26
  • `and` does not work the way you're expecting it to work. You need to individually compare each of the characters yourself – sshashank124 Feb 20 '18 at 14:26
  • 3
    Also consider using `isalpha` and `isnum` https://docs.python.org/2/library/stdtypes.html#str.isalpha – sshashank124 Feb 20 '18 at 14:28
  • 3
    Please put more effort into your title. It should describe the problem you're having, not be a plea for help. – glibdud Feb 20 '18 at 14:29
  • Can your license plates have single or double digit numbers? They can in most countries, and your code would declare that to be invalid. – Mawg says reinstate Monica Feb 20 '18 at 14:30
  • Thank you for response. If I need to compare the characters individually, why "if l[0:4] in "1234567890":" works? Thank you – Dmitry Tharn Feb 20 '18 at 14:30
  • Your question relates to basically just line 11 and 12 of the code you posted, next time please try to include the minimal code required to replicate the problem. Refer to [mcve]. – eugenhu Feb 20 '18 at 14:31
  • `l[0:4]` equals to `'1234'` and it is in the `'1234567890'` string. `l[4:7]` equals to `'POW'` and it is **not** in the `'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` string. Try this code: https://github.com/foobar167/junkyard/blob/master/license_plate.py – FooBar167 Feb 20 '18 at 15:09

3 Answers3

3

l[4:7] is a string of length 3. So suppose l is "1234POW", then l[4:7] is "POW". Your long string "ABCDEFGHIJKLMNOPQRSTUVWXYZ" does not contain the substring "POW".

If you want to check that every one of a sequence of characters are in your long string, you can use the function all.

if all(ch in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" for ch in l[4:7]):
    ...

or even just

 if l[4:7].isupper():

You got away with l[0:4] in "1234567890" because "1234" is an exact substring of "1234567890". If you had different numbers, it would not have worked, for the same reason as above.

Instead you could use:

if l[:4].isdigit() and l[4:7].isupper():

On the other hand, your upper condition

if l[0] and l[1] and l[2] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

is also wrong. Python understands this as

if (l[0]) and (l[1]) and (l[2] in "ABCDEFGHIJKLMNOPQRSTUVWXYZ")

i.e.

if l[0] is not zero
   and l[1] is not zero
   and l[2] is in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

So your upper condition should also be changed:

e.g.

if l[:3].isupper() and l[3:6].isdigit():
    ...
khelwood
  • 55,782
  • 14
  • 81
  • 108
0

This is typically a regex problem. https://docs.python.org/3/library/re.html

Trye something like this:

import re

new_plate_re = re.compile(r'^\D{3}\d{3}$')
old_plate_re = re.compile(r'^\d{3}\D{3}$')

def check_plate(plate_num):
    match_new = new_plate_re.match(plate_num)
    if match_new is not None:
        print("You have a license plate of a new type")
        return
    match_old = old_plate_re.match(plate_num)
    if match_old is not None:
        print("You have a license plate of a old type")
        return
    print("Unknown format!")
Samuel GIFFARD
  • 796
  • 6
  • 22
0

khelwood's answer is perfectly fine, but here is an alternative just because when you're learning it's often helpful to see several techniques. You could turn those initial characters in the string into a Python set. The easiest way to build the set is to use a slice as others have said, and then call the set() function. Overall it would look like this:

if set(l[0:3]).issubset("ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
    if set(l[3:6]).issubset("1234567890"):
       # ...
Arthur Tacca
  • 8,833
  • 2
  • 31
  • 49