2
votes

So here's what I'm trying to do. I have quite a few folders made in a special directory on my computer to hide stuff in. I have 4 levels of folders, each folder with folders numbered 1 - 4.

Example:

1>1>1>1
1>1>1>2
...
1>2>1>1
...
4>1>1>1
...
4>4>4>4

I wrote a python program to ask for a pin, then open the file directory corresponding with the pin. [Ex.. pin# 4322 will open 4>3>2>2]. Only problem I'm having is I cannot limit input to only numbers 1 - 4, and when I enter a number outside of this range internet explorer is opened (UGH! IE).

Here's the code.... (Python 2.7.6)

pin=str(raw_input("What is your 4-digit pin number? "))
intpin=int(pin)
#==============##==============#
pin1=pin[0:1]
pin2=pin[1:2]
pin3=pin[2:3]
pin4=pin[3:4]
#==============##==============#
ipin1=int(pin1)
ipin2=int(pin2)
ipin3=int(pin3)
ipin4=int(pin4)
#==============##==============#
print("")
print pin1
print pin2
print("")
path=("D:/Documents/Personal/"+pin1+"/"+pin2+"/"+pin3+"/"+pin4)
import webbrowser as wb
wb.open(path)
#==============##==============#
print("Thank You!")
print("Your window has opened, now please close this one...")
3

3 Answers

1
votes

You can test the input to ensure that all are digits 1-4:

bol = False
while bol == False:
    pin=str(raw_input("What is your 4-digit pin number? "))
    for digit in pin:
        if int(digit) in [1,2,3,4]:
            bol = True
        else:
            print "invalid pin"
            bol = False
            break

This, added to the beginning of your code, should work. Your code could definitely be more succinct but this isn't my place to correct you.

1
votes

You could use a regex. Regex is always a good friend.

import re
if not re.match("^([1-4])([1-4])([1-4])([1-4])$", pin):
        print "Well that's not your pin, is it?"
        import sys
        sys.exit()
1
votes

First off, raw_input always outputs a string, regardless if you input a number. You don't need to do str(raw_input.... Proof as follows:

>>> d = raw_input("What is your 4-digit number? ")
What is your 4-digit number? 5
>>> print type(d)
<type 'str'>

Second, the accepted answer does not protect you from inputs of more than 4 digits. Even an input of 12341234 will be accepted, since it fails to check the length of the passed in string.

One workaround here is not to inspect the string, but instead inspect the integer equivalent. Your desired range here is just [1111, 4444]. At this point, it's alright to use assert so you can raise an assertion error when they enter anything below or above that. However, one failing of this is that it's possible to pass in something like 1111.4, which still satisfies the inclusion check (though fails at the conversion due to ValueError).

Taking the above to consideration, here's one alternative take on your code.

def is_valid(strnum):

    # Returns false when inputs like 1.2 are given.
    try:
        intnum = int(strnum)
    except ValueError, e:
        return False

    # Check the integer equivalent if it's within the range.
    if 1111 <= intnum <= 4444:
        return True
    else: return False

strnum = raw_input("What is your 4-digit PIN?\n>> ")
# print is_valid(strnum)

if is_valid:
    # Your code here...

Some tests follows:

# On decimal/float-type inputs.
>>> 
What is your 4-digit PIN?
>> 1.2
False
>>> 
# On below or above the range wanted.
>>> 
What is your 4-digit PIN?
>> 5555
False
>>> 
What is your 4-digit PIN?
>> 1110
False
>>> 
What is your 4-digit PIN?
>> 1234
True
>>> 

Hope this helps.