0

As part of a bigger Python homework problem, I'm trying to check if a string input contains a positive/negative integer or float, and returns True if it does, False if it does not.

The homework problem will assume that the user enters in a very simple math expression, separated by whitespace (e.g. 8 / ( 2 + 2 )), after which, the expression will be broken down into separate characters in a list (e.g. ["8", "/", "(", "2", "+", "2", ")"]). Then, I will run this list through a 'for' loop that increases the number of a counter variable, based on the current token's type (e.g. if currentToken is "2", then operandCount += 1).

So far, I'm having difficulty trying to accomplish this with a currentToken that contains a positive/negative float or int-type number (e.g. "8", "-9", "4.6"). The main challenge here is that my professor does not allow us to use try-except anywhere in our code, so that rules out a lot of the solutions I've found online so far as many of them involve catching an error message.

The closest I've come to solving this was using the 'isnumeric()' and 'isdigit()' methods.

# Assume that the user will enter in a simple math expression, separated by whitespace.
expression = input("Enter an expression: ")
expr = expression.split()

operandCount = 0

for currentToken in expr:
    if currentToken.isnumeric() == True:
        operandCount += 1

        # operandCount should increase when the 'for' loop encounters
        # a positive/negative integer/float.

However, it only returns True for strings that contain purely positive integers. I need it to be able to return True for integers and floats, both positive and negative. Thanks in advance for any advice!

Rizuan
  • 13
  • 3
  • 1
    You could use regular expression (albeit them being not as pythonic for that case). Here you can find more options: https://stackoverflow.com/questions/354038/how-do-i-check-if-a-string-is-a-number-float in the answer from user2489252. – skymon Aug 18 '19 at 10:23
  • what about brackets do they count? – Lupos Aug 18 '19 at 10:32
  • I think what are you doing right now is wrong you increase operandCount when it's true. Don't you want to increase operandCount when its false for example when you have a "/" and not a number? – Lupos Aug 18 '19 at 10:44

2 Answers2

1

Apply a regular expression to search for a numeric string which optionally can be

  • a negative number: -1
  • have comma separation: 120,000
  • have an optional decimal point: 0.34, .1415926
import re 
for currentToken in expr:   
   m = re.match("^[-\.\d]+[,]?[\d]*[\.]?[\d]?$", str(currentToken)) 
  if (m): 
     print "number:", m.group[0]
suspectus
  • 16,548
  • 8
  • 49
  • 57
  • I think it is not possible to do `m.group[0]` but rather `m.group(0)` like: `re.match("^[-\.\d]+[,]?[\d]*[\.]?[\d]?$", "50,000").group(0)`. Unfortunately this expression catches numbers with more than one decimal point, like dates: `re.match("^[-\.\d]+[,]?[\d]*[\.]?[\d]?$", "10.10.2023").group(0)`. – KLaz Aug 21 '23 at 07:56
0

As pointed out skymon using regex is a good idea, here is an example:

import re

def isAdigit(text, pat=r'^-*\d+\.*\d*[ \t]*$'):
    if re.search(pat, text) != None:
        return True

    return False

expression = input("Enter an expression: ")
expr = expression.split()

operandCount = 0

for currentToken in expr:
    if isAdigit(currentToken):
        operandCount += 1

print (operandCount)

Example usage:

input: 1 + 2 / ( 69 * -420 ) - -3.14 => output: 5

I also recommend you learn more about regex.

Oleg Vorobiov
  • 482
  • 5
  • 14