简体   繁体   中英

Python - Check user input to make sure it is an integer - no letters, etc

This code is a preview from an upcoming competition at picoctf.com. I modified the original code provided so it allows for user input, but I can't get Test #2 to work. When a string of 10 characters is entered with at least one letter, I want it to print that only numbers may be used. Currently it tries to convert the user input to an integer value to compare it to the actual serial, but if there is a letter present the test fails since a letter can't be converted to a integer value:

123456789a yields "invalid literal for int() with base 10..."

How can I fix this piece of code so that it tests correctly?

**

if int(serial) != serial:
            print ("only numbers allowed")
            print ('Failed Test 2')

**

#!/usr/bin/env python
# Your goal is to find the input that will verify your robot's serial number
#solution to keep it handy = 0933427186

serial = input ("Please enter a valid serial number from your RoboCorpIntergalactic purchase")

def check_serial(serial):
    if len(serial) != 10:
        print ('Failed Test 1')
        return False
    if int(serial) != serial:
        print ("only numbers allowed")
        print ('Failed Test 2')
        return False
    if int(serial[0])+int(serial[1]) != 9:
        print ('Failed Test 3')
        return False
    if int(serial[2])*int(serial[3]) != 9:
        print ('Failed Test 4')
        return False
    if int(serial[4])-int(serial[5]) != 2:
        print ('Failed Test 5')
        return False
    if int(serial[5])%int(serial[4]) != 2:
        print ('Failed Test 6')
        return False
    if int(serial[6])/int(serial[7]) != 7:
        print ('Failed Test 7')
        return False
    if int(serial[8])-int(serial[9]) != 2:
        print ('Failed Test 8')
        return False
    if int(serial[7])*int(serial[1]) != 9:
        print ('Failed Test 9')
        return False
    if int(serial[2]) + int(serial[3]) != int(serial[9]):
        print ('Failed Test 10')
        return False
    return True

if check_serial(serial):
    print ("Thank you! Your product has been verified!")
else:
    print ("I'm sorry that is incorrect. Please use a valid RoboCorpIntergalactic serial number")

Use str.isdigit() to test if all characters are digits:

>>> 'a1'.isdigit()
False
>>> '11'.isdigit()
True
>>> '1a'.isdigit()
False

You may want to turn your serial string into a sequence of integers to make all your tests easier:

s_int = [int(d) for d in serial]

then

if s_int[0] + s_int[1] != 9:

etc.

You could easily build a sequence of tests with indices, an operator and the expected outcome:

import operator

tests = (
    (0, 1, operator.add, 9),
    (2, 3, operator.mul, 9),
    (4, 5, operator.sub, 2),
    (5, 4, operator.mod, 2),
    (6, 7, operator.truediv, 7),
    (8, 9, operator.sub, 2),
    (7, 1, operator.mul, 9),
)

for i, (a, b, op, res) in enumerate(tests, 3):
    if op(s_int[a], s_int[b]) != res:
        print("Failed test {}".format(i))
        return False

Use str.isdigit()

Return true if all characters in the string are digits and there is at least one character, false otherwise.

You could use a regular expression as well:

import re;
if(re.match('\D', serial)):
    print ('Failed Test 2')
try:
    int(serial)
except ValueError:
    print ("only numbers allowed")
    print ('Failed Test 2')

or following Martijn's suggestion

try:
    s_int = [int(d) for d in serial]
except ValueError:
    s_int = None
    print ("only numbers allowed")
    print ('Failed Test 2')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM