How to type negative number with .isdigit?

Question:

when I try this

if question.isdigit() is True:

I can type in numbers fine, and this would filter out alpha/alphanumeric strings

when I try ‘s1’ and ‘s’ for example, it would go to (else).

Problem is, when I put negative number such as -1, ‘.isdigit’ counts ‘-‘ sign as string value and it rejects it. How can I make it so that ‘.isdigit’ allows negative symbol ‘-‘?

Here is the code. Of the thing i tried.

while a <=10 + Z:
    question = input("What is " + str(n1) + str(op) + str(n2) + "?")
    a = a+1

    if question.lstrip("-").isdigit() is True:
        ans = ops[op](n1, n2)
        n1 = random.randint(1,9)
        n2 = random.randint(1,9)
        op = random.choice(list(ops))

        if int(question) is ans:
            count = count + 1
            Z = Z + 0
            print ("Well done")
        else:
            count = count + 0
            Z = Z + 0
            print ("WRONG")
    else:
        count = count + 0
        Z = Z + 1
        print ("Please type in the number")
Asked By: Wdoctor123

||

Answers:

Use lstrip:

question.lstrip("-").isdigit()

Example:

>>>'-6'.lstrip('-')
'6'
>>>'-6'.lstrip('-').isdigit()
True

You can lstrip('+-') if you want to consider +6 a valid digit.

But I wouldn’t use isdigit, you can try int(question), it’ll throw an exception if the value cannot be represented as int:

try:
    int(question)
except ValueError:
    # not int
Answered By: Maroun

Use a try/except, if we cannot cast to an int it will set is_dig to False:

try:
    int(question)
    is_dig = True
except ValueError:
    is_dig = False
if is_dig:
  ......

Or make a function:

def is_digit(n):
    try:
        int(n)
        return True
    except ValueError:
        return  False

if is_digit(question):
   ....

Looking at your edit cast to int at the start,checking if the input is a digit and then casting is pointless, do it in one step:

while a < 10: 
     try:
        question = int(input("What is {} {} {} ?".format(n1,op,n2)))
     except ValueError:
        print("Invalid input")
        continue # if we are here we ask user for input again

    ans = ops[op](n1, n2)
    n1 = random.randint(1,9)
    n2 = random.randint(1,9)
    op = random.choice(list(ops))

    if question ==  ans:
        print ("Well done")
    else:
        print("Wrong answer")
    a += 1

Not sure what Z is doing at all but Z = Z + 0 is the same as not doing anything to Z at all 1 + 0 == 1

Using a function to take the input we can just use range:

def is_digit(n1,op,n2):
    while True:
        try:
            n = int(input("What is {} {} {} ?".format(n1,op,n2)))
            return n
        except ValueError:
            print("Invalid input")


for _ in range(a):
    question = is_digit(n1,op,n2) # will only return a value when we get legal input
    ans = ops[op](n1, n2)
    n1 = random.randint(1,9)
    n2 = random.randint(1,9)
    op = random.choice(list(ops))

    if question ==  ans:
        print ("Well done")
    else:
        print("Wrong answer")
Answered By: Padraic Cunningham

If you do not wish to go for try… except, you could use regular expression

if re.match("[+-]?d", question) is not None:
    question = int(question)
else:
    print "Not a valid number"

With try… except, it is simpler:

try:
    question = int(question)
except ValueError:
    print "Not a valid number"

If isdigit is must and you need to preserve the original value as well, you can either use lstrip as mentioned in an answer given. Another solution will be:

if question[0]=="-":
    if question[1:].isdigit():
        print "Number"
else:
    if question.isdigit():
        print "Number"
Answered By: thiruvenkadam

I have just had a similar question on edabit where I realised that negative numbers returned as False whilst using isnumeric(). I have put my solution below:
Create a function that takes a list of strings and integers, and filters out the list so that it returns a list of integers only.

def filter_list(list):
    numbers = [i for i in list if str(i).isnumeric() == True]
    for i in list:
        try:
            int(i)
            if i <0:
                numbers.append(i)
        except ValueError:
            continue
    return numbers
list = [1,2,3,'a','b','c', -6, 0]
print(filter_list(list))

I am still new to Python so this is a basic attempt. Feel free to let me know if there is a much easier or better looking way.

Answered By: James Mahoney

To check if your input string is numeric or not, even in cases when you enter negative values or floats you can do this:

if string.replace('.','').replace('-','').isnumeric():
    print(string + ' is a number')

If you want to check specifically if your string is a negative number you can do this:

if string[0] == '-' and string[1:].replace('.','').isnumeric():
    print(string + ' is a negative number')

Edit: Replace removes all "." and "-" from the string, so "…-1-.-" would classify as a number too!

Answered By: Hurri

I know it’s late, but I just stumbled appon this question and I had a similar problem wich I solved this way:

@staticmethod
    def getStringToFloatOrNone(value):
        if value == None:
            return None  
        if not str(value).replace(",","").replace(".","").replace("-","").strip().isdigit(): 
            return 0   
        return value if isinstance(value, float) or isinstance(value, int) else float(Helper.createViableFloatOrIntString(value))  

        return int(float(value)) if isinstance(value, float) or isinstance(value, int) else int(float(Helper.createViableFloatOrIntString(value))) 

Just replace all the common delimitter and try if it’s a digit.
If yes, get the actual value as float.

Answered By: user3793935

Simple way to do this using lambda,

is_numeric = lambda x: x.replace('.', '', 1).replace('-', '', 1).isdigit()

You can use this like:

if is_numeric(question):
    ## your code here ##

@Hurri have done something similar, but afraid it return True for values like IP addresses.

Answered By: Priyank-py
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.