jkibbe
jkibbe

Reputation: 3

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")

Upvotes: 0

Views: 13852

Answers (3)

Anirudh Ramanathan
Anirudh Ramanathan

Reputation: 46728

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')

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1121654

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

Upvotes: 5

John La Rooy
John La Rooy

Reputation: 304147

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')

Upvotes: 1

Related Questions